summaryrefslogtreecommitdiff
path: root/drivers/uwb
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2012-04-16 17:28:28 +0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-27 20:51:06 +0400
commite40b6d45d7dec827630e970d3e614408745c7384 (patch)
tree30ab4cf9bcb9214e326fa67f302e8ee0a3bc0a96 /drivers/uwb
parentcb17a9920b2c6fdae11afde6a550c40c6968f615 (diff)
downloadlinux-e40b6d45d7dec827630e970d3e614408745c7384.tar.xz
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>
Diffstat (limited to 'drivers/uwb')
-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 697e56a5bcdd..47146c894339 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -106,6 +106,7 @@ struct uwb_rc_neh {
u8 evt_type;
__le16 evt;
u8 context;
+ u8 completed;
uwb_rc_cmd_cb_f cb;
void *arg;
@@ -408,6 +409,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
struct device *dev = &rc->uwb_dev.dev;
struct uwb_rc_neh *neh;
struct uwb_rceb *notif;
+ unsigned long flags;
if (rceb->bEventContext == 0) {
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
} else {
neh = uwb_rc_neh_lookup(rc, rceb);
if (neh) {
- del_timer_sync(&neh->timer);
+ spin_lock_irqsave(&rc->neh_lock, flags);
+ /* to guard against a timeout */
+ neh->completed = 1;
+ del_timer(&neh->timer);
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
uwb_rc_neh_cb(neh, rceb, size);
} else
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)
unsigned long flags;
spin_lock_irqsave(&rc->neh_lock, flags);
+ if (neh->completed) {
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+ return;
+ }
if (neh->context)
__uwb_rc_neh_rm(rc, neh);
else