summaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/comedi_fops.c
diff options
context:
space:
mode:
authorIan Abbott2013-11-08 16:03:32 +0100
committerGreg Kroah-Hartman2013-11-12 01:16:44 +0100
commit5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540 (patch)
tree0bfade11593603377f28228a2db2ed13cdaa7b7a /drivers/staging/comedi/comedi_fops.c
parentstaging: comedi: protect against detach during read operation (diff)
downloadkernel-qcow2-linux-5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540.tar.gz
kernel-qcow2-linux-5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540.tar.xz
kernel-qcow2-linux-5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540.zip
staging: comedi: add a kref to comedi device
Add a `struct kref refcount` member to `struct comedi_device` to allow safe destruction of the comedi device. Only free the comedi device via the 'release' callback `kref_put()`. Currently, nothing calls `kref_put()`, so the safe destruction is ineffective, but this will be addressed by later patches. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r--drivers/staging/comedi/comedi_fops.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index fa8da20df753..403324c895b1 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -89,12 +89,29 @@ static struct cdev comedi_cdev;
static void comedi_device_init(struct comedi_device *dev)
{
+ kref_init(&dev->refcount);
spin_lock_init(&dev->spinlock);
mutex_init(&dev->mutex);
init_rwsem(&dev->attach_lock);
dev->minor = -1;
}
+static void comedi_dev_kref_release(struct kref *kref)
+{
+ struct comedi_device *dev =
+ container_of(kref, struct comedi_device, refcount);
+
+ mutex_destroy(&dev->mutex);
+ kfree(dev);
+}
+
+int comedi_dev_put(struct comedi_device *dev)
+{
+ if (dev)
+ return kref_put(&dev->refcount, comedi_dev_kref_release);
+ return 1;
+}
+
static void comedi_device_cleanup(struct comedi_device *dev)
{
struct module *driver_module = NULL;
@@ -112,7 +129,6 @@ static void comedi_device_cleanup(struct comedi_device *dev)
dev->use_count--;
}
mutex_unlock(&dev->mutex);
- mutex_destroy(&dev->mutex);
}
static bool comedi_clear_board_dev(struct comedi_device *dev)
@@ -148,7 +164,7 @@ static void comedi_free_board_dev(struct comedi_device *dev)
MKDEV(COMEDI_MAJOR, dev->minor));
}
comedi_device_cleanup(dev);
- kfree(dev);
+ comedi_dev_put(dev);
}
}
@@ -2494,7 +2510,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
if (i == COMEDI_NUM_BOARD_MINORS) {
mutex_unlock(&dev->mutex);
comedi_device_cleanup(dev);
- kfree(dev);
+ comedi_dev_put(dev);
pr_err("comedi: error: ran out of minor numbers for board device files.\n");
return ERR_PTR(-EBUSY);
}