aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2015-08-14 11:52:07 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-14 20:19:49 -0400
commit830acf9e3044d4644f91b4418ef35a2094089946 (patch)
tree35ee259df952b9e15eb9110605157c45fd47bf1a
parentcbba3e6f7a1eb642cccf520f690d4a58b97a9588 (diff)
tty: serial: 8250_omap: do not use RX DMA if pause is not supported
The 8250-omap driver requires the DMA-engine driver to support the pause command in order to properly turn off programmed RX transfer before the driver stars manually reading from the FIFO. The lacking support of the requirement has been discovered recently. In order to stay safe here we disable RX-DMA completly on probe. The rx_dma_broken assignment on probe could be removed once we working pause function in omap-dma. Cc: <stable@vger.kernel.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/8250/8250_omap.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index 0340ee6ba970..826c5c4a2103 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -112,6 +112,7 @@ struct omap8250_priv {
112 struct work_struct qos_work; 112 struct work_struct qos_work;
113 struct uart_8250_dma omap8250_dma; 113 struct uart_8250_dma omap8250_dma;
114 spinlock_t rx_dma_lock; 114 spinlock_t rx_dma_lock;
115 bool rx_dma_broken;
115}; 116};
116 117
117static u32 uart_read(struct uart_8250_port *up, u32 reg) 118static u32 uart_read(struct uart_8250_port *up, u32 reg)
@@ -761,6 +762,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
761 struct omap8250_priv *priv = p->port.private_data; 762 struct omap8250_priv *priv = p->port.private_data;
762 struct uart_8250_dma *dma = p->dma; 763 struct uart_8250_dma *dma = p->dma;
763 unsigned long flags; 764 unsigned long flags;
765 int ret;
764 766
765 spin_lock_irqsave(&priv->rx_dma_lock, flags); 767 spin_lock_irqsave(&priv->rx_dma_lock, flags);
766 768
@@ -769,7 +771,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
769 return; 771 return;
770 } 772 }
771 773
772 dmaengine_pause(dma->rxchan); 774 ret = dmaengine_pause(dma->rxchan);
775 if (WARN_ON_ONCE(ret))
776 priv->rx_dma_broken = true;
773 777
774 spin_unlock_irqrestore(&priv->rx_dma_lock, flags); 778 spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
775 779
@@ -813,6 +817,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
813 break; 817 break;
814 } 818 }
815 819
820 if (priv->rx_dma_broken)
821 return -EINVAL;
822
816 spin_lock_irqsave(&priv->rx_dma_lock, flags); 823 spin_lock_irqsave(&priv->rx_dma_lock, flags);
817 824
818 if (dma->rx_running) 825 if (dma->rx_running)
@@ -1207,6 +1214,11 @@ static int omap8250_probe(struct platform_device *pdev)
1207 1214
1208 if (of_machine_is_compatible("ti,am33xx")) 1215 if (of_machine_is_compatible("ti,am33xx"))
1209 priv->habit |= OMAP_DMA_TX_KICK; 1216 priv->habit |= OMAP_DMA_TX_KICK;
1217 /*
1218 * pause is currently not supported atleast on omap-sdma
1219 * and edma on most earlier kernels.
1220 */
1221 priv->rx_dma_broken = true;
1210 } 1222 }
1211 } 1223 }
1212#endif 1224#endif