aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorJiada Wang <jiada_wang@mentor.com>2014-12-09 04:11:23 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-09 17:23:07 -0500
commit73631813c1ed17437e9de86f82a477fa4bac90c1 (patch)
tree1adfd7774d7b636ba899d3c013221cd131b9f1fc /drivers/tty
parent55d8693acd65b1c14e011cbcbfad2a15626472cd (diff)
serial: imx: use locking to stop concurrent access of UCR1
Several places are accessing the UCR1 register without locking. This probably will cause a race issue when another thread is accessing the same register. Add locking to preventing concurrent access of the UCR1 register. Signed-off-by: Jiada Wang <jiada_wang@mentor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/imx.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index eb2210fa972e..c851247a27cb 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -731,6 +731,9 @@ static int start_rx_dma(struct imx_port *sport);
731static void imx_dma_rxint(struct imx_port *sport) 731static void imx_dma_rxint(struct imx_port *sport)
732{ 732{
733 unsigned long temp; 733 unsigned long temp;
734 unsigned long flags;
735
736 spin_lock_irqsave(&sport->port.lock, flags);
734 737
735 temp = readl(sport->port.membase + USR2); 738 temp = readl(sport->port.membase + USR2);
736 if ((temp & USR2_RDR) && !sport->dma_is_rxing) { 739 if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
@@ -744,6 +747,8 @@ static void imx_dma_rxint(struct imx_port *sport)
744 /* tell the DMA to receive the data. */ 747 /* tell the DMA to receive the data. */
745 start_rx_dma(sport); 748 start_rx_dma(sport);
746 } 749 }
750
751 spin_unlock_irqrestore(&sport->port.lock, flags);
747} 752}
748 753
749static irqreturn_t imx_int(int irq, void *dev_id) 754static irqreturn_t imx_int(int irq, void *dev_id)
@@ -873,6 +878,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
873static void imx_rx_dma_done(struct imx_port *sport) 878static void imx_rx_dma_done(struct imx_port *sport)
874{ 879{
875 unsigned long temp; 880 unsigned long temp;
881 unsigned long flags;
882
883 spin_lock_irqsave(&sport->port.lock, flags);
876 884
877 /* Enable this interrupt when the RXFIFO is empty. */ 885 /* Enable this interrupt when the RXFIFO is empty. */
878 temp = readl(sport->port.membase + UCR1); 886 temp = readl(sport->port.membase + UCR1);
@@ -884,6 +892,8 @@ static void imx_rx_dma_done(struct imx_port *sport)
884 /* Is the shutdown waiting for us? */ 892 /* Is the shutdown waiting for us? */
885 if (waitqueue_active(&sport->dma_wait)) 893 if (waitqueue_active(&sport->dma_wait))
886 wake_up(&sport->dma_wait); 894 wake_up(&sport->dma_wait);
895
896 spin_unlock_irqrestore(&sport->port.lock, flags);
887} 897}
888 898
889/* 899/*
@@ -1194,9 +1204,11 @@ static void imx_shutdown(struct uart_port *port)
1194 dmaengine_terminate_all(sport->dma_chan_tx); 1204 dmaengine_terminate_all(sport->dma_chan_tx);
1195 dmaengine_terminate_all(sport->dma_chan_rx); 1205 dmaengine_terminate_all(sport->dma_chan_rx);
1196 } 1206 }
1207 spin_lock_irqsave(&sport->port.lock, flags);
1197 imx_stop_tx(port); 1208 imx_stop_tx(port);
1198 imx_stop_rx(port); 1209 imx_stop_rx(port);
1199 imx_disable_dma(sport); 1210 imx_disable_dma(sport);
1211 spin_unlock_irqrestore(&sport->port.lock, flags);
1200 imx_uart_dma_exit(sport); 1212 imx_uart_dma_exit(sport);
1201 } 1213 }
1202 1214