]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Aug 2021 10:39:10 +0000 (12:39 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Aug 2021 10:39:10 +0000 (12:39 +0200)
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

queue-4.19/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch [new file with mode: 0644]
queue-4.19/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch b/queue-4.19/mips-malta-do-not-byte-swap-accesses-to-the-cbus-uart.patch
new file mode 100644 (file)
index 0000000..aea6b7e
--- /dev/null
@@ -0,0 +1,68 @@
+From 9a936d6c3d3d6c33ecbadf72dccdb567b5cd3c72 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+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 <macro@orcam.me.uk>
+
+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 <asm/serial.h>'s long and annyoing existence")
+Cc: stable@vger.kernel.org # v2.6.23+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260524430.37803@angie.orcam.me.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.19/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch b/queue-4.19/serial-8250-mask-out-floating-16-32-bit-bus-bits.patch
new file mode 100644 (file)
index 0000000..5f6fdb2
--- /dev/null
@@ -0,0 +1,104 @@
+From e5227c51090e165db4b48dcaa300605bfced7014 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+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 <macro@orcam.me.uk>
+
+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: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>
+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é <f4bug@amsat.org>
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260516220.37803@angie.orcam.me.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -313,7 +313,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 */
+@@ -1301,9 +1305,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;
index cb13d85b918ff4fabe5e67dbd5ce038d83502494..482a0c38ad118ac3a411f8885e2b5094d1561623 100644 (file)
@@ -38,3 +38,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