diff options
| author | Ilia Mirkin <imirkin@alum.mit.edu> | 2014-01-23 02:45:02 -0500 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2014-01-29 18:20:28 -0500 |
| commit | f3980dc50c5117a952baee7135aae50d48304af3 (patch) | |
| tree | 34f162b4df261f10701e13e279cf09363023797c /drivers | |
| parent | 09c3de135063f93d7137ad112f551f293b1204cf (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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 14 |
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 | |||
| 545 | fail_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); |
