aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-10-10 21:30:03 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-10-10 21:34:47 -0400
commitba538cd2a83f3556448759283d2330a603005afe (patch)
treeb65d2ac13e5764d91b6ad1d44e0b88c5c699c8e6 /drivers/input
parentb5d21704361eefe337a36ebbb57a1d9927132511 (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.c28
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
110out: 111out:
@@ -112,17 +113,14 @@ out:
112 return retval; 113 return retval;
113} 114}
114 115
115static int serio_raw_cleanup(struct serio_raw *serio_raw) 116static 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
128static int serio_raw_release(struct inode *inode, struct file *file) 126static 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}