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 <abbo...@mev.co.uk>
---
 drivers/staging/comedi/comedi_fops.c | 22 +++++++++++++++++++---
 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 fa8da20..403324c 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 05cc8db..08652df 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;
-- 
1.8.4.2

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to