aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2008-06-02 00:41:57 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-06-02 00:41:57 -0400
commite8ef4347099584b49ecf74144ad2089b724292cf (patch)
tree2dd76225570d3f6d64785e588cf8f64454e59739 /drivers/input
parentf6d65610df3bd4e7138da03aec391224219df135 (diff)
Input: serio - remove pending events when unregistering driver
That fixes an opps when driver is repeatedly loaded and unloaded in a tight loop. Tested-by: Roland Kletzing <devzero@web.de> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/serio/serio.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 7f5293828fbf..78f2abb5c11b 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -331,9 +331,10 @@ static void serio_handle_event(void)
331} 331}
332 332
333/* 333/*
334 * Remove all events that have been submitted for a given serio port. 334 * Remove all events that have been submitted for a given
335 * object, be it serio port or driver.
335 */ 336 */
336static void serio_remove_pending_events(struct serio *serio) 337static void serio_remove_pending_events(void *object)
337{ 338{
338 struct list_head *node, *next; 339 struct list_head *node, *next;
339 struct serio_event *event; 340 struct serio_event *event;
@@ -343,7 +344,7 @@ static void serio_remove_pending_events(struct serio *serio)
343 344
344 list_for_each_safe(node, next, &serio_event_list) { 345 list_for_each_safe(node, next, &serio_event_list) {
345 event = list_entry(node, struct serio_event, node); 346 event = list_entry(node, struct serio_event, node);
346 if (event->object == serio) { 347 if (event->object == object) {
347 list_del_init(node); 348 list_del_init(node);
348 serio_free_event(event); 349 serio_free_event(event);
349 } 350 }
@@ -837,7 +838,9 @@ void serio_unregister_driver(struct serio_driver *drv)
837 struct serio *serio; 838 struct serio *serio;
838 839
839 mutex_lock(&serio_mutex); 840 mutex_lock(&serio_mutex);
841
840 drv->manual_bind = 1; /* so serio_find_driver ignores it */ 842 drv->manual_bind = 1; /* so serio_find_driver ignores it */
843 serio_remove_pending_events(drv);
841 844
842start_over: 845start_over:
843 list_for_each_entry(serio, &serio_list, node) { 846 list_for_each_entry(serio, &serio_list, node) {