diff options
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r-- | drivers/gpu/drm/drm_gem.c | 109 |
1 files changed, 100 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 512078ebd97b..8b55ece97967 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -257,7 +257,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) | |||
257 | struct drm_gem_object *obj = ptr; | 257 | struct drm_gem_object *obj = ptr; |
258 | struct drm_device *dev = obj->dev; | 258 | struct drm_device *dev = obj->dev; |
259 | 259 | ||
260 | if (dev->driver->gem_close_object) | 260 | if (obj->funcs && obj->funcs->close) |
261 | obj->funcs->close(obj, file_priv); | ||
262 | else if (dev->driver->gem_close_object) | ||
261 | dev->driver->gem_close_object(obj, file_priv); | 263 | dev->driver->gem_close_object(obj, file_priv); |
262 | 264 | ||
263 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | 265 | if (drm_core_check_feature(dev, DRIVER_PRIME)) |
@@ -410,7 +412,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, | |||
410 | if (ret) | 412 | if (ret) |
411 | goto err_remove; | 413 | goto err_remove; |
412 | 414 | ||
413 | if (dev->driver->gem_open_object) { | 415 | if (obj->funcs && obj->funcs->open) { |
416 | ret = obj->funcs->open(obj, file_priv); | ||
417 | if (ret) | ||
418 | goto err_revoke; | ||
419 | } else if (dev->driver->gem_open_object) { | ||
414 | ret = dev->driver->gem_open_object(obj, file_priv); | 420 | ret = dev->driver->gem_open_object(obj, file_priv); |
415 | if (ret) | 421 | if (ret) |
416 | goto err_revoke; | 422 | goto err_revoke; |
@@ -835,7 +841,9 @@ drm_gem_object_free(struct kref *kref) | |||
835 | container_of(kref, struct drm_gem_object, refcount); | 841 | container_of(kref, struct drm_gem_object, refcount); |
836 | struct drm_device *dev = obj->dev; | 842 | struct drm_device *dev = obj->dev; |
837 | 843 | ||
838 | if (dev->driver->gem_free_object_unlocked) { | 844 | if (obj->funcs) { |
845 | obj->funcs->free(obj); | ||
846 | } else if (dev->driver->gem_free_object_unlocked) { | ||
839 | dev->driver->gem_free_object_unlocked(obj); | 847 | dev->driver->gem_free_object_unlocked(obj); |
840 | } else if (dev->driver->gem_free_object) { | 848 | } else if (dev->driver->gem_free_object) { |
841 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | 849 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
@@ -864,13 +872,13 @@ drm_gem_object_put_unlocked(struct drm_gem_object *obj) | |||
864 | 872 | ||
865 | dev = obj->dev; | 873 | dev = obj->dev; |
866 | 874 | ||
867 | if (dev->driver->gem_free_object_unlocked) { | 875 | if (dev->driver->gem_free_object) { |
868 | kref_put(&obj->refcount, drm_gem_object_free); | ||
869 | } else { | ||
870 | might_lock(&dev->struct_mutex); | 876 | might_lock(&dev->struct_mutex); |
871 | if (kref_put_mutex(&obj->refcount, drm_gem_object_free, | 877 | if (kref_put_mutex(&obj->refcount, drm_gem_object_free, |
872 | &dev->struct_mutex)) | 878 | &dev->struct_mutex)) |
873 | mutex_unlock(&dev->struct_mutex); | 879 | mutex_unlock(&dev->struct_mutex); |
880 | } else { | ||
881 | kref_put(&obj->refcount, drm_gem_object_free); | ||
874 | } | 882 | } |
875 | } | 883 | } |
876 | EXPORT_SYMBOL(drm_gem_object_put_unlocked); | 884 | EXPORT_SYMBOL(drm_gem_object_put_unlocked); |
@@ -960,11 +968,14 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, | |||
960 | if (obj_size < vma->vm_end - vma->vm_start) | 968 | if (obj_size < vma->vm_end - vma->vm_start) |
961 | return -EINVAL; | 969 | return -EINVAL; |
962 | 970 | ||
963 | if (!dev->driver->gem_vm_ops) | 971 | if (obj->funcs && obj->funcs->vm_ops) |
972 | vma->vm_ops = obj->funcs->vm_ops; | ||
973 | else if (dev->driver->gem_vm_ops) | ||
974 | vma->vm_ops = dev->driver->gem_vm_ops; | ||
975 | else | ||
964 | return -EINVAL; | 976 | return -EINVAL; |
965 | 977 | ||
966 | vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; | 978 | vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; |
967 | vma->vm_ops = dev->driver->gem_vm_ops; | ||
968 | vma->vm_private_data = obj; | 979 | vma->vm_private_data = obj; |
969 | vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); | 980 | vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); |
970 | vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); | 981 | vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); |
@@ -1066,6 +1077,86 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, | |||
1066 | drm_printf_indent(p, indent, "imported=%s\n", | 1077 | drm_printf_indent(p, indent, "imported=%s\n", |
1067 | obj->import_attach ? "yes" : "no"); | 1078 | obj->import_attach ? "yes" : "no"); |
1068 | 1079 | ||
1069 | if (obj->dev->driver->gem_print_info) | 1080 | if (obj->funcs && obj->funcs->print_info) |
1081 | obj->funcs->print_info(p, indent, obj); | ||
1082 | else if (obj->dev->driver->gem_print_info) | ||
1070 | obj->dev->driver->gem_print_info(p, indent, obj); | 1083 | obj->dev->driver->gem_print_info(p, indent, obj); |
1071 | } | 1084 | } |
1085 | |||
1086 | /** | ||
1087 | * drm_gem_pin - Pin backing buffer in memory | ||
1088 | * @obj: GEM object | ||
1089 | * | ||
1090 | * Make sure the backing buffer is pinned in memory. | ||
1091 | * | ||
1092 | * Returns: | ||
1093 | * 0 on success or a negative error code on failure. | ||
1094 | */ | ||
1095 | int drm_gem_pin(struct drm_gem_object *obj) | ||
1096 | { | ||
1097 | if (obj->funcs && obj->funcs->pin) | ||
1098 | return obj->funcs->pin(obj); | ||
1099 | else if (obj->dev->driver->gem_prime_pin) | ||
1100 | return obj->dev->driver->gem_prime_pin(obj); | ||
1101 | else | ||
1102 | return 0; | ||
1103 | } | ||
1104 | EXPORT_SYMBOL(drm_gem_pin); | ||
1105 | |||
1106 | /** | ||
1107 | * drm_gem_unpin - Unpin backing buffer from memory | ||
1108 | * @obj: GEM object | ||
1109 | * | ||
1110 | * Relax the requirement that the backing buffer is pinned in memory. | ||
1111 | */ | ||
1112 | void drm_gem_unpin(struct drm_gem_object *obj) | ||
1113 | { | ||
1114 | if (obj->funcs && obj->funcs->unpin) | ||
1115 | obj->funcs->unpin(obj); | ||
1116 | else if (obj->dev->driver->gem_prime_unpin) | ||
1117 | obj->dev->driver->gem_prime_unpin(obj); | ||
1118 | } | ||
1119 | EXPORT_SYMBOL(drm_gem_unpin); | ||
1120 | |||
1121 | /** | ||
1122 | * drm_gem_vmap - Map buffer into kernel virtual address space | ||
1123 | * @obj: GEM object | ||
1124 | * | ||
1125 | * Returns: | ||
1126 | * A virtual pointer to a newly created GEM object or an ERR_PTR-encoded negative | ||
1127 | * error code on failure. | ||
1128 | */ | ||
1129 | void *drm_gem_vmap(struct drm_gem_object *obj) | ||
1130 | { | ||
1131 | void *vaddr; | ||
1132 | |||
1133 | if (obj->funcs && obj->funcs->vmap) | ||
1134 | vaddr = obj->funcs->vmap(obj); | ||
1135 | else if (obj->dev->driver->gem_prime_vmap) | ||
1136 | vaddr = obj->dev->driver->gem_prime_vmap(obj); | ||
1137 | else | ||
1138 | vaddr = ERR_PTR(-EOPNOTSUPP); | ||
1139 | |||
1140 | if (!vaddr) | ||
1141 | vaddr = ERR_PTR(-ENOMEM); | ||
1142 | |||
1143 | return vaddr; | ||
1144 | } | ||
1145 | EXPORT_SYMBOL(drm_gem_vmap); | ||
1146 | |||
1147 | /** | ||
1148 | * drm_gem_vunmap - Remove buffer mapping from kernel virtual address space | ||
1149 | * @obj: GEM object | ||
1150 | * @vaddr: Virtual address (can be NULL) | ||
1151 | */ | ||
1152 | void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr) | ||
1153 | { | ||
1154 | if (!vaddr) | ||
1155 | return; | ||
1156 | |||
1157 | if (obj->funcs && obj->funcs->vunmap) | ||
1158 | obj->funcs->vunmap(obj, vaddr); | ||
1159 | else if (obj->dev->driver->gem_prime_vunmap) | ||
1160 | obj->dev->driver->gem_prime_vunmap(obj, vaddr); | ||
1161 | } | ||
1162 | EXPORT_SYMBOL(drm_gem_vunmap); | ||