diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-11 01:30:03 (GMT) |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-11 01:34:47 (GMT) |
commit | ba538cd2a83f3556448759283d2330a603005afe (patch) | |
tree | b65d2ac13e5764d91b6ad1d44e0b88c5c699c8e6 | |
parent | b5d21704361eefe337a36ebbb57a1d9927132511 (diff) | |
download | linux-ba538cd2a83f3556448759283d2330a603005afe.tar.xz |
Input: serio_raw - use kref instead of rolling out its own refcounting
Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/serio/serio_raw.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index b7ba459..ef3a69c3 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -9,6 +9,7 @@ * the Free Software Foundation. */ +#include <linux/kref.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/poll.h> @@ -33,7 +34,7 @@ struct serio_raw { unsigned int tail, head; char name[16]; - unsigned int refcnt; + struct kref kref; struct serio *serio; struct miscdevice dev; wait_queue_head_t wait; @@ -104,7 +105,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) list->serio_raw = serio_raw; file->private_data = list; - serio_raw->refcnt++; + kref_get(&serio_raw->kref); list_add_tail(&list->node, &serio_raw->list); out: @@ -112,17 +113,14 @@ out: return retval; } -static int serio_raw_cleanup(struct serio_raw *serio_raw) +static void serio_raw_cleanup(struct kref *kref) { - if (--serio_raw->refcnt == 0) { - misc_deregister(&serio_raw->dev); - list_del_init(&serio_raw->node); - kfree(serio_raw); + struct serio_raw *serio_raw = + container_of(kref, struct serio_raw, kref); - return 1; - } - - return 0; + misc_deregister(&serio_raw->dev); + list_del_init(&serio_raw->node); + kfree(serio_raw); } static int serio_raw_release(struct inode *inode, struct file *file) @@ -132,7 +130,7 @@ static int serio_raw_release(struct inode *inode, struct file *file) mutex_lock(&serio_raw_mutex); - serio_raw_cleanup(serio_raw); + kref_put(&serio_raw->kref, serio_raw_cleanup); mutex_unlock(&serio_raw_mutex); return 0; @@ -283,7 +281,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) mutex_lock(&serio_raw_mutex); snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++); - serio_raw->refcnt = 1; + kref_init(&serio_raw->kref); serio_raw->serio = serio; INIT_LIST_HEAD(&serio_raw->list); init_waitqueue_head(&serio_raw->wait); @@ -357,8 +355,8 @@ static void serio_raw_disconnect(struct serio *serio) serio_set_drvdata(serio, NULL); serio_raw->serio = NULL; - if (!serio_raw_cleanup(serio_raw)) - wake_up_interruptible(&serio_raw->wait); + wake_up_interruptible(&serio_raw->wait); + kref_put(&serio_raw->kref, serio_raw_cleanup); mutex_unlock(&serio_raw_mutex); } |