diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-04-16 15:28:28 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2012-05-11 13:13:54 +0100 |
commit | 52f274aeb59471c970756082dd94c8db630495f3 (patch) | |
tree | b8c95600b9a6a2c58c69c577585b49b2e58e272f /drivers | |
parent | 8047d2777a1a75d796b20876897c166de9664937 (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>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers')
-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 a269937be1b..8cb71bb333c 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -107,6 +107,7 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; + u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -409,6 +410,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); @@ -422,7 +424,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", @@ -568,6 +574,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 |