ascend inclusion category: bugfix Bugzilla: https://gitee.com/openeuler/kernel/issues/I8NC0E CVE: N/A
---------------------------------------
Hisi when designing ascend chip, connect the serial port interrupt signal lines to mbigen equipment, mbigen write GICD_SETSPI_NSR register trigger the SPI interrupt. This can result in serial port drop interrupts.
Signed-off-by: Xu Qiang xuqiang36@huawei.com Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/tty/serial/Kconfig | 15 +++++++++++++++ drivers/tty/serial/amba-pl011.c | 17 +++++++++++++++++ 2 files changed, 32 insertions(+)
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index bdc568a4ab66..a2577253f774 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -73,6 +73,21 @@ config SERIAL_AMBA_PL011_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.)
+config SERIAL_ATTACHED_MBIGEN + bool "Serial port interrupt signal lines connected to the mbigen" + depends on SERIAL_AMBA_PL011=y + depends on ASCEND_FEATURES + default n + help + Say Y here when the interrupt signal line of the serial port is + connected to the mbigne. The mbigen device has the function of + clearing interrupts automatically. However, the interrupt processing + function of the serial port driver may process multiple interrupts + at a time. The mbigen device cannot adapt to this scenario. + As a result, interrupts are lost.Because it maybe discard interrupt. + + If unsure, say N. + config SERIAL_EARLYCON_SEMIHOST bool "Early console using Arm compatible semihosting" depends on ARM64 || ARM || RISCV diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 3dc9b0fcab1c..713e3ef8738f 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1548,6 +1548,18 @@ static void check_apply_cts_event_workaround(struct uart_amba_port *uap) pl011_read(uap, REG_ICR); }
+#ifdef CONFIG_SERIAL_ATTACHED_MBIGEN +static bool pl011_enable_hisi_wkrd; +static int __init pl011_check_hisi_workaround_setup(char *str) +{ + pl011_enable_hisi_wkrd = 1; + return 0; +} +__setup("pl011_hisi_wkrd", pl011_check_hisi_workaround_setup); +#else +#define pl011_enable_hisi_wkrd 0 +#endif + static irqreturn_t pl011_int(int irq, void *dev_id) { struct uart_amba_port *uap = dev_id; @@ -1585,6 +1597,11 @@ static irqreturn_t pl011_int(int irq, void *dev_id) handled = 1; }
+ if (pl011_enable_hisi_wkrd) { + pl011_write(0, uap, REG_IMSC); + pl011_write(uap->im, uap, REG_IMSC); + } + spin_unlock_irqrestore(&uap->port.lock, flags);
return IRQ_RETVAL(handled);