diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index 8bcbbf2bbfc..e4ffa9c3f6b 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -13,6 +13,7 @@ #include #include #include +#include /* UART Control Register Bit Fields.*/ #define URXD_CHARRDY (1<<15) @@ -144,8 +145,22 @@ struct mxc_uart { u32 ts; }; +static void _mxc_serial_flush(struct mxc_uart *base) +{ + unsigned int timeout = 4000; + + if (!(readl(&base->cr1) & UCR1_UARTEN) || + !(readl(&base->cr2) & UCR2_TXEN)) + return; + + while (!(readl(&base->sr2) & USR2_TXDC) && --timeout) + udelay(1); +} + static void _mxc_serial_init(struct mxc_uart *base, int use_dte) { + _mxc_serial_flush(base); + writel(0, &base->cr1); writel(0, &base->cr2); @@ -169,6 +184,8 @@ static void _mxc_serial_setbrg(struct mxc_uart *base, unsigned long clk, { u32 tmp; + _mxc_serial_flush(base); + tmp = RFDIV << UFCR_RFDIV_SHF; if (use_dte) tmp |= UFCR_DCEDTE; @@ -252,10 +269,17 @@ static int mxc_serial_init(void) return 0; } +static int mxc_serial_stop(void) +{ + _mxc_serial_flush(mxc_base); + + return 0; +} + static struct serial_device mxc_serial_drv = { .name = "mxc_serial", .start = mxc_serial_init, - .stop = NULL, + .stop = mxc_serial_stop, .setbrg = mxc_serial_setbrg, .putc = mxc_serial_putc, .puts = default_serial_puts,