diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-10 21:30:03 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-10 21:34:47 -0400 |
commit | ba538cd2a83f3556448759283d2330a603005afe (patch) | |
tree | b65d2ac13e5764d91b6ad1d44e0b88c5c699c8e6 /drivers/input | |
parent | b5d21704361eefe337a36ebbb57a1d9927132511 (diff) |
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>
Diffstat (limited to 'drivers/input')
-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 b7ba4597f7f0..ef3a69c304d3 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kref.h> | ||
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
14 | #include <linux/poll.h> | 15 | #include <linux/poll.h> |
@@ -33,7 +34,7 @@ struct serio_raw { | |||
33 | unsigned int tail, head; | 34 | unsigned int tail, head; |
34 | 35 | ||
35 | char name[16]; | 36 | char name[16]; |
36 | unsigned int refcnt; | 37 | struct kref kref; |
37 | struct serio *serio; | 38 | struct serio *serio; |
38 | struct miscdevice dev; | 39 | struct miscdevice dev; |
39 | wait_queue_head_t wait; | 40 | wait_queue_head_t wait; |
@@ -104,7 +105,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
104 | list->serio_raw = serio_raw; | 105 | list->serio_raw = serio_raw; |
105 | file->private_data = list; | 106 | file->private_data = list; |
106 | 107 | ||
107 | serio_raw->refcnt++; | 108 | kref_get(&serio_raw->kref); |
108 | list_add_tail(&list->node, &serio_raw->list); | 109 | list_add_tail(&list->node, &serio_raw->list); |
109 | 110 | ||
110 | out: | 111 | out: |
@@ -112,17 +113,14 @@ out: | |||
112 | return retval; | 113 | return retval; |
113 | } | 114 | } |
114 | 115 | ||
115 | static int serio_raw_cleanup(struct serio_raw *serio_raw) | 116 | static void serio_raw_cleanup(struct kref *kref) |
116 | { | 117 | { |
117 | if (--serio_raw->refcnt == 0) { | 118 | struct serio_raw *serio_raw = |
118 | misc_deregister(&serio_raw->dev); | 119 | container_of(kref, struct serio_raw, kref); |
119 | list_del_init(&serio_raw->node); | ||
120 | kfree(serio_raw); | ||
121 | 120 | ||
122 | return 1; | 121 | misc_deregister(&serio_raw->dev); |
123 | } | 122 | list_del_init(&serio_raw->node); |
124 | 123 | kfree(serio_raw); | |
125 | return 0; | ||
126 | } | 124 | } |
127 | 125 | ||
128 | static int serio_raw_release(struct inode *inode, struct file *file) | 126 | 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) | |||
132 | 130 | ||
133 | mutex_lock(&serio_raw_mutex); | 131 | mutex_lock(&serio_raw_mutex); |
134 | 132 | ||
135 | serio_raw_cleanup(serio_raw); | 133 | kref_put(&serio_raw->kref, serio_raw_cleanup); |
136 | 134 | ||
137 | mutex_unlock(&serio_raw_mutex); | 135 | mutex_unlock(&serio_raw_mutex); |
138 | return 0; | 136 | return 0; |
@@ -283,7 +281,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) | |||
283 | mutex_lock(&serio_raw_mutex); | 281 | mutex_lock(&serio_raw_mutex); |
284 | 282 | ||
285 | snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++); | 283 | snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++); |
286 | serio_raw->refcnt = 1; | 284 | kref_init(&serio_raw->kref); |
287 | serio_raw->serio = serio; | 285 | serio_raw->serio = serio; |
288 | INIT_LIST_HEAD(&serio_raw->list); | 286 | INIT_LIST_HEAD(&serio_raw->list); |
289 | init_waitqueue_head(&serio_raw->wait); | 287 | init_waitqueue_head(&serio_raw->wait); |
@@ -357,8 +355,8 @@ static void serio_raw_disconnect(struct serio *serio) | |||
357 | serio_set_drvdata(serio, NULL); | 355 | serio_set_drvdata(serio, NULL); |
358 | 356 | ||
359 | serio_raw->serio = NULL; | 357 | serio_raw->serio = NULL; |
360 | if (!serio_raw_cleanup(serio_raw)) | 358 | wake_up_interruptible(&serio_raw->wait); |
361 | wake_up_interruptible(&serio_raw->wait); | 359 | kref_put(&serio_raw->kref, serio_raw_cleanup); |
362 | 360 | ||
363 | mutex_unlock(&serio_raw_mutex); | 361 | mutex_unlock(&serio_raw_mutex); |
364 | } | 362 | } |