drivers: uart_pl011: Enable shared interrupts support
The PrimeCell UART (PL011) IP can use one single combined/shared interrupt line instead than different IRQ lines for TX/RX/Err/... This is the most common configuration supported in the Linux world but not currently supported in Zephyr. QEMU emulates a PL011 UART with a single interrupt line as well. To support this configuration we have to hookup the PL011 driver with a shared IRQ driver and add two new configuration options when the shared IRQ line is used. Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
parent
e2905c09cb
commit
b9fc192779
|
@ -20,4 +20,25 @@ config UART_PL011_PORT1
|
|||
help
|
||||
Build the driver to utilize UART controller Port 1.
|
||||
|
||||
config UART_PL011_SHARED_IRQ
|
||||
bool
|
||||
|
||||
config UART_PL011_PORT0_SHARED_IRQ
|
||||
bool "Shared IRQ for UART 0"
|
||||
depends on SHARED_IRQ_0
|
||||
depends on UART_PL011_PORT0
|
||||
select UART_PL011_SHARED_IRQ
|
||||
help
|
||||
When interrupts fire, the shared IRQ driver is notified. Then the shared IRQ
|
||||
driver dispatches the interrupt to the UART driver.
|
||||
|
||||
config UART_PL011_PORT1_SHARED_IRQ
|
||||
bool "Shared IRQ for UART 1"
|
||||
depends on SHARED_IRQ_1
|
||||
depends on UART_PL011_PORT1
|
||||
select UART_PL011_SHARED_IRQ
|
||||
help
|
||||
When interrupts fire, the shared IRQ driver is notified. Then the shared IRQ
|
||||
driver dispatches the interrupt to the UART driver.
|
||||
|
||||
endif # UART_PL011
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include <soc.h>
|
||||
#include <drivers/uart.h>
|
||||
|
||||
#if defined(CONFIG_SHARED_IRQ)
|
||||
#include <shared_irq.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* UART PL011 register map structure
|
||||
|
@ -43,6 +46,9 @@ struct pl011_data {
|
|||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||
uart_irq_callback_user_data_t irq_cb;
|
||||
void *irq_cb_data;
|
||||
#if defined(CONFIG_UART_PL011_SHARED_IRQ)
|
||||
char *shared_irq_dev_name;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -423,6 +429,9 @@ static struct uart_device_config pl011_cfg_port_0 = {
|
|||
|
||||
static struct pl011_data pl011_data_port_0 = {
|
||||
.baud_rate = DT_PL011_PORT0_BAUD_RATE,
|
||||
#if defined(CONFIG_UART_PL011_SHARED_IRQ)
|
||||
.shared_irq_dev_name = DT_INST_0_SHARED_IRQ_LABEL,
|
||||
#endif
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(pl011_port_0,
|
||||
|
@ -436,6 +445,14 @@ DEVICE_AND_API_INIT(pl011_port_0,
|
|||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||
static void pl011_irq_config_func_0(struct device *dev)
|
||||
{
|
||||
#if defined(CONFIG_UART_PL011_PORT0_SHARED_IRQ)
|
||||
struct device *shared_irq_dev;
|
||||
|
||||
shared_irq_dev = device_get_binding(DEV_DATA(dev)->shared_irq_dev_name);
|
||||
__ASSERT(shared_irq_dev != NULL, "Failed to get shared irq");
|
||||
shared_irq_isr_register(shared_irq_dev, (isr_t)pl011_isr, dev);
|
||||
shared_irq_enable(shared_irq_dev, dev);
|
||||
#else
|
||||
IRQ_CONNECT(DT_PL011_PORT0_IRQ_TX,
|
||||
DT_PL011_PORT0_IRQ_PRI,
|
||||
pl011_isr,
|
||||
|
@ -456,6 +473,7 @@ static void pl011_irq_config_func_0(struct device *dev)
|
|||
DEVICE_GET(pl011_port_0),
|
||||
0);
|
||||
irq_enable(DT_PL011_PORT0_IRQ_RXTIM);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -477,6 +495,9 @@ static struct uart_device_config pl011_cfg_port_1 = {
|
|||
|
||||
static struct pl011_data pl011_data_port_1 = {
|
||||
.baud_rate = DT_PL011_PORT1_BAUD_RATE,
|
||||
#if defined(CONFIG_UART_PL011_SHARED_IRQ)
|
||||
.shared_irq_dev_name = DT_INST_1_SHARED_IRQ_LABEL,
|
||||
#endif
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(pl011_port_1,
|
||||
|
@ -490,6 +511,14 @@ DEVICE_AND_API_INIT(pl011_port_1,
|
|||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||
static void pl011_irq_config_func_1(struct device *dev)
|
||||
{
|
||||
#if defined(CONFIG_UART_PL011_PORT1_SHARED_IRQ)
|
||||
struct device *shared_irq_dev;
|
||||
|
||||
shared_irq_dev = device_get_binding(DEV_DATA(dev)->shared_irq_dev_name);
|
||||
__ASSERT(shared_irq_dev != NULL, "Failed to get shared irq");
|
||||
shared_irq_isr_register(shared_irq_dev, (isr_t)pl011_isr, dev);
|
||||
shared_irq_enable(shared_irq_dev, dev);
|
||||
#else
|
||||
IRQ_CONNECT(DT_PL011_PORT1_IRQ_TX,
|
||||
DT_PL011_PORT1_IRQ_PRI,
|
||||
pl011_isr,
|
||||
|
@ -510,6 +539,7 @@ static void pl011_irq_config_func_1(struct device *dev)
|
|||
DEVICE_GET(pl011_port_1),
|
||||
0);
|
||||
irq_enable(DT_PL011_PORT1_IRQ_RXTIM);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue