From 80313586356c8a06cc969724dea1cc58d2a04d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= Date: Tue, 12 Dec 2017 16:15:21 +0100 Subject: [PATCH] serial: max310x: Use level-triggered interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was getting this trace along with a disabled IRQ when I was generating heavy traffic over four daisy-chained UARTs (MAX14830) on my test kit (Marvell Armada AM388, Solidrun Clearfog Base): irq 51: nobody cared (try booting with the "irqpoll" option) CPU: 0 PID: 68 Comm: irq/51-spi1.2 Not tainted 4.14.4 #7 Hardware name: Marvell Armada 380/385 (Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x84/0x98) [] (dump_stack) from [] (__report_bad_irq+0x28/0xcc) [] (__report_bad_irq) from [] (note_interrupt+0x28c/0x2dc) [] (note_interrupt) from [] (handle_irq_event_percpu+0x4c/0x58) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x44/0x68) [] (handle_irq_event) from [] (handle_edge_irq+0x12c/0x1dc) [] (handle_edge_irq) from [] (generic_handle_irq+0x24/0x34) [] (generic_handle_irq) from [] (mvebu_gpio_irq_handler+0xe0/0x184) [] (mvebu_gpio_irq_handler) from [] (generic_handle_irq+0x24/0x34) [] (generic_handle_irq) from [] (__handle_domain_irq+0x5c/0xb4) [] (__handle_domain_irq) from [] (gic_handle_irq+0x4c/0x90) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) Exception stack(0xeea77c30 to 0xeea77c78) 7c20: 0000000a 018cba80 0000000a f098f680 7c40: 0000020a f098f680 00000008 0000020a 018cba80 00000001 ee9302a0 eea76000 7c60: ef2b2640 eea77c80 c050687c c0506894 80070013 ffffffff [] (__irq_svc) from [] (orion_spi_setup_transfer+0x118/0x20c) [] (orion_spi_setup_transfer) from [] (orion_spi_transfer_one+0x1c/0x26c) [] (orion_spi_transfer_one) from [] (spi_transfer_one_message+0xec/0x500) [] (spi_transfer_one_message) from [] (__spi_pump_messages+0x3f4/0x680) [] (__spi_pump_messages) from [] (__spi_sync+0x1fc/0x200) [] (__spi_sync) from [] (spi_sync+0x24/0x3c) [] (spi_sync) from [] (spi_write_then_read+0xd0/0x17c) [] (spi_write_then_read) from [] (_regmap_raw_read+0xb0/0x250) [] (_regmap_raw_read) from [] (_regmap_bus_read+0x24/0x4c) [] (_regmap_bus_read) from [] (_regmap_read+0x60/0x148) [] (_regmap_read) from [] (regmap_read+0x3c/0x5c) [] (regmap_read) from [] (max310x_port_irq+0x104/0x2dc) [] (max310x_port_irq) from [] (max310x_ist+0x68/0xc0) [] (max310x_ist) from [] (irq_thread_fn+0x1c/0x54) [] (irq_thread_fn) from [] (irq_thread+0x12c/0x1f0) [] (irq_thread) from [] (kthread+0x128/0x158) [] (kthread) from [] (ret_from_fork+0x14/0x24) handlers: [] irq_default_primary_handler threaded [] max310x_ist Disabling IRQ #51 On a multi-UART max310x, each UART has its own interrupt status register which automatically de-asserts the IRQ line upon read. (There are also top-level IRQ indicator registers which are not clear-on-read, but they are not relevant here.) It was quite possible to receive a pending IRQ for, e.g., UART0, enter the threaded IRQ handler, clear the ISR for UART0 which de-asserts the IRQ line, and then race with another event on the same chip, but a different UART channel. That resulted in another edge on the shared-within-the-chip IRQ line which got intercepted by the kernel. That all led to an edge-level interrupt which was not being handled by anybody because our threaded handler hasn't finished yet. As the chip actually uses *level* triggered IRQs, let's convert the example DT bindings to these. Signed-off-by: Jan Kundrát Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/maxim,max310x.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.txt b/Documentation/devicetree/bindings/serial/maxim,max310x.txt index 83a919c241b0..0c58052a18bb 100644 --- a/Documentation/devicetree/bindings/serial/maxim,max310x.txt +++ b/Documentation/devicetree/bindings/serial/maxim,max310x.txt @@ -30,7 +30,7 @@ Example: clocks = <&clk20m>; clock-names = "osc"; interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; gpio-controller; #gpio-cells = <2>; };