From 86b687842ea583551e814da3acee7a6977ef0468 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Aug 2021 12:38:56 +0200 Subject: [PATCH] 4.14-stable patches added patches: mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch serial-8250-mask-out-floating-16-32-bit-bus-bits.patch --- ...-byte-swap-accesses-to-the-cbus-uart.patch | 68 ++++++++++++ ...mask-out-floating-16-32-bit-bus-bits.patch | 104 ++++++++++++++++++ queue-4.14/series | 2 + 3 files changed, 174 insertions(+) create mode 100644 queue-4.14/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch create mode 100644 queue-4.14/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch diff --git a/queue-4.14/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch b/queue-4.14/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch new file mode 100644 index 00000000000..aea6b7e800e --- /dev/null +++ b/queue-4.14/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch @@ -0,0 +1,68 @@ +From 9a936d6c3d3d6c33ecbadf72dccdb567b5cd3c72 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Sat, 26 Jun 2021 06:11:13 +0200 +Subject: MIPS: Malta: Do not byte-swap accesses to the CBUS UART +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maciej W. Rozycki + +commit 9a936d6c3d3d6c33ecbadf72dccdb567b5cd3c72 upstream. + +Correct big-endian accesses to the CBUS UART, a Malta on-board discrete +TI16C550C part wired directly to the system controller's device bus, and +do not use byte swapping with the 32-bit accesses to the device. + +The CBUS is used for devices such as the boot flash memory needed early +on in system bootstrap even before PCI has been initialised. Therefore +it uses the system controller's device bus, which follows the endianness +set with the CPU, which means no byte-swapping is ever required for data +accesses to CBUS, unlike with PCI. + +The CBUS UART uses the UPIO_MEM32 access method, that is the `readl' and +`writel' MMIO accessors, which on the MIPS platform imply byte-swapping +with PCI systems. Consequently the wrong byte lane is accessed with the +big-endian configuration and the UART is not correctly accessed. + +As it happens the UPIO_MEM32BE access method makes use of the `ioread32' +and `iowrite32' MMIO accessors, which still use `readl' and `writel' +respectively, however they byte-swap data passed, effectively cancelling +swapping done with the accessors themselves and making it suitable for +the CBUS UART. + +Make the CBUS UART switch between UPIO_MEM32 and UPIO_MEM32BE then, +based on the endianness selected. With this change in place the device +is correctly recognised with big-endian Malta at boot, along with the +Super I/O devices behind PCI: + +Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled +printk: console [ttyS0] disabled +serial8250.0: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A +printk: console [ttyS0] enabled +printk: bootconsole [uart8250] disabled +serial8250.0: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A +serial8250.0: ttyS2 at MMIO 0x1f000900 (irq = 20, base_baud = 230400) is a 16550A + +Fixes: e7c4782f92fc ("[MIPS] Put an end to 's long and annyoing existence") +Cc: stable@vger.kernel.org # v2.6.23+ +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Maciej W. Rozycki +Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260524430.37803@angie.orcam.me.uk +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/mti-malta/malta-platform.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/mips/mti-malta/malta-platform.c ++++ b/arch/mips/mti-malta/malta-platform.c +@@ -47,7 +47,8 @@ static struct plat_serial8250_port uart8 + .mapbase = 0x1f000900, /* The CBUS UART */ + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, + .uartclk = 3686400, /* Twice the usual clk! */ +- .iotype = UPIO_MEM32, ++ .iotype = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) ? ++ UPIO_MEM32BE : UPIO_MEM32, + .flags = CBUS_UART_FLAGS, + .regshift = 3, + }, diff --git a/queue-4.14/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch b/queue-4.14/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch new file mode 100644 index 00000000000..fdc259e1577 --- /dev/null +++ b/queue-4.14/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch @@ -0,0 +1,104 @@ +From e5227c51090e165db4b48dcaa300605bfced7014 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Sat, 26 Jun 2021 06:11:05 +0200 +Subject: serial: 8250: Mask out floating 16/32-bit bus bits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maciej W. Rozycki + +commit e5227c51090e165db4b48dcaa300605bfced7014 upstream. + +Make sure only actual 8 bits of the IIR register are used in determining +the port type in `autoconfig'. + +The `serial_in' port accessor returns the `unsigned int' type, meaning +that with UPIO_AU, UPIO_MEM16, UPIO_MEM32, and UPIO_MEM32BE access types +more than 8 bits of data are returned, of which the high order bits will +often come from bus lines that are left floating in the data phase. For +example with the MIPS Malta board's CBUS UART, where the registers are +aligned on 8-byte boundaries and which uses 32-bit accesses, data as +follows is returned: + +YAMON> dump -32 0xbf000900 0x40 + +BF000900: 1F000942 1F000942 1F000900 1F000900 ...B...B........ +BF000910: 1F000901 1F000901 1F000900 1F000900 ................ +BF000920: 1F000900 1F000900 1F000960 1F000960 ...........`...` +BF000930: 1F000900 1F000900 1F0009FF 1F0009FF ................ + +YAMON> + +Evidently high-order 24 bits return values previously driven in the +address phase (the 3 highest order address bits used with the command +above are masked out in the simple virtual address mapping used here and +come out at zeros on the external bus), a common scenario with bus lines +left floating, due to bus capacitance. + +Consequently when the value of IIR, mapped at 0x1f000910, is retrieved +in `autoconfig', it comes out at 0x1f0009c1 and when it is right-shifted +by 6 and then assigned to 8-bit `scratch' variable, the value calculated +is 0x27, not one of 0, 1, 2, 3 expected in port type determination. + +Fix the issue then, by assigning the value returned from `serial_in' to +`scratch' first, which masks out 24 high-order bits retrieved, and only +then right-shift the resulting 8-bit data quantity, producing the value +of 3 in this case, as expected. Fix the same issue in `serial_dl_read'. + +The problem first appeared with Linux 2.6.9-rc3 which predates our repo +history, but the origin could be identified with the old MIPS/Linux repo +also at: +as commit e0d2356c0777 ("Merge with Linux 2.6.9-rc3."), where code in +`serial_in' was updated with this case: + ++ case UPIO_MEM32: ++ return readl(up->port.membase + offset); ++ + +which made it produce results outside the unsigned 8-bit range for the +first time, though obviously it is system dependent what actual values +appear in the high order bits retrieved and it may well have been zeros +in the relevant positions with the system the change originally was +intended for. It is at that point that code in `autoconf' should have +been updated accordingly, but clearly it was overlooked. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org # v2.6.12+ +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Maciej W. Rozycki +Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260516220.37803@angie.orcam.me.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_port.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -314,7 +314,11 @@ static const struct serial8250_config ua + /* Uart divisor latch read */ + static int default_serial_dl_read(struct uart_8250_port *up) + { +- return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; ++ /* Assign these in pieces to truncate any bits above 7. */ ++ unsigned char dll = serial_in(up, UART_DLL); ++ unsigned char dlm = serial_in(up, UART_DLM); ++ ++ return dll | dlm << 8; + } + + /* Uart divisor latch write */ +@@ -1302,9 +1306,11 @@ static void autoconfig(struct uart_8250_ + serial_out(up, UART_LCR, 0); + + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); +- scratch = serial_in(up, UART_IIR) >> 6; + +- switch (scratch) { ++ /* Assign this as it is to truncate any bits above 7. */ ++ scratch = serial_in(up, UART_IIR); ++ ++ switch (scratch >> 6) { + case 0: + autoconfig_8250(up); + break; diff --git a/queue-4.14/series b/queue-4.14/series index 77ea07c8294..49fc8c8f98b 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -25,3 +25,5 @@ staging-rtl8723bs-fix-a-resource-leak-in-sd_int_dpc.patch media-rtl28xxu-fix-zero-length-control-request.patch pipe-increase-minimum-default-pipe-size-to-2-pages.patch ext4-fix-potential-htree-corruption-when-growing-large_dir-directories.patch +serial-8250-mask-out-floating-16-32-bit-bus-bits.patch +mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch -- 2.47.3