Commit 2707208e authored by Roland Stigge's avatar Roland Stigge

ARM: LPC32xx: serial.c: HW bug workaround

This patch fixes a HW bug by flushing RX FIFOs of the UARTs on init. It was
ported from NXP's git.lpclinux.com tree.
Signed-off-by: default avatarRoland Stigge <stigge@antcom.de>
Cc: stable@vger.kernel.org
parent 94ed7830
...@@ -88,6 +88,7 @@ struct uartinit { ...@@ -88,6 +88,7 @@ struct uartinit {
char *uart_ck_name; char *uart_ck_name;
u32 ck_mode_mask; u32 ck_mode_mask;
void __iomem *pdiv_clk_reg; void __iomem *pdiv_clk_reg;
resource_size_t mapbase;
}; };
static struct uartinit uartinit_data[] __initdata = { static struct uartinit uartinit_data[] __initdata = {
...@@ -97,6 +98,7 @@ static struct uartinit uartinit_data[] __initdata = { ...@@ -97,6 +98,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask = .ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5), LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL, .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL,
.mapbase = LPC32XX_UART5_BASE,
}, },
#endif #endif
#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT #ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
...@@ -105,6 +107,7 @@ static struct uartinit uartinit_data[] __initdata = { ...@@ -105,6 +107,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask = .ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3), LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL, .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL,
.mapbase = LPC32XX_UART3_BASE,
}, },
#endif #endif
#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT #ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
...@@ -113,6 +116,7 @@ static struct uartinit uartinit_data[] __initdata = { ...@@ -113,6 +116,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask = .ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4), LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL, .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL,
.mapbase = LPC32XX_UART4_BASE,
}, },
#endif #endif
#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT #ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
...@@ -121,6 +125,7 @@ static struct uartinit uartinit_data[] __initdata = { ...@@ -121,6 +125,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask = .ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6), LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL, .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL,
.mapbase = LPC32XX_UART6_BASE,
}, },
#endif #endif
}; };
...@@ -165,6 +170,19 @@ void __init lpc32xx_serial_init(void) ...@@ -165,6 +170,19 @@ void __init lpc32xx_serial_init(void)
/* pre-UART clock divider set to 1 */ /* pre-UART clock divider set to 1 */
__raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg); __raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg);
/*
* Force a flush of the RX FIFOs to work around a
* HW bug
*/
puart = uartinit_data[i].mapbase;
__raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
__raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
j = LPC32XX_SUART_FIFO_SIZE;
while (j--)
tmp = __raw_readl(
LPC32XX_UART_DLL_FIFO(puart));
__raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
} }
/* This needs to be done after all UART clocks are setup */ /* This needs to be done after all UART clocks are setup */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment