diff options
| author | Roland Stigge <stigge@antcom.de> | 2012-02-27 11:28:02 -0500 |
|---|---|---|
| committer | Roland Stigge <stigge@antcom.de> | 2012-02-27 11:28:02 -0500 |
| commit | 2707208ee8a80dbbd5426f5aa1a934f766825bb5 (patch) | |
| tree | 91cdaf595011eb7618d9160f9e2cbea890f54509 | |
| parent | 94ed7830cba4dce57b18a2926b5d826bfd184bd6 (diff) | |
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: Roland Stigge <stigge@antcom.de>
Cc: stable@vger.kernel.org
| -rw-r--r-- | arch/arm/mach-lpc32xx/serial.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c index 429cfdbb2b3d..1a3fd4ce0469 100644 --- a/arch/arm/mach-lpc32xx/serial.c +++ b/arch/arm/mach-lpc32xx/serial.c | |||
| @@ -88,6 +88,7 @@ struct uartinit { | |||
| 88 | char *uart_ck_name; | 88 | char *uart_ck_name; |
| 89 | u32 ck_mode_mask; | 89 | u32 ck_mode_mask; |
| 90 | void __iomem *pdiv_clk_reg; | 90 | void __iomem *pdiv_clk_reg; |
| 91 | resource_size_t mapbase; | ||
| 91 | }; | 92 | }; |
| 92 | 93 | ||
| 93 | static struct uartinit uartinit_data[] __initdata = { | 94 | static struct uartinit uartinit_data[] __initdata = { |
| @@ -97,6 +98,7 @@ static struct uartinit uartinit_data[] __initdata = { | |||
| 97 | .ck_mode_mask = | 98 | .ck_mode_mask = |
| 98 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5), | 99 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5), |
| 99 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL, | 100 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL, |
| 101 | .mapbase = LPC32XX_UART5_BASE, | ||
| 100 | }, | 102 | }, |
| 101 | #endif | 103 | #endif |
| 102 | #ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT | 104 | #ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT |
| @@ -105,6 +107,7 @@ static struct uartinit uartinit_data[] __initdata = { | |||
| 105 | .ck_mode_mask = | 107 | .ck_mode_mask = |
| 106 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3), | 108 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3), |
| 107 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL, | 109 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL, |
| 110 | .mapbase = LPC32XX_UART3_BASE, | ||
| 108 | }, | 111 | }, |
| 109 | #endif | 112 | #endif |
| 110 | #ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT | 113 | #ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT |
| @@ -113,6 +116,7 @@ static struct uartinit uartinit_data[] __initdata = { | |||
| 113 | .ck_mode_mask = | 116 | .ck_mode_mask = |
| 114 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4), | 117 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4), |
| 115 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL, | 118 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL, |
| 119 | .mapbase = LPC32XX_UART4_BASE, | ||
| 116 | }, | 120 | }, |
| 117 | #endif | 121 | #endif |
| 118 | #ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT | 122 | #ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT |
| @@ -121,6 +125,7 @@ static struct uartinit uartinit_data[] __initdata = { | |||
| 121 | .ck_mode_mask = | 125 | .ck_mode_mask = |
| 122 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6), | 126 | LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6), |
| 123 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL, | 127 | .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL, |
| 128 | .mapbase = LPC32XX_UART6_BASE, | ||
| 124 | }, | 129 | }, |
| 125 | #endif | 130 | #endif |
| 126 | }; | 131 | }; |
| @@ -165,6 +170,19 @@ void __init lpc32xx_serial_init(void) | |||
| 165 | 170 | ||
| 166 | /* pre-UART clock divider set to 1 */ | 171 | /* pre-UART clock divider set to 1 */ |
| 167 | __raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg); | 172 | __raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg); |
| 173 | |||
| 174 | /* | ||
| 175 | * Force a flush of the RX FIFOs to work around a | ||
| 176 | * HW bug | ||
| 177 | */ | ||
| 178 | puart = uartinit_data[i].mapbase; | ||
| 179 | __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart)); | ||
| 180 | __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart)); | ||
| 181 | j = LPC32XX_SUART_FIFO_SIZE; | ||
| 182 | while (j--) | ||
| 183 | tmp = __raw_readl( | ||
| 184 | LPC32XX_UART_DLL_FIFO(puart)); | ||
| 185 | __raw_writel(0, LPC32XX_UART_IIR_FCR(puart)); | ||
| 168 | } | 186 | } |
| 169 | 187 | ||
| 170 | /* This needs to be done after all UART clocks are setup */ | 188 | /* This needs to be done after all UART clocks are setup */ |
