vga_switcheroo.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*
  2. * Copyright (c) 2010 Red Hat Inc.
  3. * Author : Dave Airlie <airlied@redhat.com>
  4. *
  5. *
  6. * Licensed under GPLv2
  7. *
  8. * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
  9. *
  10. * Switcher interface - methods require for ATPX and DCM
  11. * - switchto - this throws the output MUX switch
  12. * - discrete_set_power - sets the power state for the discrete card
  13. *
  14. * GPU driver interface
  15. * - set_gpu_state - this should do the equiv of s/r for the card
  16. * - this should *not* set the discrete power state
  17. * - switch_check - check if the device is in a position to switch now
  18. */
  19. #define pr_fmt(fmt) "vga_switcheroo: " fmt
  20. #include <linux/module.h>
  21. #include <linux/seq_file.h>
  22. #include <linux/uaccess.h>
  23. #include <linux/fs.h>
  24. #include <linux/debugfs.h>
  25. #include <linux/fb.h>
  26. #include <linux/pci.h>
  27. #include <linux/console.h>
  28. #include <linux/vga_switcheroo.h>
  29. #include <linux/pm_runtime.h>
  30. #include <linux/vgaarb.h>
  31. struct vga_switcheroo_client {
  32. struct pci_dev *pdev;
  33. struct fb_info *fb_info;
  34. int pwr_state;
  35. const struct vga_switcheroo_client_ops *ops;
  36. int id;
  37. bool active;
  38. bool driver_power_control;
  39. struct list_head list;
  40. };
  41. static DEFINE_MUTEX(vgasr_mutex);
  42. struct vgasr_priv {
  43. bool active;
  44. bool delayed_switch_active;
  45. enum vga_switcheroo_client_id delayed_client_id;
  46. struct dentry *debugfs_root;
  47. struct dentry *switch_file;
  48. int registered_clients;
  49. struct list_head clients;
  50. struct vga_switcheroo_handler *handler;
  51. };
  52. #define ID_BIT_AUDIO 0x100
  53. #define client_is_audio(c) ((c)->id & ID_BIT_AUDIO)
  54. #define client_is_vga(c) ((c)->id == -1 || !client_is_audio(c))
  55. #define client_id(c) ((c)->id & ~ID_BIT_AUDIO)
  56. static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
  57. static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
  58. /* only one switcheroo per system */
  59. static struct vgasr_priv vgasr_priv = {
  60. .clients = LIST_HEAD_INIT(vgasr_priv.clients),
  61. };
  62. static bool vga_switcheroo_ready(void)
  63. {
  64. /* we're ready if we get two clients + handler */
  65. return !vgasr_priv.active &&
  66. vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
  67. }
  68. static void vga_switcheroo_enable(void)
  69. {
  70. int ret;
  71. struct vga_switcheroo_client *client;
  72. /* call the handler to init */
  73. if (vgasr_priv.handler->init)
  74. vgasr_priv.handler->init();
  75. list_for_each_entry(client, &vgasr_priv.clients, list) {
  76. if (client->id != -1)
  77. continue;
  78. ret = vgasr_priv.handler->get_client_id(client->pdev);
  79. if (ret < 0)
  80. return;
  81. client->id = ret;
  82. }
  83. vga_switcheroo_debugfs_init(&vgasr_priv);
  84. vgasr_priv.active = true;
  85. }
  86. int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
  87. {
  88. mutex_lock(&vgasr_mutex);
  89. if (vgasr_priv.handler) {
  90. mutex_unlock(&vgasr_mutex);
  91. return -EINVAL;
  92. }
  93. vgasr_priv.handler = handler;
  94. if (vga_switcheroo_ready()) {
  95. pr_info("enabled\n");
  96. vga_switcheroo_enable();
  97. }
  98. mutex_unlock(&vgasr_mutex);
  99. return 0;
  100. }
  101. EXPORT_SYMBOL(vga_switcheroo_register_handler);
  102. void vga_switcheroo_unregister_handler(void)
  103. {
  104. mutex_lock(&vgasr_mutex);
  105. vgasr_priv.handler = NULL;
  106. if (vgasr_priv.active) {
  107. pr_info("disabled\n");
  108. vga_switcheroo_debugfs_fini(&vgasr_priv);
  109. vgasr_priv.active = false;
  110. }
  111. mutex_unlock(&vgasr_mutex);
  112. }
  113. EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
  114. static int register_client(struct pci_dev *pdev,
  115. const struct vga_switcheroo_client_ops *ops,
  116. int id, bool active, bool driver_power_control)
  117. {
  118. struct vga_switcheroo_client *client;
  119. client = kzalloc(sizeof(*client), GFP_KERNEL);
  120. if (!client)
  121. return -ENOMEM;
  122. client->pwr_state = VGA_SWITCHEROO_ON;
  123. client->pdev = pdev;
  124. client->ops = ops;
  125. client->id = id;
  126. client->active = active;
  127. client->driver_power_control = driver_power_control;
  128. mutex_lock(&vgasr_mutex);
  129. list_add_tail(&client->list, &vgasr_priv.clients);
  130. if (client_is_vga(client))
  131. vgasr_priv.registered_clients++;
  132. if (vga_switcheroo_ready()) {
  133. pr_info("enabled\n");
  134. vga_switcheroo_enable();
  135. }
  136. mutex_unlock(&vgasr_mutex);
  137. return 0;
  138. }
  139. int vga_switcheroo_register_client(struct pci_dev *pdev,
  140. const struct vga_switcheroo_client_ops *ops,
  141. bool driver_power_control)
  142. {
  143. return register_client(pdev, ops, -1,
  144. pdev == vga_default_device(),
  145. driver_power_control);
  146. }
  147. EXPORT_SYMBOL(vga_switcheroo_register_client);
  148. int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
  149. const struct vga_switcheroo_client_ops *ops,
  150. int id, bool active)
  151. {
  152. return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false);
  153. }
  154. EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
  155. static struct vga_switcheroo_client *
  156. find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
  157. {
  158. struct vga_switcheroo_client *client;
  159. list_for_each_entry(client, head, list)
  160. if (client->pdev == pdev)
  161. return client;
  162. return NULL;
  163. }
  164. static struct vga_switcheroo_client *
  165. find_client_from_id(struct list_head *head, int client_id)
  166. {
  167. struct vga_switcheroo_client *client;
  168. list_for_each_entry(client, head, list)
  169. if (client->id == client_id)
  170. return client;
  171. return NULL;
  172. }
  173. static struct vga_switcheroo_client *
  174. find_active_client(struct list_head *head)
  175. {
  176. struct vga_switcheroo_client *client;
  177. list_for_each_entry(client, head, list)
  178. if (client->active && client_is_vga(client))
  179. return client;
  180. return NULL;
  181. }
  182. int vga_switcheroo_get_client_state(struct pci_dev *pdev)
  183. {
  184. struct vga_switcheroo_client *client;
  185. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  186. if (!client)
  187. return VGA_SWITCHEROO_NOT_FOUND;
  188. if (!vgasr_priv.active)
  189. return VGA_SWITCHEROO_INIT;
  190. return client->pwr_state;
  191. }
  192. EXPORT_SYMBOL(vga_switcheroo_get_client_state);
  193. void vga_switcheroo_unregister_client(struct pci_dev *pdev)
  194. {
  195. struct vga_switcheroo_client *client;
  196. mutex_lock(&vgasr_mutex);
  197. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  198. if (client) {
  199. if (client_is_vga(client))
  200. vgasr_priv.registered_clients--;
  201. list_del(&client->list);
  202. kfree(client);
  203. }
  204. if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
  205. pr_info("disabled\n");
  206. vga_switcheroo_debugfs_fini(&vgasr_priv);
  207. vgasr_priv.active = false;
  208. }
  209. mutex_unlock(&vgasr_mutex);
  210. }
  211. EXPORT_SYMBOL(vga_switcheroo_unregister_client);
  212. void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
  213. struct fb_info *info)
  214. {
  215. struct vga_switcheroo_client *client;
  216. mutex_lock(&vgasr_mutex);
  217. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  218. if (client)
  219. client->fb_info = info;
  220. mutex_unlock(&vgasr_mutex);
  221. }
  222. EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
  223. static int vga_switcheroo_show(struct seq_file *m, void *v)
  224. {
  225. struct vga_switcheroo_client *client;
  226. int i = 0;
  227. mutex_lock(&vgasr_mutex);
  228. list_for_each_entry(client, &vgasr_priv.clients, list) {
  229. seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
  230. client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :
  231. "IGD",
  232. client_is_vga(client) ? "" : "-Audio",
  233. client->active ? '+' : ' ',
  234. client->driver_power_control ? "Dyn" : "",
  235. client->pwr_state ? "Pwr" : "Off",
  236. pci_name(client->pdev));
  237. i++;
  238. }
  239. mutex_unlock(&vgasr_mutex);
  240. return 0;
  241. }
  242. static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
  243. {
  244. return single_open(file, vga_switcheroo_show, NULL);
  245. }
  246. static int vga_switchon(struct vga_switcheroo_client *client)
  247. {
  248. if (client->driver_power_control)
  249. return 0;
  250. if (vgasr_priv.handler->power_state)
  251. vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
  252. /* call the driver callback to turn on device */
  253. client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
  254. client->pwr_state = VGA_SWITCHEROO_ON;
  255. return 0;
  256. }
  257. static int vga_switchoff(struct vga_switcheroo_client *client)
  258. {
  259. if (client->driver_power_control)
  260. return 0;
  261. /* call the driver callback to turn off device */
  262. client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
  263. if (vgasr_priv.handler->power_state)
  264. vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
  265. client->pwr_state = VGA_SWITCHEROO_OFF;
  266. return 0;
  267. }
  268. static void set_audio_state(int id, int state)
  269. {
  270. struct vga_switcheroo_client *client;
  271. client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
  272. if (client && client->pwr_state != state) {
  273. client->ops->set_gpu_state(client->pdev, state);
  274. client->pwr_state = state;
  275. }
  276. }
  277. /* stage one happens before delay */
  278. static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
  279. {
  280. struct vga_switcheroo_client *active;
  281. active = find_active_client(&vgasr_priv.clients);
  282. if (!active)
  283. return 0;
  284. if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
  285. vga_switchon(new_client);
  286. vga_set_default_device(new_client->pdev);
  287. return 0;
  288. }
  289. /* post delay */
  290. static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
  291. {
  292. int ret;
  293. struct vga_switcheroo_client *active;
  294. active = find_active_client(&vgasr_priv.clients);
  295. if (!active)
  296. return 0;
  297. active->active = false;
  298. set_audio_state(active->id, VGA_SWITCHEROO_OFF);
  299. if (new_client->fb_info) {
  300. struct fb_event event;
  301. console_lock();
  302. event.info = new_client->fb_info;
  303. fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
  304. console_unlock();
  305. }
  306. ret = vgasr_priv.handler->switchto(new_client->id);
  307. if (ret)
  308. return ret;
  309. if (new_client->ops->reprobe)
  310. new_client->ops->reprobe(new_client->pdev);
  311. if (active->pwr_state == VGA_SWITCHEROO_ON)
  312. vga_switchoff(active);
  313. set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
  314. new_client->active = true;
  315. return 0;
  316. }
  317. static bool check_can_switch(void)
  318. {
  319. struct vga_switcheroo_client *client;
  320. list_for_each_entry(client, &vgasr_priv.clients, list) {
  321. if (!client->ops->can_switch(client->pdev)) {
  322. pr_err("client %x refused switch\n", client->id);
  323. return false;
  324. }
  325. }
  326. return true;
  327. }
  328. static ssize_t
  329. vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
  330. size_t cnt, loff_t *ppos)
  331. {
  332. char usercmd[64];
  333. int ret;
  334. bool delay = false, can_switch;
  335. bool just_mux = false;
  336. int client_id = -1;
  337. struct vga_switcheroo_client *client = NULL;
  338. if (cnt > 63)
  339. cnt = 63;
  340. if (copy_from_user(usercmd, ubuf, cnt))
  341. return -EFAULT;
  342. mutex_lock(&vgasr_mutex);
  343. if (!vgasr_priv.active) {
  344. cnt = -EINVAL;
  345. goto out;
  346. }
  347. /* pwr off the device not in use */
  348. if (strncmp(usercmd, "OFF", 3) == 0) {
  349. list_for_each_entry(client, &vgasr_priv.clients, list) {
  350. if (client->active || client_is_audio(client))
  351. continue;
  352. if (client->driver_power_control)
  353. continue;
  354. set_audio_state(client->id, VGA_SWITCHEROO_OFF);
  355. if (client->pwr_state == VGA_SWITCHEROO_ON)
  356. vga_switchoff(client);
  357. }
  358. goto out;
  359. }
  360. /* pwr on the device not in use */
  361. if (strncmp(usercmd, "ON", 2) == 0) {
  362. list_for_each_entry(client, &vgasr_priv.clients, list) {
  363. if (client->active || client_is_audio(client))
  364. continue;
  365. if (client->driver_power_control)
  366. continue;
  367. if (client->pwr_state == VGA_SWITCHEROO_OFF)
  368. vga_switchon(client);
  369. set_audio_state(client->id, VGA_SWITCHEROO_ON);
  370. }
  371. goto out;
  372. }
  373. /* request a delayed switch - test can we switch now */
  374. if (strncmp(usercmd, "DIGD", 4) == 0) {
  375. client_id = VGA_SWITCHEROO_IGD;
  376. delay = true;
  377. }
  378. if (strncmp(usercmd, "DDIS", 4) == 0) {
  379. client_id = VGA_SWITCHEROO_DIS;
  380. delay = true;
  381. }
  382. if (strncmp(usercmd, "IGD", 3) == 0)
  383. client_id = VGA_SWITCHEROO_IGD;
  384. if (strncmp(usercmd, "DIS", 3) == 0)
  385. client_id = VGA_SWITCHEROO_DIS;
  386. if (strncmp(usercmd, "MIGD", 4) == 0) {
  387. just_mux = true;
  388. client_id = VGA_SWITCHEROO_IGD;
  389. }
  390. if (strncmp(usercmd, "MDIS", 4) == 0) {
  391. just_mux = true;
  392. client_id = VGA_SWITCHEROO_DIS;
  393. }
  394. if (client_id == -1)
  395. goto out;
  396. client = find_client_from_id(&vgasr_priv.clients, client_id);
  397. if (!client)
  398. goto out;
  399. vgasr_priv.delayed_switch_active = false;
  400. if (just_mux) {
  401. ret = vgasr_priv.handler->switchto(client_id);
  402. goto out;
  403. }
  404. if (client->active)
  405. goto out;
  406. /* okay we want a switch - test if devices are willing to switch */
  407. can_switch = check_can_switch();
  408. if (can_switch == false && delay == false)
  409. goto out;
  410. if (can_switch) {
  411. ret = vga_switchto_stage1(client);
  412. if (ret)
  413. pr_err("switching failed stage 1 %d\n", ret);
  414. ret = vga_switchto_stage2(client);
  415. if (ret)
  416. pr_err("switching failed stage 2 %d\n", ret);
  417. } else {
  418. pr_info("setting delayed switch to client %d\n", client->id);
  419. vgasr_priv.delayed_switch_active = true;
  420. vgasr_priv.delayed_client_id = client_id;
  421. ret = vga_switchto_stage1(client);
  422. if (ret)
  423. pr_err("delayed switching stage 1 failed %d\n", ret);
  424. }
  425. out:
  426. mutex_unlock(&vgasr_mutex);
  427. return cnt;
  428. }
  429. static const struct file_operations vga_switcheroo_debugfs_fops = {
  430. .owner = THIS_MODULE,
  431. .open = vga_switcheroo_debugfs_open,
  432. .write = vga_switcheroo_debugfs_write,
  433. .read = seq_read,
  434. .llseek = seq_lseek,
  435. .release = single_release,
  436. };
  437. static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
  438. {
  439. debugfs_remove(priv->switch_file);
  440. priv->switch_file = NULL;
  441. debugfs_remove(priv->debugfs_root);
  442. priv->debugfs_root = NULL;
  443. }
  444. static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
  445. {
  446. static const char mp[] = "/sys/kernel/debug";
  447. /* already initialised */
  448. if (priv->debugfs_root)
  449. return 0;
  450. priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
  451. if (!priv->debugfs_root) {
  452. pr_err("Cannot create %s/vgaswitcheroo\n", mp);
  453. goto fail;
  454. }
  455. priv->switch_file = debugfs_create_file("switch", 0644,
  456. priv->debugfs_root, NULL,
  457. &vga_switcheroo_debugfs_fops);
  458. if (!priv->switch_file) {
  459. pr_err("cannot create %s/vgaswitcheroo/switch\n", mp);
  460. goto fail;
  461. }
  462. return 0;
  463. fail:
  464. vga_switcheroo_debugfs_fini(priv);
  465. return -1;
  466. }
  467. int vga_switcheroo_process_delayed_switch(void)
  468. {
  469. struct vga_switcheroo_client *client;
  470. int ret;
  471. int err = -EINVAL;
  472. mutex_lock(&vgasr_mutex);
  473. if (!vgasr_priv.delayed_switch_active)
  474. goto err;
  475. pr_info("processing delayed switch to %d\n",
  476. vgasr_priv.delayed_client_id);
  477. client = find_client_from_id(&vgasr_priv.clients,
  478. vgasr_priv.delayed_client_id);
  479. if (!client || !check_can_switch())
  480. goto err;
  481. ret = vga_switchto_stage2(client);
  482. if (ret)
  483. pr_err("delayed switching failed stage 2 %d\n", ret);
  484. vgasr_priv.delayed_switch_active = false;
  485. err = 0;
  486. err:
  487. mutex_unlock(&vgasr_mutex);
  488. return err;
  489. }
  490. EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
  491. static void vga_switcheroo_power_switch(struct pci_dev *pdev,
  492. enum vga_switcheroo_state state)
  493. {
  494. struct vga_switcheroo_client *client;
  495. if (!vgasr_priv.handler->power_state)
  496. return;
  497. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  498. if (!client)
  499. return;
  500. if (!client->driver_power_control)
  501. return;
  502. vgasr_priv.handler->power_state(client->id, state);
  503. }
  504. /* force a PCI device to a certain state - mainly to turn off audio clients */
  505. void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
  506. enum vga_switcheroo_state dynamic)
  507. {
  508. struct vga_switcheroo_client *client;
  509. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  510. if (!client)
  511. return;
  512. if (!client->driver_power_control)
  513. return;
  514. client->pwr_state = dynamic;
  515. set_audio_state(client->id, dynamic);
  516. }
  517. EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
  518. /* switcheroo power domain */
  519. static int vga_switcheroo_runtime_suspend(struct device *dev)
  520. {
  521. struct pci_dev *pdev = to_pci_dev(dev);
  522. int ret;
  523. ret = dev->bus->pm->runtime_suspend(dev);
  524. if (ret)
  525. return ret;
  526. if (vgasr_priv.handler->switchto)
  527. vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
  528. vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
  529. return 0;
  530. }
  531. static int vga_switcheroo_runtime_resume(struct device *dev)
  532. {
  533. struct pci_dev *pdev = to_pci_dev(dev);
  534. int ret;
  535. vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
  536. ret = dev->bus->pm->runtime_resume(dev);
  537. if (ret)
  538. return ret;
  539. return 0;
  540. }
  541. /* this version is for the case where the power switch is separate
  542. to the device being powered down. */
  543. int vga_switcheroo_init_domain_pm_ops(struct device *dev,
  544. struct dev_pm_domain *domain)
  545. {
  546. /* copy over all the bus versions */
  547. if (dev->bus && dev->bus->pm) {
  548. domain->ops = *dev->bus->pm;
  549. domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
  550. domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
  551. dev->pm_domain = domain;
  552. return 0;
  553. }
  554. dev->pm_domain = NULL;
  555. return -EINVAL;
  556. }
  557. EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
  558. void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
  559. {
  560. dev->pm_domain = NULL;
  561. }
  562. EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
  563. static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
  564. {
  565. struct pci_dev *pdev = to_pci_dev(dev);
  566. int ret;
  567. struct vga_switcheroo_client *client, *found = NULL;
  568. /* we need to check if we have to switch back on the video
  569. device so the audio device can come back */
  570. list_for_each_entry(client, &vgasr_priv.clients, list) {
  571. if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
  572. client_is_vga(client)) {
  573. found = client;
  574. ret = pm_runtime_get_sync(&client->pdev->dev);
  575. if (ret) {
  576. if (ret != 1)
  577. return ret;
  578. }
  579. break;
  580. }
  581. }
  582. ret = dev->bus->pm->runtime_resume(dev);
  583. /* put the reference for the gpu */
  584. if (found) {
  585. pm_runtime_mark_last_busy(&found->pdev->dev);
  586. pm_runtime_put_autosuspend(&found->pdev->dev);
  587. }
  588. return ret;
  589. }
  590. int
  591. vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
  592. struct dev_pm_domain *domain)
  593. {
  594. /* copy over all the bus versions */
  595. if (dev->bus && dev->bus->pm) {
  596. domain->ops = *dev->bus->pm;
  597. domain->ops.runtime_resume =
  598. vga_switcheroo_runtime_resume_hdmi_audio;
  599. dev->pm_domain = domain;
  600. return 0;
  601. }
  602. dev->pm_domain = NULL;
  603. return -EINVAL;
  604. }
  605. EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);