From patchwork Fri Mar 25 11:56:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: ar71xx-make-bootconsole-wait-for-both-THRE-and-TEMT From: Christian Dresel X-Patchwork-Id: 38 Message-Id: <1458907015-16685-1-git-send-email-fff@chrisi01.de> To: franken-dev@freifunk.net Date: Fri, 25 Mar 2016 12:56:55 +0100 Fix the Race Condition on boot Signed-off-by: Christian Dresel new file: build_patches/openwrt/0005-ar71xx-make-bootconsole-wait-for-both-THRE-and-TEMT.patch --- ...e-bootconsole-wait-for-both-THRE-and-TEMT.patch | 86 ++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 build_patches/openwrt/0005-ar71xx-make-bootconsole-wait-for-both-THRE-and-TEMT.patch diff --git a/build_patches/openwrt/0005-ar71xx-make-bootconsole-wait-for-both-THRE-and-TEMT.patch b/build_patches/openwrt/0005-ar71xx-make-bootconsole-wait-for-both-THRE-and-TEMT.patch new file mode 100644 index 0000000..ada44bc --- /dev/null +++ b/build_patches/openwrt/0005-ar71xx-make-bootconsole-wait-for-both-THRE-and-TEMT.patch @@ -0,0 +1,86 @@ +From: Matthias Schiffer +Date: Thu, 24 Mar 2016 18:30:26 +0100 +Subject: ar71xx: make bootconsole wait for both THRE and TEMT + +Original commit message: + + MIPS: ath79: make bootconsole wait for both THRE and TEMT + + This makes the ath79 bootconsole behave the same way as the generic 8250 + bootconsole. + + Also waiting for TEMT (transmit buffer is empty) instead of just THRE + (transmit buffer is not full) ensures that all characters have been + transmitted before the real serial driver starts reconfiguring the serial + controller (which would sometimes result in garbage being transmitted.) + This change does not cause a visible performance loss. + + In addition, this seems to fix a hang observed in certain configurations on + many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver. + + A more complete follow-up patch will disable 8250 autoconfig for ath79 + altogether (the serial controller is detected as a 16550A, which is not + fully compatible with the ath79 serial, and the autoconfig may lead to + undefined behavior on ath79.) + +diff --git a/target/linux/ar71xx/patches-3.18/103-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch b/target/linux/ar71xx/patches-3.18/103-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch +new file mode 100644 +index 0000000..7be14ab +--- /dev/null ++++ b/target/linux/ar71xx/patches-3.18/103-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch +@@ -0,0 +1,54 @@ ++From f1ba020af5076172c9d29006a747ccf40027fedc Mon Sep 17 00:00:00 2001 ++Message-Id: ++From: Matthias Schiffer ++Date: Thu, 24 Mar 2016 15:34:05 +0100 ++Subject: [PATCH] MIPS: ath79: make bootconsole wait for both THRE and TEMT ++ ++This makes the ath79 bootconsole behave the same way as the generic 8250 ++bootconsole. ++ ++Also waiting for TEMT (transmit buffer is empty) instead of just THRE ++(transmit buffer is not full) ensures that all characters have been ++transmitted before the real serial driver starts reconfiguring the serial ++controller (which would sometimes result in garbage being transmitted.) ++This change does not cause a visible performance loss. ++ ++In addition, this seems to fix a hang observed in certain configurations on ++many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver. ++ ++A more complete follow-up patch will disable 8250 autoconfig for ath79 ++altogether (the serial controller is detected as a 16550A, which is not ++fully compatible with the ath79 serial, and the autoconfig may lead to ++undefined behavior on ath79.) ++ ++Cc: ++Signed-off-by: Matthias Schiffer ++--- ++ arch/mips/ath79/early_printk.c | 6 ++++-- ++ 1 file changed, 4 insertions(+), 2 deletions(-) ++ ++diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c ++index b955faf..d1adc59 100644 ++--- a/arch/mips/ath79/early_printk.c +++++ b/arch/mips/ath79/early_printk.c ++@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) ++ } while (1); ++ } ++ +++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) +++ ++ static void prom_putchar_ar71xx(unsigned char ch) ++ { ++ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); ++ ++- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); +++ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); ++ __raw_writel(ch, base + UART_TX * 4); ++- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); +++ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); ++ } ++ ++ static void prom_putchar_ar933x(unsigned char ch) ++-- ++2.7.4 ++ +