diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-06-02 00:41:57 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-06-02 00:41:57 -0400 |
commit | e8ef4347099584b49ecf74144ad2089b724292cf (patch) | |
tree | 2dd76225570d3f6d64785e588cf8f64454e59739 /drivers/input/serio/serio.c | |
parent | f6d65610df3bd4e7138da03aec391224219df135 (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/serio/serio.c')
-rw-r--r-- | drivers/input/serio/serio.c | 9 |
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 | */ |
336 | static void serio_remove_pending_events(struct serio *serio) | 337 | static 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 | ||
842 | start_over: | 845 | start_over: |
843 | list_for_each_entry(serio, &serio_list, node) { | 846 | list_for_each_entry(serio, &serio_list, node) { |