Commit e9f80f33 authored by Viresh Kumar's avatar Viresh Kumar Committed by Greg Kroah-Hartman

greybus: uart: 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: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 19cdabcf
......@@ -674,6 +674,7 @@ static int set_serial_info(struct gb_tty *gb_tty,
static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg)
{
int retval = 0;
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
struct async_icount old;
struct async_icount new;
......@@ -682,11 +683,11 @@ static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg)
return -EINVAL;
do {
spin_lock_irq(&gb_tty->read_lock);
spin_lock_irqsave(&gb_tty->read_lock, flags);
old = gb_tty->oldcount;
new = gb_tty->iocount;
gb_tty->oldcount = new;
spin_unlock_irq(&gb_tty->read_lock);
spin_unlock_irqrestore(&gb_tty->read_lock, flags);
if ((arg & TIOCM_DSR) && (old.dsr != new.dsr))
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment