aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/es2.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2016-06-23 23:23:06 +0530
committerGreg Kroah-Hartman <gregkh@google.com>2016-06-23 15:18:42 -0700
commitfe9054155d831fee7a8e737ff3898c4bc2e5fc4d (patch)
tree3a150eb86970ac2e7adab18031e0c1bdd51bd191 /drivers/staging/greybus/es2.c
parentgreybus: uart: don't use spin_lock_irq() (diff)
downloadlinux-dev-fe9054155d831fee7a8e737ff3898c4bc2e5fc4d.tar.xz
linux-dev-fe9054155d831fee7a8e737ff3898c4bc2e5fc4d.zip
greybus: es2.c: don't use spin_lock_irq()
spin_[un]lock_irq() routines should be used carefully as they things can go wrong, if they are mixed with spin_lock_irqsave() or other variants. The main problem is that spin_[un]lock_irq() routines doesn't check if the IRQs are already disabled/enabled on the local CPU and so spin_unlock_irq() will forcefully enable interrupts for example. This may not work well, if some other code was relying on interrupts being disabled. Use spin_lock_irqsave() and spin_unlock_restore() instead. This patch doesn't claim that it fixes the JIRA completely, but the issue was harder to reproduce for some iterations after this, which was quite easy to reproduce earlier on. Tested on EVT 2.0 with lots of debug patches to kernel and greybus. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/es2.c')
-rw-r--r--drivers/staging/greybus/es2.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c
index bdf502493e31..89fe7641cd24 100644
--- a/drivers/staging/greybus/es2.c
+++ b/drivers/staging/greybus/es2.c
@@ -496,11 +496,12 @@ static void message_cancel(struct gb_message *message)
struct gb_host_device *hd = message->operation->connection->hd;
struct es2_ap_dev *es2 = hd_to_es2(hd);
struct urb *urb;
+ unsigned long flags;
int i;
might_sleep();
- spin_lock_irq(&es2->cport_out_urb_lock);
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
urb = message->hcpriv;
/* Prevent dynamically allocated urb from being deallocated. */
@@ -513,14 +514,14 @@ static void message_cancel(struct gb_message *message)
break;
}
}
- spin_unlock_irq(&es2->cport_out_urb_lock);
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
usb_kill_urb(urb);
if (i < NUM_CPORT_OUT_URB) {
- spin_lock_irq(&es2->cport_out_urb_lock);
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
es2->cport_out_urb_cancelled[i] = false;
- spin_unlock_irq(&es2->cport_out_urb_lock);
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
}
usb_free_urb(urb);