]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Tue, 1 Aug 2023 01:06:57 +0000 (21:06 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 1 Aug 2023 01:06:57 +0000 (21:06 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/irq-bcm6345-l1-do-not-assume-a-fixed-block-to-cpu-ma.patch [new file with mode: 0644]
queue-4.19/serial-8250_dw-preserve-original-value-of-dlf-regist.patch [new file with mode: 0644]
queue-4.19/serial-8250_dw-split-synopsys-designware-8250-common.patch [new file with mode: 0644]
queue-4.19/series

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 (file)
index 0000000..cba5686
--- /dev/null
@@ -0,0 +1,91 @@
+From 0b5c1ed824c9f4c402894b21832f28e2be39c34f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <jonas.gorski@gmail.com>
+
+[ 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 <jonas.gorski@gmail.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230629072620.62527-1-jonas.gorski@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..f2dada5
--- /dev/null
@@ -0,0 +1,59 @@
+From 2e0c83378411b7ea232f838719cd0a7e39401cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <colorsu1922@gmail.com>
+
+[ 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 <stable@kernel.org>
+Signed-off-by: Ruihong Luo <colorsu1922@gmail.com>
+Link: https://lore.kernel.org/stable/20230713004235.35904-1-colorsu1922%40gmail.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230713004235.35904-1-colorsu1922@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..4494977
--- /dev/null
@@ -0,0 +1,214 @@
+From 755494b48a3ef94c23930cf79fceea45f1ff8c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2019 12:43:16 +0300
+Subject: serial: 8250_dw: split Synopsys DesignWare 8250 common functions
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ 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 <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20190806094322.64987-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 748c5ea8b879 ("serial: 8250_dw: Preserve original value of DLF register")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <linux/bitops.h>
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/serial_8250.h>
++#include <linux/serial_core.h>
++
++#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 <linux/types.h>
++
++#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
+
index 140d78c879c8eefc8f010ed39b572e3bf3260242..47df622f501ce154afbb4553e2c70df3dc6bea47 100644 (file)
@@ -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