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