drm/nouveau: resume display if any later suspend bits fail
authorIlia Mirkin <imirkin@alum.mit.edu>
Thu, 23 Jan 2014 07:45:02 +0000 (02:45 -0500)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 29 Jan 2014 23:20:28 +0000 (09:20 +1000)
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>
drivers/gpu/drm/nouveau/nouveau_drm.c

index eecc6ca377c8ef1b4295ac9bf735e48d81cc3b42..78c8e7146d56b2c5f7d189e372e542f4d9b43717 100644 (file)
@@ -503,19 +503,21 @@ nouveau_do_suspend(struct drm_device *dev)
        if (drm->cechan) {
                ret = nouveau_channel_idle(drm->cechan);
                if (ret)
-                       return ret;
+                       goto fail_display;
        }
 
        if (drm->channel) {
                ret = nouveau_channel_idle(drm->channel);
                if (ret)
-                       return ret;
+                       goto fail_display;
        }
 
        NV_INFO(drm, "suspending client object trees...\n");
        if (drm->fence && nouveau_fence(drm)->suspend) {
-               if (!nouveau_fence(drm)->suspend(drm))
-                       return -ENOMEM;
+               if (!nouveau_fence(drm)->suspend(drm)) {
+                       ret = -ENOMEM;
+                       goto fail_display;
+               }
        }
 
        list_for_each_entry(cli, &drm->clients, head) {
@@ -537,6 +539,10 @@ fail_client:
                nouveau_client_init(&cli->base);
        }
 
+       if (drm->fence && nouveau_fence(drm)->resume)
+               nouveau_fence(drm)->resume(drm);
+
+fail_display:
        if (dev->mode_config.num_crtc) {
                NV_INFO(drm, "resuming display...\n");
                nouveau_display_resume(dev);