msm_serial: Use spin_lock_irqsave() and spin_lock_irqrestore() apis
Currently spin_lock() and spin_unlock() apis are used while handling
interrupts for synchronization which may create deadlock or schedule
out current interrupt processing part if any other interrupt comes on
the same cpu. Hence use spin_lock_irqsave() and spin_lock_irqrestore()
apis to make driver smp-safe.
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 4400441..9e85eb5 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -232,11 +232,12 @@
#ifdef CONFIG_SERIAL_MSM_RX_WAKEUP
static irqreturn_t msm_rx_irq(int irq, void *dev_id)
{
+ unsigned long flags;
struct uart_port *port = dev_id;
struct msm_port *msm_port = UART_TO_MSM(port);
int inject_wakeup = 0;
- spin_lock(&port->lock);
+ spin_lock_irqsave(&port->lock, flags);
if (msm_port->clk_state == MSM_CLK_OFF) {
/* ignore the first irq - it is a pending irq that occured
@@ -257,7 +258,7 @@
tty_flip_buffer_push(tty);
}
- spin_unlock(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}
#endif
@@ -358,11 +359,12 @@
static irqreturn_t msm_irq(int irq, void *dev_id)
{
+ unsigned long flags;
struct uart_port *port = dev_id;
struct msm_port *msm_port = UART_TO_MSM(port);
unsigned int misr;
- spin_lock(&port->lock);
+ spin_lock_irqsave(&port->lock, flags);
clk_enable(msm_port->clk);
misr = msm_read(port, UART_MISR);
msm_write(port, 0, UART_IMR); /* disable interrupt */
@@ -376,7 +378,7 @@
msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */
clk_disable(msm_port->clk);
- spin_unlock(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}