Merge drm/drm-next into drm-misc-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / ttm / ttm_device.c
index 2df59b3c2ea1674cbc9349772a4c149d09ce8ca7..be24bb6cefd0b8f3b870b93a3f030e05117c2615 100644 (file)
@@ -220,6 +220,7 @@ int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs,
        INIT_DELAYED_WORK(&bdev->wq, ttm_device_delayed_workqueue);
        spin_lock_init(&bdev->lru_lock);
        INIT_LIST_HEAD(&bdev->ddestroy);
+       INIT_LIST_HEAD(&bdev->pinned);
        bdev->dev_mapping = mapping;
        mutex_lock(&ttm_global_mutex);
        list_add_tail(&bdev->device_list, &glob->device_list);
@@ -257,3 +258,50 @@ void ttm_device_fini(struct ttm_device *bdev)
        ttm_global_release();
 }
 EXPORT_SYMBOL(ttm_device_fini);
+
+void ttm_device_clear_dma_mappings(struct ttm_device *bdev)
+{
+       struct ttm_resource_manager *man;
+       struct ttm_buffer_object *bo;
+       unsigned int i, j;
+
+       spin_lock(&bdev->lru_lock);
+       while (!list_empty(&bdev->pinned)) {
+               bo = list_first_entry(&bdev->pinned, struct ttm_buffer_object, lru);
+               /* Take ref against racing releases once lru_lock is unlocked */
+               if (ttm_bo_get_unless_zero(bo)) {
+                       list_del_init(&bo->lru);
+                       spin_unlock(&bdev->lru_lock);
+
+                       if (bo->ttm)
+                               ttm_tt_unpopulate(bo->bdev, bo->ttm);
+
+                       ttm_bo_put(bo);
+                       spin_lock(&bdev->lru_lock);
+               }
+       }
+
+       for (i = TTM_PL_SYSTEM; i < TTM_NUM_MEM_TYPES; ++i) {
+               man = ttm_manager_type(bdev, i);
+               if (!man || !man->use_tt)
+                       continue;
+
+               for (j = 0; j < TTM_MAX_BO_PRIORITY; ++j) {
+                       while (!list_empty(&man->lru[j])) {
+                               bo = list_first_entry(&man->lru[j], struct ttm_buffer_object, lru);
+                               if (ttm_bo_get_unless_zero(bo)) {
+                                       list_del_init(&bo->lru);
+                                       spin_unlock(&bdev->lru_lock);
+
+                                       if (bo->ttm)
+                                               ttm_tt_unpopulate(bo->bdev, bo->ttm);
+
+                                       ttm_bo_put(bo);
+                                       spin_lock(&bdev->lru_lock);
+                               }
+                       }
+               }
+       }
+       spin_unlock(&bdev->lru_lock);
+}
+EXPORT_SYMBOL(ttm_device_clear_dma_mappings);