aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2014-01-23 02:45:02 -0500
committerBen Skeggs <bskeggs@redhat.com>2014-01-29 18:20:28 -0500
commitf3980dc50c5117a952baee7135aae50d48304af3 (patch)
tree34f162b4df261f10701e13e279cf09363023797c
parent09c3de135063f93d7137ad112f551f293b1204cf (diff)
drm/nouveau: resume display if any later suspend bits fail
If either idling channels or suspending the fence were to fail, the display would never be resumed. Also if a client fails, resume the fence (not functionally important, but it would potentially leak memory). See https://bugs.freedesktop.org/show_bug.cgi?id=70213 Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index eecc6ca377c8..78c8e7146d56 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -503,19 +503,21 @@ nouveau_do_suspend(struct drm_device *dev)
503 if (drm->cechan) { 503 if (drm->cechan) {
504 ret = nouveau_channel_idle(drm->cechan); 504 ret = nouveau_channel_idle(drm->cechan);
505 if (ret) 505 if (ret)
506 return ret; 506 goto fail_display;
507 } 507 }
508 508
509 if (drm->channel) { 509 if (drm->channel) {
510 ret = nouveau_channel_idle(drm->channel); 510 ret = nouveau_channel_idle(drm->channel);
511 if (ret) 511 if (ret)
512 return ret; 512 goto fail_display;
513 } 513 }
514 514
515 NV_INFO(drm, "suspending client object trees...\n"); 515 NV_INFO(drm, "suspending client object trees...\n");
516 if (drm->fence && nouveau_fence(drm)->suspend) { 516 if (drm->fence && nouveau_fence(drm)->suspend) {
517 if (!nouveau_fence(drm)->suspend(drm)) 517 if (!nouveau_fence(drm)->suspend(drm)) {
518 return -ENOMEM; 518 ret = -ENOMEM;
519 goto fail_display;
520 }
519 } 521 }
520 522
521 list_for_each_entry(cli, &drm->clients, head) { 523 list_for_each_entry(cli, &drm->clients, head) {
@@ -537,6 +539,10 @@ fail_client:
537 nouveau_client_init(&cli->base); 539 nouveau_client_init(&cli->base);
538 } 540 }
539 541
542 if (drm->fence && nouveau_fence(drm)->resume)
543 nouveau_fence(drm)->resume(drm);
544
545fail_display:
540 if (dev->mode_config.num_crtc) { 546 if (dev->mode_config.num_crtc) {
541 NV_INFO(drm, "resuming display...\n"); 547 NV_INFO(drm, "resuming display...\n");
542 nouveau_display_resume(dev); 548 nouveau_display_resume(dev);