2014-02-11 02:17:47 +08:00
|
|
|
* Maxim MAX310X advanced Universal Asynchronous Receiver-Transmitter (UART)
|
|
|
|
|
|
|
|
Required properties:
|
|
|
|
- compatible: Should be one of the following:
|
|
|
|
- "maxim,max3107" for Maxim MAX3107,
|
|
|
|
- "maxim,max3108" for Maxim MAX3108,
|
|
|
|
- "maxim,max3109" for Maxim MAX3109,
|
|
|
|
- "maxim,max14830" for Maxim MAX14830.
|
|
|
|
- reg: SPI chip select number.
|
|
|
|
- interrupt-parent: The phandle for the interrupt controller that
|
|
|
|
services interrupts for this IC.
|
|
|
|
- interrupts: Specifies the interrupt source of the parent interrupt
|
|
|
|
controller. The format of the interrupt specifier depends on the
|
|
|
|
parent interrupt controller.
|
|
|
|
- clocks: phandle to the IC source clock.
|
2014-02-15 18:59:02 +08:00
|
|
|
- clock-names: Should be "xtal" if clock is an external crystal or
|
|
|
|
"osc" if an external clock source is used.
|
2014-02-11 02:17:47 +08:00
|
|
|
|
|
|
|
Optional properties:
|
|
|
|
- gpio-controller: Marks the device node as a GPIO controller.
|
|
|
|
- #gpio-cells: Should be two. The first cell is the GPIO number and
|
|
|
|
the second cell is used to specify the GPIO polarity:
|
|
|
|
0 = active high,
|
|
|
|
1 = active low.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
max14830: max14830@0 {
|
|
|
|
compatible = "maxim,max14830";
|
|
|
|
reg = <0>;
|
|
|
|
clocks = <&clk20m>;
|
|
|
|
clock-names = "osc";
|
|
|
|
interrupt-parent = <&gpio3>;
|
serial: max310x: Use level-triggered interrupts
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)
[<c0110ba4>] (unwind_backtrace) from [<c010c1d8>] (show_stack+0x10/0x14)
[<c010c1d8>] (show_stack) from [<c07776ac>] (dump_stack+0x84/0x98)
[<c07776ac>] (dump_stack) from [<c016bdfc>] (__report_bad_irq+0x28/0xcc)
[<c016bdfc>] (__report_bad_irq) from [<c016c204>] (note_interrupt+0x28c/0x2dc)
[<c016c204>] (note_interrupt) from [<c01695d4>] (handle_irq_event_percpu+0x4c/0x58)
[<c01695d4>] (handle_irq_event_percpu) from [<c0169624>] (handle_irq_event+0x44/0x68)
[<c0169624>] (handle_irq_event) from [<c016ce80>] (handle_edge_irq+0x12c/0x1dc)
[<c016ce80>] (handle_edge_irq) from [<c016872c>] (generic_handle_irq+0x24/0x34)
[<c016872c>] (generic_handle_irq) from [<c03fc5a0>] (mvebu_gpio_irq_handler+0xe0/0x184)
[<c03fc5a0>] (mvebu_gpio_irq_handler) from [<c016872c>] (generic_handle_irq+0x24/0x34)
[<c016872c>] (generic_handle_irq) from [<c0168c4c>] (__handle_domain_irq+0x5c/0xb4)
[<c0168c4c>] (__handle_domain_irq) from [<c0101520>] (gic_handle_irq+0x4c/0x90)
[<c0101520>] (gic_handle_irq) from [<c010ce4c>] (__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
[<c010ce4c>] (__irq_svc) from [<c0506894>] (orion_spi_setup_transfer+0x118/0x20c)
[<c0506894>] (orion_spi_setup_transfer) from [<c05069ac>] (orion_spi_transfer_one+0x1c/0x26c)
[<c05069ac>] (orion_spi_transfer_one) from [<c05060e4>] (spi_transfer_one_message+0xec/0x500)
[<c05060e4>] (spi_transfer_one_message) from [<c05059a4>] (__spi_pump_messages+0x3f4/0x680)
[<c05059a4>] (__spi_pump_messages) from [<c0505e38>] (__spi_sync+0x1fc/0x200)
[<c0505e38>] (__spi_sync) from [<c0505e60>] (spi_sync+0x24/0x3c)
[<c0505e60>] (spi_sync) from [<c0505f48>] (spi_write_then_read+0xd0/0x17c)
[<c0505f48>] (spi_write_then_read) from [<c0482efc>] (_regmap_raw_read+0xb0/0x250)
[<c0482efc>] (_regmap_raw_read) from [<c04830c0>] (_regmap_bus_read+0x24/0x4c)
[<c04830c0>] (_regmap_bus_read) from [<c04826f4>] (_regmap_read+0x60/0x148)
[<c04826f4>] (_regmap_read) from [<c0482818>] (regmap_read+0x3c/0x5c)
[<c0482818>] (regmap_read) from [<c04592b4>] (max310x_port_irq+0x104/0x2dc)
[<c04592b4>] (max310x_port_irq) from [<c0459a40>] (max310x_ist+0x68/0xc0)
[<c0459a40>] (max310x_ist) from [<c016a610>] (irq_thread_fn+0x1c/0x54)
[<c016a610>] (irq_thread_fn) from [<c016a8d8>] (irq_thread+0x12c/0x1f0)
[<c016a8d8>] (irq_thread) from [<c013e560>] (kthread+0x128/0x158)
[<c013e560>] (kthread) from [<c0107a50>] (ret_from_fork+0x14/0x24)
handlers:
[<c0169694>] irq_default_primary_handler threaded [<c04599d8>] 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 <jan.kundrat@cesnet.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-12-12 23:15:21 +08:00
|
|
|
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
|
2014-02-11 02:17:47 +08:00
|
|
|
gpio-controller;
|
|
|
|
#gpio-cells = <2>;
|
|
|
|
};
|