summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorSergey Organov <sorganov@gmail.com>2023-02-01 15:26:54 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-02-08 13:11:48 +0100
commitd45fb2e430e54fac6af3cabb39c36171c4bf3f52 (patch)
tree8d82191906391e249ca493904dc8ffb1bc41a4aa /drivers/tty
parentserial: 8250_pci1xxxx: Add power management functions to quad-uart driver (diff)
downloadlinux-d45fb2e430e54fac6af3cabb39c36171c4bf3f52.tar.xz
linux-d45fb2e430e54fac6af3cabb39c36171c4bf3f52.zip
serial: imx: factor-out common code to imx_uart_soft_reset()
We perform soft reset in 2 places, slightly differently for no sufficient reasons, so move more generic variant to a function, and re-use the code. Out of 2 repeat counters, 10 and 100, select 10, as the code works at interrupts disabled, and in practice the reset happens immediately. Signed-off-by: Sergey Organov <sorganov@gmail.com> Link: https://lore.kernel.org/r/20230201142700.4346-2-sorganov@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/imx.c73
1 files changed, 37 insertions, 36 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 0e0590d1b123..e7c88e7528d7 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -398,6 +398,39 @@ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
}
/* called with port.lock taken and irqs off */
+static void imx_uart_soft_reset(struct imx_port *sport)
+{
+ int i = 10;
+ u32 ucr2, ubir, ubmr, uts;
+
+ /*
+ * According to the Reference Manual description of the UART SRST bit:
+ *
+ * "Reset the transmit and receive state machines,
+ * all FIFOs and register USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD
+ * and UTS[6-3]".
+ *
+ * We don't need to restore the old values from USR1, USR2, URXD and
+ * UTXD. UBRC is read only, so only save/restore the other three
+ * registers.
+ */
+ ubir = imx_uart_readl(sport, UBIR);
+ ubmr = imx_uart_readl(sport, UBMR);
+ uts = imx_uart_readl(sport, IMX21_UTS);
+
+ ucr2 = imx_uart_readl(sport, UCR2);
+ imx_uart_writel(sport, ucr2 & ~UCR2_SRST, UCR2);
+
+ while (!(imx_uart_readl(sport, UCR2) & UCR2_SRST) && (--i > 0))
+ udelay(1);
+
+ /* Restore the registers */
+ imx_uart_writel(sport, ubir, UBIR);
+ imx_uart_writel(sport, ubmr, UBMR);
+ imx_uart_writel(sport, uts, IMX21_UTS);
+}
+
+/* called with port.lock taken and irqs off */
static void imx_uart_start_rx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
@@ -1400,7 +1433,7 @@ static void imx_uart_disable_dma(struct imx_port *sport)
static int imx_uart_startup(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- int retval, i;
+ int retval;
unsigned long flags;
int dma_is_inited = 0;
u32 ucr1, ucr2, ucr3, ucr4, uts;
@@ -1432,15 +1465,9 @@ static int imx_uart_startup(struct uart_port *port)
dma_is_inited = 1;
spin_lock_irqsave(&sport->port.lock, flags);
- /* Reset fifo's and state machines */
- i = 100;
- ucr2 = imx_uart_readl(sport, UCR2);
- ucr2 &= ~UCR2_SRST;
- imx_uart_writel(sport, ucr2, UCR2);
-
- while (!(imx_uart_readl(sport, UCR2) & UCR2_SRST) && (--i > 0))
- udelay(1);
+ /* Reset fifo's and state machines */
+ imx_uart_soft_reset(sport);
/*
* Finally, clear and enable interrupts
@@ -1596,8 +1623,6 @@ static void imx_uart_flush_buffer(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
struct scatterlist *sgl = &sport->tx_sgl[0];
- u32 ucr2;
- int i = 100, ubir, ubmr, uts;
if (!sport->dma_chan_tx)
return;
@@ -1615,32 +1640,8 @@ static void imx_uart_flush_buffer(struct uart_port *port)
sport->dma_is_txing = 0;
}
- /*
- * According to the Reference Manual description of the UART SRST bit:
- *
- * "Reset the transmit and receive state machines,
- * all FIFOs and register USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD
- * and UTS[6-3]".
- *
- * We don't need to restore the old values from USR1, USR2, URXD and
- * UTXD. UBRC is read only, so only save/restore the other three
- * registers.
- */
- ubir = imx_uart_readl(sport, UBIR);
- ubmr = imx_uart_readl(sport, UBMR);
- uts = imx_uart_readl(sport, IMX21_UTS);
-
- ucr2 = imx_uart_readl(sport, UCR2);
- ucr2 &= ~UCR2_SRST;
- imx_uart_writel(sport, ucr2, UCR2);
+ imx_uart_soft_reset(sport);
- while (!(imx_uart_readl(sport, UCR2) & UCR2_SRST) && (--i > 0))
- udelay(1);
-
- /* Restore the registers */
- imx_uart_writel(sport, ubir, UBIR);
- imx_uart_writel(sport, ubmr, UBMR);
- imx_uart_writel(sport, uts, IMX21_UTS);
}
static void