diff options
Diffstat (limited to 'drivers/input/serio/serio.c')
-rw-r--r-- | drivers/input/serio/serio.c | 142 |
1 files changed, 58 insertions, 84 deletions
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 0236f0d5fd91..c3b626e9eae7 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/stddef.h> | 31 | #include <linux/stddef.h> |
30 | #include <linux/module.h> | 32 | #include <linux/module.h> |
31 | #include <linux/serio.h> | 33 | #include <linux/serio.h> |
@@ -119,11 +121,10 @@ static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) | |||
119 | 121 | ||
120 | error = device_bind_driver(&serio->dev); | 122 | error = device_bind_driver(&serio->dev); |
121 | if (error) { | 123 | if (error) { |
122 | printk(KERN_WARNING | 124 | dev_warn(&serio->dev, |
123 | "serio: device_bind_driver() failed " | 125 | "device_bind_driver() failed for %s (%s) and %s, error: %d\n", |
124 | "for %s (%s) and %s, error: %d\n", | 126 | serio->phys, serio->name, |
125 | serio->phys, serio->name, | 127 | drv->description, error); |
126 | drv->description, error); | ||
127 | serio_disconnect_driver(serio); | 128 | serio_disconnect_driver(serio); |
128 | serio->dev.driver = NULL; | 129 | serio->dev.driver = NULL; |
129 | return error; | 130 | return error; |
@@ -138,9 +139,9 @@ static void serio_find_driver(struct serio *serio) | |||
138 | 139 | ||
139 | error = device_attach(&serio->dev); | 140 | error = device_attach(&serio->dev); |
140 | if (error < 0) | 141 | if (error < 0) |
141 | printk(KERN_WARNING | 142 | dev_warn(&serio->dev, |
142 | "serio: device_attach() failed for %s (%s), error: %d\n", | 143 | "device_attach() failed for %s (%s), error: %d\n", |
143 | serio->phys, serio->name, error); | 144 | serio->phys, serio->name, error); |
144 | } | 145 | } |
145 | 146 | ||
146 | 147 | ||
@@ -194,17 +195,14 @@ static int serio_queue_event(void *object, struct module *owner, | |||
194 | 195 | ||
195 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | 196 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); |
196 | if (!event) { | 197 | if (!event) { |
197 | printk(KERN_ERR | 198 | pr_err("Not enough memory to queue event %d\n", event_type); |
198 | "serio: Not enough memory to queue event %d\n", | ||
199 | event_type); | ||
200 | retval = -ENOMEM; | 199 | retval = -ENOMEM; |
201 | goto out; | 200 | goto out; |
202 | } | 201 | } |
203 | 202 | ||
204 | if (!try_module_get(owner)) { | 203 | if (!try_module_get(owner)) { |
205 | printk(KERN_WARNING | 204 | pr_warning("Can't get module reference, dropping event %d\n", |
206 | "serio: Can't get module reference, dropping event %d\n", | 205 | event_type); |
207 | event_type); | ||
208 | kfree(event); | 206 | kfree(event); |
209 | retval = -EINVAL; | 207 | retval = -EINVAL; |
210 | goto out; | 208 | goto out; |
@@ -230,14 +228,12 @@ static void serio_free_event(struct serio_event *event) | |||
230 | 228 | ||
231 | static void serio_remove_duplicate_events(struct serio_event *event) | 229 | static void serio_remove_duplicate_events(struct serio_event *event) |
232 | { | 230 | { |
233 | struct list_head *node, *next; | 231 | struct serio_event *e, *next; |
234 | struct serio_event *e; | ||
235 | unsigned long flags; | 232 | unsigned long flags; |
236 | 233 | ||
237 | spin_lock_irqsave(&serio_event_lock, flags); | 234 | spin_lock_irqsave(&serio_event_lock, flags); |
238 | 235 | ||
239 | list_for_each_safe(node, next, &serio_event_list) { | 236 | list_for_each_entry_safe(e, next, &serio_event_list, node) { |
240 | e = list_entry(node, struct serio_event, node); | ||
241 | if (event->object == e->object) { | 237 | if (event->object == e->object) { |
242 | /* | 238 | /* |
243 | * If this event is of different type we should not | 239 | * If this event is of different type we should not |
@@ -247,7 +243,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
247 | if (event->type != e->type) | 243 | if (event->type != e->type) |
248 | break; | 244 | break; |
249 | 245 | ||
250 | list_del_init(node); | 246 | list_del_init(&e->node); |
251 | serio_free_event(e); | 247 | serio_free_event(e); |
252 | } | 248 | } |
253 | } | 249 | } |
@@ -258,23 +254,18 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
258 | 254 | ||
259 | static struct serio_event *serio_get_event(void) | 255 | static struct serio_event *serio_get_event(void) |
260 | { | 256 | { |
261 | struct serio_event *event; | 257 | struct serio_event *event = NULL; |
262 | struct list_head *node; | ||
263 | unsigned long flags; | 258 | unsigned long flags; |
264 | 259 | ||
265 | spin_lock_irqsave(&serio_event_lock, flags); | 260 | spin_lock_irqsave(&serio_event_lock, flags); |
266 | 261 | ||
267 | if (list_empty(&serio_event_list)) { | 262 | if (!list_empty(&serio_event_list)) { |
268 | spin_unlock_irqrestore(&serio_event_lock, flags); | 263 | event = list_first_entry(&serio_event_list, |
269 | return NULL; | 264 | struct serio_event, node); |
265 | list_del_init(&event->node); | ||
270 | } | 266 | } |
271 | 267 | ||
272 | node = serio_event_list.next; | ||
273 | event = list_entry(node, struct serio_event, node); | ||
274 | list_del_init(node); | ||
275 | |||
276 | spin_unlock_irqrestore(&serio_event_lock, flags); | 268 | spin_unlock_irqrestore(&serio_event_lock, flags); |
277 | |||
278 | return event; | 269 | return event; |
279 | } | 270 | } |
280 | 271 | ||
@@ -284,38 +275,30 @@ static void serio_handle_event(void) | |||
284 | 275 | ||
285 | mutex_lock(&serio_mutex); | 276 | mutex_lock(&serio_mutex); |
286 | 277 | ||
287 | /* | 278 | while ((event = serio_get_event())) { |
288 | * Note that we handle only one event here to give swsusp | ||
289 | * a chance to freeze kseriod thread. Serio events should | ||
290 | * be pretty rare so we are not concerned about taking | ||
291 | * performance hit. | ||
292 | */ | ||
293 | if ((event = serio_get_event())) { | ||
294 | 279 | ||
295 | switch (event->type) { | 280 | switch (event->type) { |
296 | case SERIO_REGISTER_PORT: | ||
297 | serio_add_port(event->object); | ||
298 | break; | ||
299 | 281 | ||
300 | case SERIO_RECONNECT_PORT: | 282 | case SERIO_REGISTER_PORT: |
301 | serio_reconnect_port(event->object); | 283 | serio_add_port(event->object); |
302 | break; | 284 | break; |
303 | 285 | ||
304 | case SERIO_RESCAN_PORT: | 286 | case SERIO_RECONNECT_PORT: |
305 | serio_disconnect_port(event->object); | 287 | serio_reconnect_port(event->object); |
306 | serio_find_driver(event->object); | 288 | break; |
307 | break; | ||
308 | 289 | ||
309 | case SERIO_RECONNECT_CHAIN: | 290 | case SERIO_RESCAN_PORT: |
310 | serio_reconnect_chain(event->object); | 291 | serio_disconnect_port(event->object); |
311 | break; | 292 | serio_find_driver(event->object); |
293 | break; | ||
312 | 294 | ||
313 | case SERIO_ATTACH_DRIVER: | 295 | case SERIO_RECONNECT_CHAIN: |
314 | serio_attach_driver(event->object); | 296 | serio_reconnect_chain(event->object); |
315 | break; | 297 | break; |
316 | 298 | ||
317 | default: | 299 | case SERIO_ATTACH_DRIVER: |
318 | break; | 300 | serio_attach_driver(event->object); |
301 | break; | ||
319 | } | 302 | } |
320 | 303 | ||
321 | serio_remove_duplicate_events(event); | 304 | serio_remove_duplicate_events(event); |
@@ -331,16 +314,14 @@ static void serio_handle_event(void) | |||
331 | */ | 314 | */ |
332 | static void serio_remove_pending_events(void *object) | 315 | static void serio_remove_pending_events(void *object) |
333 | { | 316 | { |
334 | struct list_head *node, *next; | 317 | struct serio_event *event, *next; |
335 | struct serio_event *event; | ||
336 | unsigned long flags; | 318 | unsigned long flags; |
337 | 319 | ||
338 | spin_lock_irqsave(&serio_event_lock, flags); | 320 | spin_lock_irqsave(&serio_event_lock, flags); |
339 | 321 | ||
340 | list_for_each_safe(node, next, &serio_event_list) { | 322 | list_for_each_entry_safe(event, next, &serio_event_list, node) { |
341 | event = list_entry(node, struct serio_event, node); | ||
342 | if (event->object == object) { | 323 | if (event->object == object) { |
343 | list_del_init(node); | 324 | list_del_init(&event->node); |
344 | serio_free_event(event); | 325 | serio_free_event(event); |
345 | } | 326 | } |
346 | } | 327 | } |
@@ -380,14 +361,12 @@ static struct serio *serio_get_pending_child(struct serio *parent) | |||
380 | 361 | ||
381 | static int serio_thread(void *nothing) | 362 | static int serio_thread(void *nothing) |
382 | { | 363 | { |
383 | set_freezable(); | ||
384 | do { | 364 | do { |
385 | serio_handle_event(); | 365 | serio_handle_event(); |
386 | wait_event_freezable(serio_wait, | 366 | wait_event_interruptible(serio_wait, |
387 | kthread_should_stop() || !list_empty(&serio_event_list)); | 367 | kthread_should_stop() || !list_empty(&serio_event_list)); |
388 | } while (!kthread_should_stop()); | 368 | } while (!kthread_should_stop()); |
389 | 369 | ||
390 | printk(KERN_DEBUG "serio: kseriod exiting\n"); | ||
391 | return 0; | 370 | return 0; |
392 | } | 371 | } |
393 | 372 | ||
@@ -452,6 +431,11 @@ static struct attribute_group serio_id_attr_group = { | |||
452 | .attrs = serio_device_id_attrs, | 431 | .attrs = serio_device_id_attrs, |
453 | }; | 432 | }; |
454 | 433 | ||
434 | static const struct attribute_group *serio_device_attr_groups[] = { | ||
435 | &serio_id_attr_group, | ||
436 | NULL | ||
437 | }; | ||
438 | |||
455 | static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 439 | static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
456 | { | 440 | { |
457 | struct serio *serio = to_serio_port(dev); | 441 | struct serio *serio = to_serio_port(dev); |
@@ -539,6 +523,7 @@ static void serio_init_port(struct serio *serio) | |||
539 | (long)atomic_inc_return(&serio_no) - 1); | 523 | (long)atomic_inc_return(&serio_no) - 1); |
540 | serio->dev.bus = &serio_bus; | 524 | serio->dev.bus = &serio_bus; |
541 | serio->dev.release = serio_release_port; | 525 | serio->dev.release = serio_release_port; |
526 | serio->dev.groups = serio_device_attr_groups; | ||
542 | if (serio->parent) { | 527 | if (serio->parent) { |
543 | serio->dev.parent = &serio->parent->dev; | 528 | serio->dev.parent = &serio->parent->dev; |
544 | serio->depth = serio->parent->depth + 1; | 529 | serio->depth = serio->parent->depth + 1; |
@@ -562,21 +547,15 @@ static void serio_add_port(struct serio *serio) | |||
562 | } | 547 | } |
563 | 548 | ||
564 | list_add_tail(&serio->node, &serio_list); | 549 | list_add_tail(&serio->node, &serio_list); |
550 | |||
565 | if (serio->start) | 551 | if (serio->start) |
566 | serio->start(serio); | 552 | serio->start(serio); |
553 | |||
567 | error = device_add(&serio->dev); | 554 | error = device_add(&serio->dev); |
568 | if (error) | 555 | if (error) |
569 | printk(KERN_ERR | 556 | dev_err(&serio->dev, |
570 | "serio: device_add() failed for %s (%s), error: %d\n", | 557 | "device_add() failed for %s (%s), error: %d\n", |
571 | serio->phys, serio->name, error); | 558 | serio->phys, serio->name, error); |
572 | else { | ||
573 | serio->registered = true; | ||
574 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
575 | if (error) | ||
576 | printk(KERN_ERR | ||
577 | "serio: sysfs_create_group() failed for %s (%s), error: %d\n", | ||
578 | serio->phys, serio->name, error); | ||
579 | } | ||
580 | } | 559 | } |
581 | 560 | ||
582 | /* | 561 | /* |
@@ -603,11 +582,8 @@ static void serio_destroy_port(struct serio *serio) | |||
603 | serio->parent = NULL; | 582 | serio->parent = NULL; |
604 | } | 583 | } |
605 | 584 | ||
606 | if (serio->registered) { | 585 | if (device_is_registered(&serio->dev)) |
607 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | ||
608 | device_del(&serio->dev); | 586 | device_del(&serio->dev); |
609 | serio->registered = false; | ||
610 | } | ||
611 | 587 | ||
612 | list_del_init(&serio->node); | 588 | list_del_init(&serio->node); |
613 | serio_remove_pending_events(serio); | 589 | serio_remove_pending_events(serio); |
@@ -805,9 +781,8 @@ static void serio_attach_driver(struct serio_driver *drv) | |||
805 | 781 | ||
806 | error = driver_attach(&drv->driver); | 782 | error = driver_attach(&drv->driver); |
807 | if (error) | 783 | if (error) |
808 | printk(KERN_WARNING | 784 | pr_warning("driver_attach() failed for %s with error %d\n", |
809 | "serio: driver_attach() failed for %s with error %d\n", | 785 | drv->driver.name, error); |
810 | drv->driver.name, error); | ||
811 | } | 786 | } |
812 | 787 | ||
813 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) | 788 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) |
@@ -827,8 +802,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons | |||
827 | 802 | ||
828 | error = driver_register(&drv->driver); | 803 | error = driver_register(&drv->driver); |
829 | if (error) { | 804 | if (error) { |
830 | printk(KERN_ERR | 805 | pr_err("driver_register() failed for %s, error: %d\n", |
831 | "serio: driver_register() failed for %s, error: %d\n", | ||
832 | drv->driver.name, error); | 806 | drv->driver.name, error); |
833 | return error; | 807 | return error; |
834 | } | 808 | } |
@@ -994,7 +968,7 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
994 | 968 | ||
995 | if (likely(serio->drv)) { | 969 | if (likely(serio->drv)) { |
996 | ret = serio->drv->interrupt(serio, data, dfl); | 970 | ret = serio->drv->interrupt(serio, data, dfl); |
997 | } else if (!dfl && serio->registered) { | 971 | } else if (!dfl && device_is_registered(&serio->dev)) { |
998 | serio_rescan(serio); | 972 | serio_rescan(serio); |
999 | ret = IRQ_HANDLED; | 973 | ret = IRQ_HANDLED; |
1000 | } | 974 | } |
@@ -1025,7 +999,7 @@ static int __init serio_init(void) | |||
1025 | 999 | ||
1026 | error = bus_register(&serio_bus); | 1000 | error = bus_register(&serio_bus); |
1027 | if (error) { | 1001 | if (error) { |
1028 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | 1002 | pr_err("Failed to register serio bus, error: %d\n", error); |
1029 | return error; | 1003 | return error; |
1030 | } | 1004 | } |
1031 | 1005 | ||
@@ -1033,7 +1007,7 @@ static int __init serio_init(void) | |||
1033 | if (IS_ERR(serio_task)) { | 1007 | if (IS_ERR(serio_task)) { |
1034 | bus_unregister(&serio_bus); | 1008 | bus_unregister(&serio_bus); |
1035 | error = PTR_ERR(serio_task); | 1009 | error = PTR_ERR(serio_task); |
1036 | printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); | 1010 | pr_err("Failed to start kseriod, error: %d\n", error); |
1037 | return error; | 1011 | return error; |
1038 | } | 1012 | } |
1039 | 1013 | ||