diff options
| author | Ian Abbott <abbotti@mev.co.uk> | 2013-11-08 15:03:32 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-11 16:16:44 -0800 |
| commit | 5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540 (patch) | |
| tree | 0bfade11593603377f28228a2db2ed13cdaa7b7a | |
| parent | 45c2bc557ca333a2115bb9f812b026b482cca5fa (diff) | |
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>
| -rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 22 | ||||
| -rw-r--r-- | drivers/staging/comedi/comedidev.h | 2 |
2 files changed, 21 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); } diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 05cc8dbcd515..08652dfa8c03 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -23,6 +23,7 @@ #include <linux/mutex.h> #include <linux/spinlock_types.h> #include <linux/rwsem.h> +#include <linux/kref.h> #include "comedi.h" @@ -187,6 +188,7 @@ struct comedi_device { spinlock_t spinlock; struct mutex mutex; struct rw_semaphore attach_lock; + struct kref refcount; int n_subdevices; struct comedi_subdevice *subdevices; |
