diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 3 |
4 files changed, 28 insertions, 28 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 0f33132fba3b..3e49babd62ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -284,7 +284,6 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) | |||
284 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | 284 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
285 | struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; | 285 | struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; |
286 | unsigned long flags; | 286 | unsigned long flags; |
287 | int ret; | ||
288 | 287 | ||
289 | /* decrement the refcount, and we're done if there's still refs */ | 288 | /* decrement the refcount, and we're done if there's still refs */ |
290 | if (likely(!atomic_dec_and_test(&chan->users))) { | 289 | if (likely(!atomic_dec_and_test(&chan->users))) { |
@@ -297,19 +296,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) | |||
297 | nouveau_debugfs_channel_fini(chan); | 296 | nouveau_debugfs_channel_fini(chan); |
298 | 297 | ||
299 | /* give it chance to idle */ | 298 | /* give it chance to idle */ |
300 | nouveau_fence_update(chan); | 299 | nouveau_channel_idle(chan); |
301 | if (chan->fence.sequence != chan->fence.sequence_ack) { | ||
302 | struct nouveau_fence *fence = NULL; | ||
303 | |||
304 | ret = nouveau_fence_new(chan, &fence, true); | ||
305 | if (ret == 0) { | ||
306 | ret = nouveau_fence_wait(fence, false, false); | ||
307 | nouveau_fence_unref(&fence); | ||
308 | } | ||
309 | |||
310 | if (ret) | ||
311 | NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); | ||
312 | } | ||
313 | 300 | ||
314 | /* ensure all outstanding fences are signaled. they should be if the | 301 | /* ensure all outstanding fences are signaled. they should be if the |
315 | * above attempts at idling were OK, but if we failed this'll tell TTM | 302 | * above attempts at idling were OK, but if we failed this'll tell TTM |
@@ -388,6 +375,27 @@ nouveau_channel_ref(struct nouveau_channel *chan, | |||
388 | *pchan = chan; | 375 | *pchan = chan; |
389 | } | 376 | } |
390 | 377 | ||
378 | void | ||
379 | nouveau_channel_idle(struct nouveau_channel *chan) | ||
380 | { | ||
381 | struct drm_device *dev = chan->dev; | ||
382 | struct nouveau_fence *fence = NULL; | ||
383 | int ret; | ||
384 | |||
385 | nouveau_fence_update(chan); | ||
386 | |||
387 | if (chan->fence.sequence != chan->fence.sequence_ack) { | ||
388 | ret = nouveau_fence_new(chan, &fence, true); | ||
389 | if (!ret) { | ||
390 | ret = nouveau_fence_wait(fence, false, false); | ||
391 | nouveau_fence_unref(&fence); | ||
392 | } | ||
393 | |||
394 | if (ret) | ||
395 | NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); | ||
396 | } | ||
397 | } | ||
398 | |||
391 | /* cleans up all the fifos from file_priv */ | 399 | /* cleans up all the fifos from file_priv */ |
392 | void | 400 | void |
393 | nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) | 401 | nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 7ff5b4369f03..a48c7da133d2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -197,22 +197,10 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) | |||
197 | 197 | ||
198 | NV_INFO(dev, "Idling channels...\n"); | 198 | NV_INFO(dev, "Idling channels...\n"); |
199 | for (i = 0; i < pfifo->channels; i++) { | 199 | for (i = 0; i < pfifo->channels; i++) { |
200 | struct nouveau_fence *fence = NULL; | ||
201 | |||
202 | chan = dev_priv->channels.ptr[i]; | 200 | chan = dev_priv->channels.ptr[i]; |
203 | if (!chan || !chan->pushbuf_bo) | ||
204 | continue; | ||
205 | |||
206 | ret = nouveau_fence_new(chan, &fence, true); | ||
207 | if (ret == 0) { | ||
208 | ret = nouveau_fence_wait(fence, false, false); | ||
209 | nouveau_fence_unref(&fence); | ||
210 | } | ||
211 | 201 | ||
212 | if (ret) { | 202 | if (chan && chan->pushbuf_bo) |
213 | NV_ERROR(dev, "Failed to idle channel %d for suspend\n", | 203 | nouveau_channel_idle(chan); |
214 | chan->id); | ||
215 | } | ||
216 | } | 204 | } |
217 | 205 | ||
218 | pgraph->fifo_access(dev, false); | 206 | pgraph->fifo_access(dev, false); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index a52b1da32031..d001453e857b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -847,6 +847,7 @@ extern void nouveau_channel_put_unlocked(struct nouveau_channel **); | |||
847 | extern void nouveau_channel_put(struct nouveau_channel **); | 847 | extern void nouveau_channel_put(struct nouveau_channel **); |
848 | extern void nouveau_channel_ref(struct nouveau_channel *chan, | 848 | extern void nouveau_channel_ref(struct nouveau_channel *chan, |
849 | struct nouveau_channel **pchan); | 849 | struct nouveau_channel **pchan); |
850 | extern void nouveau_channel_idle(struct nouveau_channel *chan); | ||
850 | 851 | ||
851 | /* nouveau_object.c */ | 852 | /* nouveau_object.c */ |
852 | #define NVOBJ_CLASS(d,c,e) do { \ | 853 | #define NVOBJ_CLASS(d,c,e) do { \ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 2fb7e9d47500..24540862a23f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -1017,6 +1017,9 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, | |||
1017 | if (IS_ERR(chan)) | 1017 | if (IS_ERR(chan)) |
1018 | return PTR_ERR(chan); | 1018 | return PTR_ERR(chan); |
1019 | 1019 | ||
1020 | /* Synchronize with the user channel */ | ||
1021 | nouveau_channel_idle(chan); | ||
1022 | |||
1020 | ret = nouveau_ramht_remove(chan, objfree->handle); | 1023 | ret = nouveau_ramht_remove(chan, objfree->handle); |
1021 | nouveau_channel_put(&chan); | 1024 | nouveau_channel_put(&chan); |
1022 | return ret; | 1025 | return ret; |