Commit fbf81762e385d3d45acad057b654d56972acf58c

Authored by Dave Airlie
1 parent fc5ea29d72

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