diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-04-16 09:28:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-18 16:15:51 -0400 |
commit | 9426cd05682745d1024dbabdec5631309bd2f480 (patch) | |
tree | a2db2587a008c8286cfc11fa6111bafd59faa4e9 | |
parent | 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b (diff) |
uwb: fix use of del_timer_sync() in interrupt
del_timer_sync() cannot be used in interrupt.
Replace it with del_timer() and a flag
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/uwb/neh.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index a269937be1b8..8cb71bb333c2 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c | |||
@@ -107,6 +107,7 @@ struct uwb_rc_neh { | |||
107 | u8 evt_type; | 107 | u8 evt_type; |
108 | __le16 evt; | 108 | __le16 evt; |
109 | u8 context; | 109 | u8 context; |
110 | u8 completed; | ||
110 | uwb_rc_cmd_cb_f cb; | 111 | uwb_rc_cmd_cb_f cb; |
111 | void *arg; | 112 | void *arg; |
112 | 113 | ||
@@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size | |||
409 | struct device *dev = &rc->uwb_dev.dev; | 410 | struct device *dev = &rc->uwb_dev.dev; |
410 | struct uwb_rc_neh *neh; | 411 | struct uwb_rc_neh *neh; |
411 | struct uwb_rceb *notif; | 412 | struct uwb_rceb *notif; |
413 | unsigned long flags; | ||
412 | 414 | ||
413 | if (rceb->bEventContext == 0) { | 415 | if (rceb->bEventContext == 0) { |
414 | notif = kmalloc(size, GFP_ATOMIC); | 416 | notif = kmalloc(size, GFP_ATOMIC); |
@@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size | |||
422 | } else { | 424 | } else { |
423 | neh = uwb_rc_neh_lookup(rc, rceb); | 425 | neh = uwb_rc_neh_lookup(rc, rceb); |
424 | if (neh) { | 426 | if (neh) { |
425 | del_timer_sync(&neh->timer); | 427 | spin_lock_irqsave(&rc->neh_lock, flags); |
428 | /* to guard against a timeout */ | ||
429 | neh->completed = 1; | ||
430 | del_timer(&neh->timer); | ||
431 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
426 | uwb_rc_neh_cb(neh, rceb, size); | 432 | uwb_rc_neh_cb(neh, rceb, size); |
427 | } else | 433 | } else |
428 | dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", | 434 | dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", |
@@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg) | |||
568 | unsigned long flags; | 574 | unsigned long flags; |
569 | 575 | ||
570 | spin_lock_irqsave(&rc->neh_lock, flags); | 576 | spin_lock_irqsave(&rc->neh_lock, flags); |
577 | if (neh->completed) { | ||
578 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
579 | return; | ||
580 | } | ||
571 | if (neh->context) | 581 | if (neh->context) |
572 | __uwb_rc_neh_rm(rc, neh); | 582 | __uwb_rc_neh_rm(rc, neh); |
573 | else | 583 | else |