|
@@ -858,6 +858,30 @@ static void mxs_auart_reset_deassert(struct uart_port *u)
|
|
|
writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
|
|
|
}
|
|
|
|
|
|
+static void mxs_auart_reset_assert(struct uart_port *u)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ reg = readl(u->membase + AUART_CTRL0);
|
|
|
+ /* if already in reset state, keep it untouched */
|
|
|
+ if (reg & AUART_CTRL0_SFTRST)
|
|
|
+ return;
|
|
|
+
|
|
|
+ writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
|
|
|
+ writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_SET);
|
|
|
+
|
|
|
+ for (i = 0; i < 1000; i++) {
|
|
|
+ reg = readl(u->membase + AUART_CTRL0);
|
|
|
+ /* reset is finished when the clock is gated */
|
|
|
+ if (reg & AUART_CTRL0_CLKGATE)
|
|
|
+ return;
|
|
|
+ udelay(10);
|
|
|
+ }
|
|
|
+
|
|
|
+ dev_err(u->dev, "Failed to reset the unit.");
|
|
|
+}
|
|
|
+
|
|
|
static int mxs_auart_startup(struct uart_port *u)
|
|
|
{
|
|
|
int ret;
|
|
@@ -867,7 +891,13 @@ static int mxs_auart_startup(struct uart_port *u)
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
|
|
|
+ if (uart_console(u)) {
|
|
|
+ writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
|
|
|
+ } else {
|
|
|
+ /* reset the unit to a well known state */
|
|
|
+ mxs_auart_reset_assert(u);
|
|
|
+ mxs_auart_reset_deassert(u);
|
|
|
+ }
|
|
|
|
|
|
writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET);
|
|
|
|
|
@@ -899,12 +929,14 @@ static void mxs_auart_shutdown(struct uart_port *u)
|
|
|
if (auart_dma_enabled(s))
|
|
|
mxs_auart_dma_exit(s);
|
|
|
|
|
|
- writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
|
|
|
-
|
|
|
- writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
|
|
|
- u->membase + AUART_INTR_CLR);
|
|
|
-
|
|
|
- writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
|
|
|
+ if (uart_console(u)) {
|
|
|
+ writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
|
|
|
+ writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
|
|
|
+ u->membase + AUART_INTR_CLR);
|
|
|
+ writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
|
|
|
+ } else {
|
|
|
+ mxs_auart_reset_assert(u);
|
|
|
+ }
|
|
|
|
|
|
clk_disable_unprepare(s->clk);
|
|
|
}
|