aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2012-04-16 09:28:28 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-27 12:51:06 -0400
commite40b6d45d7dec827630e970d3e614408745c7384 (patch)
tree30ab4cf9bcb9214e326fa67f302e8ee0a3bc0a96
parentcb17a9920b2c6fdae11afde6a550c40c6968f615 (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.c12
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