From 304eda32920b5e23f6b9bc12eb40c7dc52a464ba Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 9 Jun 2011 00:24:59 +0000 Subject: drm/gem: add hooks to notify driver when object handle is created/destroyed Nouveau is going to use these hooks to map/unmap objects from a client's private GPU address space. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_gem.c') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 74e4ff57801..bad33596639 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -210,6 +210,8 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) idr_remove(&filp->object_idr, handle); spin_unlock(&filp->table_lock); + if (dev->driver->gem_close_object) + dev->driver->gem_close_object(obj, filp); drm_gem_object_handle_unreference_unlocked(obj); return 0; @@ -226,7 +228,8 @@ drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, u32 *handlep) { - int ret; + struct drm_device *dev = obj->dev; + int ret; /* * Get the user-visible handle using idr. @@ -247,6 +250,15 @@ again: return ret; drm_gem_object_handle_reference(obj); + + if (dev->driver->gem_open_object) { + ret = dev->driver->gem_open_object(obj, file_priv); + if (ret) { + drm_gem_handle_delete(file_priv, *handlep); + return ret; + } + } + return 0; } EXPORT_SYMBOL(drm_gem_handle_create); @@ -401,7 +413,12 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private) static int drm_gem_object_release_handle(int id, void *ptr, void *data) { + struct drm_file *file_priv = data; struct drm_gem_object *obj = ptr; + struct drm_device *dev = obj->dev; + + if (dev->driver->gem_close_object) + dev->driver->gem_close_object(obj, file_priv); drm_gem_object_handle_unreference_unlocked(obj); @@ -417,7 +434,7 @@ void drm_gem_release(struct drm_device *dev, struct drm_file *file_private) { idr_for_each(&file_private->object_idr, - &drm_gem_object_release_handle, NULL); + &drm_gem_object_release_handle, file_private); idr_remove_all(&file_private->object_idr); idr_destroy(&file_private->object_idr); -- cgit v1.2.3-70-g09d2 From 62cb70118c4efabb3c0a6f962168ddcad4344eef Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 7 Jun 2011 14:17:51 +0100 Subject: drm/gem: add support for private objects These small changes should allow GEM to be used with non shmem objects as well as shmem objects. In the GMA500 case it allows the base framebuffer to appear as a GEM object and thus acquire a handle and work with KMS. For i915 it ought to be trivial to get back the wasted memory but putting the system fb back into stolen RAM and in general I can imagine it allowing the use of GEM and thus KMS with all the older cards that have their framebuffer firmly placed in video RAM. Signed-off-by: Alan Cox Tested-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 26 ++++++++++++++++++++++++-- include/drm/drmP.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_gem.c') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 7c5b5f78f1f..186d62eb063 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -129,7 +129,7 @@ drm_gem_destroy(struct drm_device *dev) } /** - * Initialize an already allocate GEM object of the specified size with + * Initialize an already allocated GEM object of the specified size with * shmfs backing store. */ int drm_gem_object_init(struct drm_device *dev, @@ -150,6 +150,27 @@ int drm_gem_object_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_gem_object_init); +/** + * Initialize an already allocated GEM object of the specified size with + * no GEM provided backing store. Instead the caller is responsible for + * backing the object and handling it. + */ +int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size) +{ + BUG_ON((size & (PAGE_SIZE - 1)) != 0); + + obj->dev = dev; + obj->filp = NULL; + + kref_init(&obj->refcount); + atomic_set(&obj->handle_count, 0); + obj->size = size; + + return 0; +} +EXPORT_SYMBOL(drm_gem_private_object_init); + /** * Allocate a GEM object of the specified size with shmfs backing store */ @@ -444,7 +465,8 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) void drm_gem_object_release(struct drm_gem_object *obj) { - fput(obj->filp); + if (obj->filp) + fput(obj->filp); } EXPORT_SYMBOL(drm_gem_object_release); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d9c8c6c4639..9b7c2bb4bb4 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1541,6 +1541,8 @@ struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, size_t size); int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size); +int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size); void drm_gem_object_handle_free(struct drm_gem_object *obj); void drm_gem_vm_open(struct vm_area_struct *vma); void drm_gem_vm_close(struct vm_area_struct *vma); -- cgit v1.2.3-70-g09d2