From: Sasha Levin Date: Tue, 1 Aug 2023 01:06:57 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v5.15.124~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5db2827d40d7fe30a0bc7790a7742519a8b9dafb;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/irq-bcm6345-l1-do-not-assume-a-fixed-block-to-cpu-ma.patch b/queue-4.19/irq-bcm6345-l1-do-not-assume-a-fixed-block-to-cpu-ma.patch new file mode 100644 index 00000000000..cba56865e6b --- /dev/null +++ b/queue-4.19/irq-bcm6345-l1-do-not-assume-a-fixed-block-to-cpu-ma.patch @@ -0,0 +1,91 @@ +From 0b5c1ed824c9f4c402894b21832f28e2be39c34f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jun 2023 09:26:20 +0200 +Subject: irq-bcm6345-l1: Do not assume a fixed block to cpu mapping +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 55ad24857341c36616ecc1d9580af5626c226cf1 ] + +The irq to block mapping is fixed, and interrupts from the first block +will always be routed to the first parent IRQ. But the parent interrupts +themselves can be routed to any available CPU. + +This is used by the bootloader to map the first parent interrupt to the +boot CPU, regardless wether the boot CPU is the first one or the second +one. + +When booting from the second CPU, the assumption that the first block's +IRQ is mapped to the first CPU breaks, and the system hangs because +interrupts do not get routed correctly. + +Fix this by passing the appropriate bcm6434_l1_cpu to the interrupt +handler instead of the chip itself, so the handler always has the right +block. + +Fixes: c7c42ec2baa1 ("irqchips/bmips: Add bcm6345-l1 interrupt controller") +Signed-off-by: Jonas Gorski +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Florian Fainelli +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20230629072620.62527-1-jonas.gorski@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm6345-l1.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c +index 31ea6332ecb83..60dc64b4ac6d2 100644 +--- a/drivers/irqchip/irq-bcm6345-l1.c ++++ b/drivers/irqchip/irq-bcm6345-l1.c +@@ -85,6 +85,7 @@ struct bcm6345_l1_chip { + }; + + struct bcm6345_l1_cpu { ++ struct bcm6345_l1_chip *intc; + void __iomem *map_base; + unsigned int parent_irq; + u32 enable_cache[]; +@@ -118,17 +119,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc, + + static void bcm6345_l1_irq_handle(struct irq_desc *desc) + { +- struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc); +- struct bcm6345_l1_cpu *cpu; ++ struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc); ++ struct bcm6345_l1_chip *intc = cpu->intc; + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int idx; + +-#ifdef CONFIG_SMP +- cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; +-#else +- cpu = intc->cpus[0]; +-#endif +- + chained_irq_enter(chip, desc); + + for (idx = 0; idx < intc->n_words; idx++) { +@@ -260,6 +255,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, + if (!cpu) + return -ENOMEM; + ++ cpu->intc = intc; + cpu->map_base = ioremap(res.start, sz); + if (!cpu->map_base) + return -ENOMEM; +@@ -275,7 +271,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, + return -EINVAL; + } + irq_set_chained_handler_and_data(cpu->parent_irq, +- bcm6345_l1_irq_handle, intc); ++ bcm6345_l1_irq_handle, cpu); + + return 0; + } +-- +2.40.1 + diff --git a/queue-4.19/serial-8250_dw-preserve-original-value-of-dlf-regist.patch b/queue-4.19/serial-8250_dw-preserve-original-value-of-dlf-regist.patch new file mode 100644 index 00000000000..f2dada54316 --- /dev/null +++ b/queue-4.19/serial-8250_dw-preserve-original-value-of-dlf-regist.patch @@ -0,0 +1,59 @@ +From 2e0c83378411b7ea232f838719cd0a7e39401cd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Jul 2023 08:42:36 +0800 +Subject: serial: 8250_dw: Preserve original value of DLF register +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ruihong Luo + +[ Upstream commit 748c5ea8b8796ae8ee80b8d3a3d940570b588d59 ] + +Preserve the original value of the Divisor Latch Fraction (DLF) register. +When the DLF register is modified without preservation, it can disrupt +the baudrate settings established by firmware or bootloader, leading to +data corruption and the generation of unreadable or distorted characters. + +Fixes: 701c5e73b296 ("serial: 8250_dw: add fractional divisor support") +Cc: stable +Signed-off-by: Ruihong Luo +Link: https://lore.kernel.org/stable/20230713004235.35904-1-colorsu1922%40gmail.com +Reviewed-by: Ilpo Järvinen +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20230713004235.35904-1-colorsu1922@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/8250/8250_dwlib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c +index 6d6a78eead3ef..1cf229cca5928 100644 +--- a/drivers/tty/serial/8250/8250_dwlib.c ++++ b/drivers/tty/serial/8250/8250_dwlib.c +@@ -80,7 +80,7 @@ static void dw8250_set_divisor(struct uart_port *p, unsigned int baud, + void dw8250_setup_port(struct uart_port *p) + { + struct uart_8250_port *up = up_to_u8250p(p); +- u32 reg; ++ u32 reg, old_dlf; + + /* + * If the Component Version Register returns zero, we know that +@@ -93,9 +93,11 @@ void dw8250_setup_port(struct uart_port *p) + dev_dbg(p->dev, "Designware UART version %c.%c%c\n", + (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); + ++ /* Preserve value written by firmware or bootloader */ ++ old_dlf = dw8250_readl_ext(p, DW_UART_DLF); + dw8250_writel_ext(p, DW_UART_DLF, ~0U); + reg = dw8250_readl_ext(p, DW_UART_DLF); +- dw8250_writel_ext(p, DW_UART_DLF, 0); ++ dw8250_writel_ext(p, DW_UART_DLF, old_dlf); + + if (reg) { + struct dw8250_port_data *d = p->private_data; +-- +2.40.1 + diff --git a/queue-4.19/serial-8250_dw-split-synopsys-designware-8250-common.patch b/queue-4.19/serial-8250_dw-split-synopsys-designware-8250-common.patch new file mode 100644 index 00000000000..44949774f47 --- /dev/null +++ b/queue-4.19/serial-8250_dw-split-synopsys-designware-8250-common.patch @@ -0,0 +1,214 @@ +From 755494b48a3ef94c23930cf79fceea45f1ff8c81 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Aug 2019 12:43:16 +0300 +Subject: serial: 8250_dw: split Synopsys DesignWare 8250 common functions + +From: Andy Shevchenko + +[ Upstream commit 136e0ab99b22378e3ff7d54f799a3a329316e869 ] + +We would like to use same functions in the couple of drivers for +Synopsys DesignWare 8250 UART. Split them from 8250_dw into new brand +library module which users will select explicitly. + +Signed-off-by: Andy Shevchenko +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20190806094322.64987-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 748c5ea8b879 ("serial: 8250_dw: Preserve original value of DLF register") +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/8250/8250_dwlib.c | 126 +++++++++++++++++++++++++++ + drivers/tty/serial/8250/8250_dwlib.h | 19 ++++ + drivers/tty/serial/8250/Kconfig | 3 + + drivers/tty/serial/8250/Makefile | 1 + + 4 files changed, 149 insertions(+) + create mode 100644 drivers/tty/serial/8250/8250_dwlib.c + create mode 100644 drivers/tty/serial/8250/8250_dwlib.h + +diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c +new file mode 100644 +index 0000000000000..6d6a78eead3ef +--- /dev/null ++++ b/drivers/tty/serial/8250/8250_dwlib.c +@@ -0,0 +1,126 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* Synopsys DesignWare 8250 library. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "8250_dwlib.h" ++ ++/* Offsets for the DesignWare specific registers */ ++#define DW_UART_DLF 0xc0 /* Divisor Latch Fraction Register */ ++#define DW_UART_CPR 0xf4 /* Component Parameter Register */ ++#define DW_UART_UCV 0xf8 /* UART Component Version */ ++ ++/* Component Parameter Register bits */ ++#define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) ++#define DW_UART_CPR_AFCE_MODE (1 << 4) ++#define DW_UART_CPR_THRE_MODE (1 << 5) ++#define DW_UART_CPR_SIR_MODE (1 << 6) ++#define DW_UART_CPR_SIR_LP_MODE (1 << 7) ++#define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) ++#define DW_UART_CPR_FIFO_ACCESS (1 << 9) ++#define DW_UART_CPR_FIFO_STAT (1 << 10) ++#define DW_UART_CPR_SHADOW (1 << 11) ++#define DW_UART_CPR_ENCODED_PARMS (1 << 12) ++#define DW_UART_CPR_DMA_EXTRA (1 << 13) ++#define DW_UART_CPR_FIFO_MODE (0xff << 16) ++ ++/* Helper for FIFO size calculation */ ++#define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) ++ ++static inline u32 dw8250_readl_ext(struct uart_port *p, int offset) ++{ ++ if (p->iotype == UPIO_MEM32BE) ++ return ioread32be(p->membase + offset); ++ return readl(p->membase + offset); ++} ++ ++static inline void dw8250_writel_ext(struct uart_port *p, int offset, u32 reg) ++{ ++ if (p->iotype == UPIO_MEM32BE) ++ iowrite32be(reg, p->membase + offset); ++ else ++ writel(reg, p->membase + offset); ++} ++ ++/* ++ * divisor = div(I) + div(F) ++ * "I" means integer, "F" means fractional ++ * quot = div(I) = clk / (16 * baud) ++ * frac = div(F) * 2^dlf_size ++ * ++ * let rem = clk % (16 * baud) ++ * we have: div(F) * (16 * baud) = rem ++ * so frac = 2^dlf_size * rem / (16 * baud) = (rem << dlf_size) / (16 * baud) ++ */ ++static unsigned int dw8250_get_divisor(struct uart_port *p, unsigned int baud, ++ unsigned int *frac) ++{ ++ unsigned int quot, rem, base_baud = baud * 16; ++ struct dw8250_port_data *d = p->private_data; ++ ++ quot = p->uartclk / base_baud; ++ rem = p->uartclk % base_baud; ++ *frac = DIV_ROUND_CLOSEST(rem << d->dlf_size, base_baud); ++ ++ return quot; ++} ++ ++static void dw8250_set_divisor(struct uart_port *p, unsigned int baud, ++ unsigned int quot, unsigned int quot_frac) ++{ ++ dw8250_writel_ext(p, DW_UART_DLF, quot_frac); ++ serial8250_do_set_divisor(p, baud, quot, quot_frac); ++} ++ ++void dw8250_setup_port(struct uart_port *p) ++{ ++ struct uart_8250_port *up = up_to_u8250p(p); ++ u32 reg; ++ ++ /* ++ * If the Component Version Register returns zero, we know that ++ * ADDITIONAL_FEATURES are not enabled. No need to go any further. ++ */ ++ reg = dw8250_readl_ext(p, DW_UART_UCV); ++ if (!reg) ++ return; ++ ++ dev_dbg(p->dev, "Designware UART version %c.%c%c\n", ++ (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); ++ ++ dw8250_writel_ext(p, DW_UART_DLF, ~0U); ++ reg = dw8250_readl_ext(p, DW_UART_DLF); ++ dw8250_writel_ext(p, DW_UART_DLF, 0); ++ ++ if (reg) { ++ struct dw8250_port_data *d = p->private_data; ++ ++ d->dlf_size = fls(reg); ++ p->get_divisor = dw8250_get_divisor; ++ p->set_divisor = dw8250_set_divisor; ++ } ++ ++ reg = dw8250_readl_ext(p, DW_UART_CPR); ++ if (!reg) ++ return; ++ ++ /* Select the type based on FIFO */ ++ if (reg & DW_UART_CPR_FIFO_MODE) { ++ p->type = PORT_16550A; ++ p->flags |= UPF_FIXED_TYPE; ++ p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); ++ up->capabilities = UART_CAP_FIFO; ++ } ++ ++ if (reg & DW_UART_CPR_AFCE_MODE) ++ up->capabilities |= UART_CAP_AFE; ++ ++ if (reg & DW_UART_CPR_SIR_MODE) ++ up->capabilities |= UART_CAP_IRDA; ++} ++EXPORT_SYMBOL_GPL(dw8250_setup_port); +diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h +new file mode 100644 +index 0000000000000..87a4db2a8aba6 +--- /dev/null ++++ b/drivers/tty/serial/8250/8250_dwlib.h +@@ -0,0 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* Synopsys DesignWare 8250 library header file. */ ++ ++#include ++ ++#include "8250.h" ++ ++struct dw8250_port_data { ++ /* Port properties */ ++ int line; ++ ++ /* DMA operations */ ++ struct uart_8250_dma dma; ++ ++ /* Hardware configuration */ ++ u8 dlf_size; ++}; ++ ++void dw8250_setup_port(struct uart_port *p); +diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig +index a9ddd76d41701..733ac320938c1 100644 +--- a/drivers/tty/serial/8250/Kconfig ++++ b/drivers/tty/serial/8250/Kconfig +@@ -312,6 +312,9 @@ config SERIAL_8250_RSA + + If you don't have such card, or if unsure, say N. + ++config SERIAL_8250_DWLIB ++ bool ++ + config SERIAL_8250_ACORN + tristate "Acorn expansion card serial port support" + depends on ARCH_ACORN && SERIAL_8250 +diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile +index 18751bc63a848..9b451d81588b2 100644 +--- a/drivers/tty/serial/8250/Makefile ++++ b/drivers/tty/serial/8250/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o + 8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o + 8250_base-y := 8250_port.o + 8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o ++8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o + 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o + obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o + obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +-- +2.40.1 + diff --git a/queue-4.19/series b/queue-4.19/series index 140d78c879c..47df622f501 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -272,3 +272,6 @@ staging-ks7010-potential-buffer-overflow-in-ks_wlan_set_encode_ext.patch hwmon-nct7802-fix-for-temp6-peci1-processed-even-if-peci1-disabled.patch btrfs-check-for-commit-error-at-btrfs_attach_transaction_barrier.patch tpm_tis-explicitly-check-for-error-code.patch +irq-bcm6345-l1-do-not-assume-a-fixed-block-to-cpu-ma.patch +serial-8250_dw-split-synopsys-designware-8250-common.patch +serial-8250_dw-preserve-original-value-of-dlf-regist.patch