Commit fbf81762e385d3d45acad057b654d56972acf58c
1 parent
fc5ea29d72
Exists in
master
and in
20 other branches
drm/kms: disable/enable poll around switcheroo on/off
Because we aren't in a suspend state the poll will still run when we have switcherooed a card off. Signed-off-by: Dave Airlie <airlied@redhat.com>
Showing 5 changed files with 33 additions and 7 deletions Side-by-side Diff
drivers/gpu/drm/drm_crtc_helper.c
... | ... | @@ -860,19 +860,24 @@ |
860 | 860 | } |
861 | 861 | } |
862 | 862 | |
863 | -void drm_kms_helper_poll_init(struct drm_device *dev) | |
863 | +void drm_kms_helper_poll_disable(struct drm_device *dev) | |
864 | 864 | { |
865 | - struct drm_connector *connector; | |
865 | + if (!dev->mode_config.poll_enabled) | |
866 | + return; | |
867 | + delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); | |
868 | +} | |
869 | +EXPORT_SYMBOL(drm_kms_helper_poll_disable); | |
870 | + | |
871 | +void drm_kms_helper_poll_enable(struct drm_device *dev) | |
872 | +{ | |
866 | 873 | bool poll = false; |
874 | + struct drm_connector *connector; | |
867 | 875 | int ret; |
868 | 876 | |
869 | 877 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
870 | 878 | if (connector->polled) |
871 | 879 | poll = true; |
872 | 880 | } |
873 | - slow_work_register_user(THIS_MODULE); | |
874 | - delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, | |
875 | - &output_poll_ops); | |
876 | 881 | |
877 | 882 | if (poll) { |
878 | 883 | ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD); |
879 | 884 | |
... | ... | @@ -880,11 +885,22 @@ |
880 | 885 | DRM_ERROR("delayed enqueue failed %d\n", ret); |
881 | 886 | } |
882 | 887 | } |
888 | +EXPORT_SYMBOL(drm_kms_helper_poll_enable); | |
889 | + | |
890 | +void drm_kms_helper_poll_init(struct drm_device *dev) | |
891 | +{ | |
892 | + slow_work_register_user(THIS_MODULE); | |
893 | + delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, | |
894 | + &output_poll_ops); | |
895 | + dev->mode_config.poll_enabled = true; | |
896 | + | |
897 | + drm_kms_helper_poll_enable(dev); | |
898 | +} | |
883 | 899 | EXPORT_SYMBOL(drm_kms_helper_poll_init); |
884 | 900 | |
885 | 901 | void drm_kms_helper_poll_fini(struct drm_device *dev) |
886 | 902 | { |
887 | - delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); | |
903 | + drm_kms_helper_poll_disable(dev); | |
888 | 904 | slow_work_unregister_user(THIS_MODULE); |
889 | 905 | } |
890 | 906 | EXPORT_SYMBOL(drm_kms_helper_poll_fini); |
drivers/gpu/drm/i915/i915_dma.c
... | ... | @@ -1399,12 +1399,14 @@ |
1399 | 1399 | struct drm_device *dev = pci_get_drvdata(pdev); |
1400 | 1400 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
1401 | 1401 | if (state == VGA_SWITCHEROO_ON) { |
1402 | - printk(KERN_INFO "i915: switched off\n"); | |
1402 | + printk(KERN_INFO "i915: switched on\n"); | |
1403 | 1403 | /* i915 resume handler doesn't set to D0 */ |
1404 | 1404 | pci_set_power_state(dev->pdev, PCI_D0); |
1405 | 1405 | i915_resume(dev); |
1406 | + drm_kms_helper_poll_enable(dev); | |
1406 | 1407 | } else { |
1407 | 1408 | printk(KERN_ERR "i915: switched off\n"); |
1409 | + drm_kms_helper_poll_disable(dev); | |
1408 | 1410 | i915_suspend(dev, pmm); |
1409 | 1411 | } |
1410 | 1412 | } |
drivers/gpu/drm/nouveau/nouveau_state.c
... | ... | @@ -376,12 +376,15 @@ |
376 | 376 | static void nouveau_switcheroo_set_state(struct pci_dev *pdev, |
377 | 377 | enum vga_switcheroo_state state) |
378 | 378 | { |
379 | + struct drm_device *dev = pci_get_drvdata(pdev); | |
379 | 380 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
380 | 381 | if (state == VGA_SWITCHEROO_ON) { |
381 | 382 | printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); |
382 | 383 | nouveau_pci_resume(pdev); |
384 | + drm_kms_helper_poll_enable(dev); | |
383 | 385 | } else { |
384 | 386 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); |
387 | + drm_kms_helper_poll_disable(dev); | |
385 | 388 | nouveau_pci_suspend(pdev, pmm); |
386 | 389 | } |
387 | 390 | } |
drivers/gpu/drm/radeon/radeon_device.c
... | ... | @@ -546,8 +546,10 @@ |
546 | 546 | /* don't suspend or resume card normally */ |
547 | 547 | rdev->powered_down = false; |
548 | 548 | radeon_resume_kms(dev); |
549 | + drm_kms_helper_poll_enable(dev); | |
549 | 550 | } else { |
550 | 551 | printk(KERN_INFO "radeon: switched off\n"); |
552 | + drm_kms_helper_poll_disable(dev); | |
551 | 553 | radeon_suspend_kms(dev, pmm); |
552 | 554 | /* don't suspend or resume card normally */ |
553 | 555 | rdev->powered_down = true; |
include/drm/drm_crtc_helper.h
... | ... | @@ -130,5 +130,8 @@ |
130 | 130 | extern void drm_kms_helper_poll_init(struct drm_device *dev); |
131 | 131 | extern void drm_kms_helper_poll_fini(struct drm_device *dev); |
132 | 132 | extern void drm_helper_hpd_irq_event(struct drm_device *dev); |
133 | + | |
134 | +extern void drm_kms_helper_poll_disable(struct drm_device *dev); | |
135 | +extern void drm_kms_helper_poll_enable(struct drm_device *dev); | |
133 | 136 | #endif |