aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-06-29 23:04:14 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-07-07 22:56:54 -0400
commit028791bb7d662550c7435d38daeb1f0b88ed5b17 (patch)
treec8898a058a1a177d1390b6aa7b76fa65ac8b264c
parent276e526cfb257add928a57b196ea3e5c22b703ef (diff)
drm/nouveau/kms: restore fbcon after display has been resumed
Under some complicated circumstances (boot, suspend, resume, attach second display, suspend, resume, suspend, detach second display, resume, suspend, attach second display, resume), the fb_set_suspend() call can somehow result in a modeset being attempted before we're ready for it and things blow up in fun ways. Running display init first fixes the issue. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c17
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.h1
3 files changed, 12 insertions, 19 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index ddd83756b9a2..5425ffe3931d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev)
652 ret = nouveau_do_resume(drm_dev); 652 ret = nouveau_do_resume(drm_dev);
653 if (ret) 653 if (ret)
654 return ret; 654 return ret;
655 if (drm_dev->mode_config.num_crtc)
656 nouveau_fbcon_set_suspend(drm_dev, 0);
657 655
658 nouveau_fbcon_zfill_all(drm_dev); 656 if (drm_dev->mode_config.num_crtc) {
659 if (drm_dev->mode_config.num_crtc)
660 nouveau_display_resume(drm_dev); 657 nouveau_display_resume(drm_dev);
658 nouveau_fbcon_set_suspend(drm_dev, 0);
659 }
660
661 return 0; 661 return 0;
662} 662}
663 663
@@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev)
683 ret = nouveau_do_resume(drm_dev); 683 ret = nouveau_do_resume(drm_dev);
684 if (ret) 684 if (ret)
685 return ret; 685 return ret;
686 if (drm_dev->mode_config.num_crtc) 686
687 nouveau_fbcon_set_suspend(drm_dev, 0); 687 if (drm_dev->mode_config.num_crtc) {
688 nouveau_fbcon_zfill_all(drm_dev);
689 if (drm_dev->mode_config.num_crtc)
690 nouveau_display_resume(drm_dev); 688 nouveau_display_resume(drm_dev);
689 nouveau_fbcon_set_suspend(drm_dev, 0);
690 }
691
691 return 0; 692 return 0;
692} 693}
693 694
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 64a42cfd3717..191665ee7f52 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
531 if (state == 1) 531 if (state == 1)
532 nouveau_fbcon_save_disable_accel(dev); 532 nouveau_fbcon_save_disable_accel(dev);
533 fb_set_suspend(drm->fbcon->helper.fbdev, state); 533 fb_set_suspend(drm->fbcon->helper.fbdev, state);
534 if (state == 0) 534 if (state == 0) {
535 nouveau_fbcon_restore_accel(dev); 535 nouveau_fbcon_restore_accel(dev);
536 nouveau_fbcon_zfill(dev, drm->fbcon);
537 }
536 console_unlock(); 538 console_unlock();
537 } 539 }
538} 540}
539
540void
541nouveau_fbcon_zfill_all(struct drm_device *dev)
542{
543 struct nouveau_drm *drm = nouveau_drm(dev);
544 if (drm->fbcon) {
545 nouveau_fbcon_zfill(dev, drm->fbcon);
546 }
547}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
index fdfc0c94fbcc..fcff797d2084 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
@@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info);
61int nouveau_fbcon_init(struct drm_device *dev); 61int nouveau_fbcon_init(struct drm_device *dev);
62void nouveau_fbcon_fini(struct drm_device *dev); 62void nouveau_fbcon_fini(struct drm_device *dev);
63void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); 63void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
64void nouveau_fbcon_zfill_all(struct drm_device *dev);
65void nouveau_fbcon_save_disable_accel(struct drm_device *dev); 64void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
66void nouveau_fbcon_restore_accel(struct drm_device *dev); 65void nouveau_fbcon_restore_accel(struct drm_device *dev);
67 66