diff --git a/drivers/serial/Kconfig.pl011 b/drivers/serial/Kconfig.pl011 index 7ad54a433ed..cafdf786039 100644 --- a/drivers/serial/Kconfig.pl011 +++ b/drivers/serial/Kconfig.pl011 @@ -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 diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c index a63ca7df932..5cc9eda5729 100644 --- a/drivers/serial/uart_pl011.c +++ b/drivers/serial/uart_pl011.c @@ -11,6 +11,9 @@ #include #include +#if defined(CONFIG_SHARED_IRQ) +#include +#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