#include <linux/smp_lock.h> /* For (un)lock_kernel */
#include <linux/dma-mapping.h>
#include <linux/mm.h>
+#include <linux/kref.h>
#include <linux/pagemap.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
#include <linux/mutex.h>
* DRM for its buffer objects.
*/
struct drm_gem_object {
+ /** Reference count of this object */
+ struct kref refcount;
+
+ /** Related drm device */
+ struct drm_device *dev;
+
/** File representing the shmem storage */
struct file *filp;
- spinlock_t lock;
-
/**
* Size of the object, in bytes. Immutable over the object's
* lifetime.
*/
size_t size;
- /** Reference count of this object, protected by object_lock */
- int refcount;
-
void *driver_private;
};
obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
+ obj->dev = dev;
obj->filp = shmem_file_setup("drm mm object", size, 0);
if (IS_ERR(obj->filp)) {
kfree(obj);
return NULL;
}
- obj->refcount = 1;
+ kref_init (&obj->refcount);
obj->size = size;
if (dev->driver->gem_init_object != NULL &&
void
drm_gem_object_reference(struct drm_device *dev, struct drm_gem_object *obj)
{
- spin_lock(&obj->lock);
- obj->refcount++;
- spin_unlock(&obj->lock);
+ kref_get(&obj->refcount);
}
EXPORT_SYMBOL(drm_gem_object_reference);
+static void
+drm_gem_object_free (struct kref *kref)
+{
+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
+ struct drm_device *dev = obj->dev;
+
+ if (dev->driver->gem_free_object != NULL)
+ dev->driver->gem_free_object(dev, obj);
+
+ fput(obj->filp);
+ kfree(obj);
+}
+
void
drm_gem_object_unreference(struct drm_device *dev, struct drm_gem_object *obj)
{
if (obj == NULL)
return;
- spin_lock(&obj->lock);
- obj->refcount--;
- spin_unlock(&obj->lock);
- if (obj->refcount == 0) {
- if (dev->driver->gem_free_object != NULL)
- dev->driver->gem_free_object(dev, obj);
-
- fput(obj->filp);
- kfree(obj);
- }
+ kref_put (&obj->refcount, drm_gem_object_free);
}
EXPORT_SYMBOL(drm_gem_object_unreference);