aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/mpsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/mpsc.c')
-rw-r--r--drivers/serial/mpsc.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 3d2fcc57b1ce..d09f2097d5b0 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -183,6 +183,7 @@ struct mpsc_port_info {
183 u8 *txb_p; /* Phys addr of txb */ 183 u8 *txb_p; /* Phys addr of txb */
184 int txr_head; /* Where new data goes */ 184 int txr_head; /* Where new data goes */
185 int txr_tail; /* Where sent data comes off */ 185 int txr_tail; /* Where sent data comes off */
186 spinlock_t tx_lock; /* transmit lock */
186 187
187 /* Mirrored values of regs we can't read (if 'mirror_regs' set) */ 188 /* Mirrored values of regs we can't read (if 'mirror_regs' set) */
188 u32 MPSC_MPCR_m; 189 u32 MPSC_MPCR_m;
@@ -1212,6 +1213,9 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
1212{ 1213{
1213 struct mpsc_tx_desc *txre; 1214 struct mpsc_tx_desc *txre;
1214 int rc = 0; 1215 int rc = 0;
1216 unsigned long iflags;
1217
1218 spin_lock_irqsave(&pi->tx_lock, iflags);
1215 1219
1216 if (!mpsc_sdma_tx_active(pi)) { 1220 if (!mpsc_sdma_tx_active(pi)) {
1217 txre = (struct mpsc_tx_desc *)(pi->txr + 1221 txre = (struct mpsc_tx_desc *)(pi->txr +
@@ -1248,6 +1252,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
1248 mpsc_sdma_start_tx(pi); /* start next desc if ready */ 1252 mpsc_sdma_start_tx(pi); /* start next desc if ready */
1249 } 1253 }
1250 1254
1255 spin_unlock_irqrestore(&pi->tx_lock, iflags);
1251 return rc; 1256 return rc;
1252} 1257}
1253 1258
@@ -1338,11 +1343,16 @@ static void
1338mpsc_start_tx(struct uart_port *port) 1343mpsc_start_tx(struct uart_port *port)
1339{ 1344{
1340 struct mpsc_port_info *pi = (struct mpsc_port_info *)port; 1345 struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
1346 unsigned long iflags;
1347
1348 spin_lock_irqsave(&pi->tx_lock, iflags);
1341 1349
1342 mpsc_unfreeze(pi); 1350 mpsc_unfreeze(pi);
1343 mpsc_copy_tx_data(pi); 1351 mpsc_copy_tx_data(pi);
1344 mpsc_sdma_start_tx(pi); 1352 mpsc_sdma_start_tx(pi);
1345 1353
1354 spin_unlock_irqrestore(&pi->tx_lock, iflags);
1355
1346 pr_debug("mpsc_start_tx[%d]\n", port->line); 1356 pr_debug("mpsc_start_tx[%d]\n", port->line);
1347 return; 1357 return;
1348} 1358}
@@ -1625,6 +1635,16 @@ mpsc_console_write(struct console *co, const char *s, uint count)
1625 struct mpsc_port_info *pi = &mpsc_ports[co->index]; 1635 struct mpsc_port_info *pi = &mpsc_ports[co->index];
1626 u8 *bp, *dp, add_cr = 0; 1636 u8 *bp, *dp, add_cr = 0;
1627 int i; 1637 int i;
1638 unsigned long iflags;
1639
1640 spin_lock_irqsave(&pi->tx_lock, iflags);
1641
1642 while (pi->txr_head != pi->txr_tail) {
1643 while (mpsc_sdma_tx_active(pi))
1644 udelay(100);
1645 mpsc_sdma_intr_ack(pi);
1646 mpsc_tx_intr(pi);
1647 }
1628 1648
1629 while (mpsc_sdma_tx_active(pi)) 1649 while (mpsc_sdma_tx_active(pi))
1630 udelay(100); 1650 udelay(100);
@@ -1668,6 +1688,7 @@ mpsc_console_write(struct console *co, const char *s, uint count)
1668 pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1); 1688 pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1);
1669 } 1689 }
1670 1690
1691 spin_unlock_irqrestore(&pi->tx_lock, iflags);
1671 return; 1692 return;
1672} 1693}
1673 1694
@@ -2005,7 +2026,8 @@ mpsc_drv_probe(struct platform_device *dev)
2005 if (!(rc = mpsc_drv_map_regs(pi, dev))) { 2026 if (!(rc = mpsc_drv_map_regs(pi, dev))) {
2006 mpsc_drv_get_platform_data(pi, dev, dev->id); 2027 mpsc_drv_get_platform_data(pi, dev, dev->id);
2007 2028
2008 if (!(rc = mpsc_make_ready(pi))) 2029 if (!(rc = mpsc_make_ready(pi))) {
2030 spin_lock_init(&pi->tx_lock);
2009 if (!(rc = uart_add_one_port(&mpsc_reg, 2031 if (!(rc = uart_add_one_port(&mpsc_reg,
2010 &pi->port))) 2032 &pi->port)))
2011 rc = 0; 2033 rc = 0;
@@ -2014,6 +2036,7 @@ mpsc_drv_probe(struct platform_device *dev)
2014 (struct uart_port *)pi); 2036 (struct uart_port *)pi);
2015 mpsc_drv_unmap_regs(pi); 2037 mpsc_drv_unmap_regs(pi);
2016 } 2038 }
2039 }
2017 else 2040 else
2018 mpsc_drv_unmap_regs(pi); 2041 mpsc_drv_unmap_regs(pi);
2019 } 2042 }