Merge "msm_serial_hs: Call clk_set_rate() from non-atomic context" into msm-3.4
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 9386804..3f4d87b 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -484,8 +484,9 @@
* Goal is to have around 8 ms before indicate stale.
* roundup (((Bit Rate * .008) / 10) + 1
*/
-static void msm_hs_set_bps_locked(struct uart_port *uport,
- unsigned int bps)
+static unsigned long msm_hs_set_bps_locked(struct uart_port *uport,
+ unsigned int bps,
+ unsigned long flags)
{
unsigned long rxstale;
unsigned long data;
@@ -584,11 +585,16 @@
} else {
uport->uartclk = 7372800;
}
+
+ spin_unlock_irqrestore(&uport->lock, flags);
if (clk_set_rate(msm_uport->clk, uport->uartclk)) {
printk(KERN_WARNING "Error setting clock rate on UART\n");
- return;
+ WARN_ON(1);
+ spin_lock_irqsave(&uport->lock, flags);
+ return flags;
}
+ spin_lock_irqsave(&uport->lock, flags);
data = rxstale & UARTDM_IPR_STALE_LSB_BMSK;
data |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2);
@@ -600,6 +606,7 @@
*/
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
+ return flags;
}
@@ -668,6 +675,7 @@
unsigned int c_cflag = termios->c_cflag;
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+ mutex_lock(&msm_uport->clk_mutex);
spin_lock_irqsave(&uport->lock, flags);
/*
@@ -694,7 +702,7 @@
if (!uport->uartclk)
msm_hs_set_std_bps_locked(uport, bps);
else
- msm_hs_set_bps_locked(uport, bps);
+ flags = msm_hs_set_bps_locked(uport, bps, flags);
data = msm_hs_read(uport, UARTDM_MR2_ADDR);
data &= ~UARTDM_MR2_PARITY_MODE_BMSK;
@@ -777,6 +785,7 @@
msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
mb();
spin_unlock_irqrestore(&uport->lock, flags);
+ mutex_unlock(&msm_uport->clk_mutex);
}
/*