Date
1 - 6 of 6
[RFC v2] uart: add ISR callback mechanism for UART drivers
Daniel Leung <daniel.leung@...>
The peripherals utilizing UART were required to register their own
ISR rountines. This means that all those peripherals drivers need to know which IRQ line is attached to a UART controller, and all the other config values required to register a ISR. This causes scalibility issue as every board and peripherals have to define those values. Another reason for this patch is to support virtual serial ports. Virtual serial ports do not have physical interrupt lines to attach, and thus would not work. This patch adds a simple callback mechanism, which calls a function when UART interrupts are triggered. The low level plumbing still needs to be done by the peripheral drivers, as these drivers may need to access low level capability of UART to function correctly. This simply moves the interrupt setup into the UART drivers themselves. By doing this, the peripheral drivers do not need to know all the config values to properly setup the interrupts and attaching the ISR. One drawback is that this adds to the interrupt latency. Note that this patch breaks backward compatibility in terms of setting up interrupt for UART controller. How to use UART is still the same. This also addresses the following issues: () UART driver for Atmel SAM3 currently does not support interrupts. So remove the code from vector table. This will be updated when there is interrupt support for the driver. () Corrected some config options for Stellaris UART driver. This was tested with samples/shell on Arduino 101, and on QEMU (Cortex-M3 and x86). [v2: missed the NBLE UART for v1. Fixed in v2.] Origin: Origin Change-Id: Ib4593d8ccd711f4e97d388c7293205d213be1aec Signed-off-by: Daniel Leung <daniel.leung(a)intel.com> --- arch/arc/soc/quark_se_ss/Kconfig | 4 - arch/arm/soc/atmel_sam3/Kconfig | 4 - arch/arm/soc/atmel_sam3/irq_vector_table.c | 16 --- arch/arm/soc/fsl_frdm_k64f/Kconfig | 8 -- arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c | 51 +++++++--- arch/arm/soc/ti_lm3s6965/Kconfig | 20 ++-- arch/arm/soc/ti_lm3s6965/irq_vector_table.c | 39 ++++--- arch/x86/soc/atom/Kconfig | 12 --- arch/x86/soc/ia32/Kconfig | 12 --- arch/x86/soc/quark_d2000/Kconfig | 12 --- arch/x86/soc/quark_se/Kconfig | 8 -- arch/x86/soc/quark_x1000/Kconfig | 8 -- boards/arduino_101/Kconfig | 8 -- drivers/bluetooth/Kconfig | 14 --- drivers/bluetooth/h4.c | 7 +- drivers/bluetooth/h5.c | 8 +- drivers/console/Kconfig | 28 ------ drivers/console/uart_console.c | 7 +- drivers/console/uart_pipe.c | 8 +- drivers/nble/Kconfig | 14 --- drivers/nble/uart.c | 8 +- drivers/serial/uart_k20.c | 140 ++++++++++++++++++++++++++ drivers/serial/uart_k20.h | 26 +++++ drivers/serial/uart_ns16550.c | 79 +++++++++++++++ drivers/serial/uart_stellaris.c | 103 +++++++++++++++++++ drivers/serial/uart_stellaris.h | 26 +++++ include/drivers/console/uart_console.h | 2 - include/drivers/console/uart_pipe.h | 9 -- include/uart.h | 41 ++++++++ 29 files changed, 490 insertions(+), 232 deletions(-) create mode 100644 drivers/serial/uart_k20.h create mode 100644 drivers/serial/uart_stellaris.h diff --git a/arch/arc/soc/quark_se_ss/Kconfig b/arch/arc/soc/quark_se_ss/Kconfig index d6d1b90..827cafa 100644 --- a/arch/arc/soc/quark_se_ss/Kconfig +++ b/arch/arc/soc/quark_se_ss/Kconfig @@ -161,10 +161,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_1" -config UART_CONSOLE_IRQ - default 42 -config UART_CONSOLE_IRQ_PRI - default 1 endif diff --git a/arch/arm/soc/atmel_sam3/Kconfig b/arch/arm/soc/atmel_sam3/Kconfig index a7cf5cc..9b880e9 100644 --- a/arch/arm/soc/atmel_sam3/Kconfig +++ b/arch/arm/soc/atmel_sam3/Kconfig @@ -148,10 +148,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 8 -config UART_CONSOLE_IRQ_PRI - default 3 endif # UART_CONSOLE diff --git a/arch/arm/soc/atmel_sam3/irq_vector_table.c b/arch/arm/soc/atmel_sam3/irq_vector_table.c index 24b1dcd..5f53773 100644 --- a/arch/arm/soc/atmel_sam3/irq_vector_table.c +++ b/arch/arm/soc/atmel_sam3/irq_vector_table.c @@ -32,11 +32,6 @@ #include <toolchain.h> #include <sections.h> -#if defined(CONFIG_CONSOLE_HANDLER) -#include <soc.h> -#include <console/uart_console.h> -#endif /* CONFIG_CONSOLE_HANDLER */ - extern void _isr_wrapper(void); typedef void (*vth)(void); /* Vector Table Handler */ @@ -50,20 +45,9 @@ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { extern void _irq_spurious(void); -#if defined(CONFIG_CONSOLE_HANDLER) -static void _uart_console_isr(void) -{ - uart_console_isr(NULL); - _IntExit(); -} -#endif /* CONFIG_CONSOLE_HANDLER */ - /* placeholders: fill with real ISRs */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { [0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious, -#if defined(CONFIG_CONSOLE_HANDLER) - [CONFIG_UART_CONSOLE_IRQ] = _uart_console_isr, -#endif }; #endif /* CONFIG_SW_ISR_TABLE */ diff --git a/arch/arm/soc/fsl_frdm_k64f/Kconfig b/arch/arm/soc/fsl_frdm_k64f/Kconfig index 7ffec5e..7a1fa30 100644 --- a/arch/arm/soc/fsl_frdm_k64f/Kconfig +++ b/arch/arm/soc/fsl_frdm_k64f/Kconfig @@ -141,10 +141,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 31 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -152,10 +148,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 33 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif diff --git a/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c b/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c index d36abca..8c02ec4 100644 --- a/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c +++ b/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c @@ -31,15 +31,8 @@ #include <toolchain.h> #include <sections.h> -#if defined(CONFIG_CONSOLE_HANDLER) #include <soc.h> -#include <console/uart_console.h> -#endif /* CONFIG_CONSOLE_HANDLER */ - -#if defined(CONFIG_BLUETOOTH_UART) -#include <soc.h> -#include <bluetooth/uart.h> -#endif /* CONFIG_BLUETOOTH_UART */ +#include <serial/uart_k20.h> extern void _isr_wrapper(void); typedef void (*vth)(void); /* Vector Table Handler */ @@ -54,10 +47,34 @@ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { extern void _irq_spurious(void); -#if defined(CONFIG_CONSOLE_HANDLER) -static void _uart_console_isr(void) +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +static void _uart_k20_0_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_0)); + _IntExit(); +} + +static void _uart_k20_1_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_1)); + _IntExit(); +} + +static void _uart_k20_2_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_2)); + _IntExit(); +} + +static void _uart_k20_3_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_3)); + _IntExit(); +} + +static void _uart_k20_4_isr(void) { - uart_console_isr(NULL); + uart_k20_isr(DEVICE_GET(uart_k20_4)); _IntExit(); } #endif /* CONFIG_CONSOLE_HANDLER */ @@ -73,11 +90,13 @@ static void _bt_uart_isr(void) /* placeholders: fill with real ISRs */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { [0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious, -#if defined(CONFIG_CONSOLE_HANDLER) - [CONFIG_UART_CONSOLE_IRQ] = _uart_console_isr, -#endif -#if defined(CONFIG_BLUETOOTH_UART) - [CONFIG_BLUETOOTH_UART_IRQ] = _bt_uart_isr, + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + [CONFIG_UART_K20_PORT_0_IRQ] = _uart_k20_0_isr, + [CONFIG_UART_K20_PORT_1_IRQ] = _uart_k20_1_isr, + [CONFIG_UART_K20_PORT_2_IRQ] = _uart_k20_2_isr, + [CONFIG_UART_K20_PORT_3_IRQ] = _uart_k20_3_isr, + [CONFIG_UART_K20_PORT_4_IRQ] = _uart_k20_4_isr, #endif }; diff --git a/arch/arm/soc/ti_lm3s6965/Kconfig b/arch/arm/soc/ti_lm3s6965/Kconfig index a9b32a2..fa643ba 100644 --- a/arch/arm/soc/ti_lm3s6965/Kconfig +++ b/arch/arm/soc/ti_lm3s6965/Kconfig @@ -66,7 +66,9 @@ if UART_STELLARIS_PORT_0 config UART_STELLARIS_PORT_0_BASE_ADDR default 0x4000C000 config UART_STELLARIS_PORT_0_IRQ - default 6 + default 5 +config UART_STELLARIS_PORT_0_IRQ_PRI + default 3 config UART_STELLARIS_PORT_0_BAUD_RATE default 115200 config UART_STELLARIS_PORT_0_CLK_FREQ @@ -81,6 +83,8 @@ config UART_STELLARIS_PORT_1_BASE_ADDR default 0x4000D000 config UART_STELLARIS_PORT_1_IRQ default 6 +config UART_STELLARIS_PORT_1_IRQ_PRI + default 3 config UART_STELLARIS_PORT_1_BAUD_RATE default 115200 config UART_STELLARIS_PORT_1_CLK_FREQ @@ -94,6 +98,8 @@ config UART_STELLARIS_PORT_2_BASE_ADDR default 0x4000E000 config UART_STELLARIS_PORT_2_IRQ default 33 +config UART_STELLARIS_PORT_2_IRQ_PRI + default 3 config UART_STELLARIS_PORT_2_BAUD_RATE default 115200 config UART_STELLARIS_PORT_2_CLK_FREQ @@ -106,10 +112,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 5 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -117,10 +119,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 6 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -128,10 +126,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_2" -config UART_PIPE_IRQ - default 33 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/arm/soc/ti_lm3s6965/irq_vector_table.c b/arch/arm/soc/ti_lm3s6965/irq_vector_table.c index d36abca..4d931f6 100644 --- a/arch/arm/soc/ti_lm3s6965/irq_vector_table.c +++ b/arch/arm/soc/ti_lm3s6965/irq_vector_table.c @@ -31,15 +31,8 @@ #include <toolchain.h> #include <sections.h> -#if defined(CONFIG_CONSOLE_HANDLER) #include <soc.h> -#include <console/uart_console.h> -#endif /* CONFIG_CONSOLE_HANDLER */ - -#if defined(CONFIG_BLUETOOTH_UART) -#include <soc.h> -#include <bluetooth/uart.h> -#endif /* CONFIG_BLUETOOTH_UART */ +#include <serial/uart_stellaris.h> extern void _isr_wrapper(void); typedef void (*vth)(void); /* Vector Table Handler */ @@ -54,30 +47,34 @@ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { extern void _irq_spurious(void); -#if defined(CONFIG_CONSOLE_HANDLER) -static void _uart_console_isr(void) +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +static void _uart_stellaris_port_0_isr(void) +{ + uart_stellaris_isr(DEVICE_GET(uart_stellaris0)); + _IntExit(); +} + +static void _uart_stellaris_port_1_isr(void) { - uart_console_isr(NULL); + uart_stellaris_isr(DEVICE_GET(uart_stellaris1)); _IntExit(); } -#endif /* CONFIG_CONSOLE_HANDLER */ -#if defined(CONFIG_BLUETOOTH_UART) -static void _bt_uart_isr(void) +static void _uart_stellaris_port_2_isr(void) { - bt_uart_isr(NULL); + uart_stellaris_isr(DEVICE_GET(uart_stellaris2)); _IntExit(); } -#endif /* CONFIG_BLUETOOTH_UART */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ /* placeholders: fill with real ISRs */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { [0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious, -#if defined(CONFIG_CONSOLE_HANDLER) - [CONFIG_UART_CONSOLE_IRQ] = _uart_console_isr, -#endif -#if defined(CONFIG_BLUETOOTH_UART) - [CONFIG_BLUETOOTH_UART_IRQ] = _bt_uart_isr, + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + [UART_STELLARIS_PORT_0_IRQ] = _uart_stellaris_port_0_isr, + [UART_STELLARIS_PORT_1_IRQ] = _uart_stellaris_port_1_isr, + [UART_STELLARIS_PORT_2_IRQ] = _uart_stellaris_port_2_isr, #endif }; diff --git a/arch/x86/soc/atom/Kconfig b/arch/x86/soc/atom/Kconfig index c9b7f5f..f085985 100644 --- a/arch/x86/soc/atom/Kconfig +++ b/arch/x86/soc/atom/Kconfig @@ -105,10 +105,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 4 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -116,10 +112,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 3 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -127,10 +119,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_1" -config UART_PIPE_IRQ - default 3 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/ia32/Kconfig b/arch/x86/soc/ia32/Kconfig index f9916ba..6025697 100644 --- a/arch/x86/soc/ia32/Kconfig +++ b/arch/x86/soc/ia32/Kconfig @@ -105,10 +105,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 4 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -116,10 +112,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 3 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -127,10 +119,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_1" -config UART_PIPE_IRQ - default 3 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/quark_d2000/Kconfig b/arch/x86/soc/quark_d2000/Kconfig index da8a1be..5d11114 100644 --- a/arch/x86/soc/quark_d2000/Kconfig +++ b/arch/x86/soc/quark_d2000/Kconfig @@ -127,10 +127,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 8 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -138,10 +134,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 6 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -149,10 +141,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_1" -config UART_PIPE_IRQ - default 6 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/quark_se/Kconfig b/arch/x86/soc/quark_se/Kconfig index a17110d..8922f2d 100644 --- a/arch/x86/soc/quark_se/Kconfig +++ b/arch/x86/soc/quark_se/Kconfig @@ -376,10 +376,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_1" -config UART_CONSOLE_IRQ - default 6 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -387,10 +383,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 38 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/quark_x1000/Kconfig b/arch/x86/soc/quark_x1000/Kconfig index ed7514d..3357d2c 100644 --- a/arch/x86/soc/quark_x1000/Kconfig +++ b/arch/x86/soc/quark_x1000/Kconfig @@ -343,10 +343,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_1" -config UART_CONSOLE_IRQ - default 17 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -354,10 +350,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 17 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif diff --git a/boards/arduino_101/Kconfig b/boards/arduino_101/Kconfig index 8d047dd..9bacabf 100644 --- a/boards/arduino_101/Kconfig +++ b/boards/arduino_101/Kconfig @@ -11,10 +11,6 @@ config GPIO config NBLE_UART_ON_DEV_NAME default UART_NS16550_PORT_0_NAME -config NBLE_UART_IRQ - default UART_NS16550_PORT_0_IRQ -config NBLE_UART_IRQ_PRI - default UART_NS16550_PORT_0_IRQ_PRI endif @@ -22,10 +18,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default UART_NS16550_PORT_1_NAME -config UART_PIPE_IRQ - default UART_NS16550_PORT_1_IRQ -config UART_PIPE_IRQ_PRI - default UART_NS16550_PORT_1_IRQ_PRI endif diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index c48e3f5..879dd47 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -71,20 +71,6 @@ config BLUETOOTH_UART_ON_DEV_NAME This option specifies the name of UART device to be used for Bluetooth. -config BLUETOOTH_UART_IRQ - int "IRQ of UART Device for Bluetooth" - depends on BLUETOOTH_UART - help - This option specifies the IRQ of UART device to be used - for Bluetooth. - -config BLUETOOTH_UART_IRQ_PRI - int "IRQ Priority of UART Device for Bluetooth" - depends on BLUETOOTH_UART - help - This option specifies the IRQ priority of UART device to be used - for Bluetooth. - # Headroom that the driver needs for sending and receiving buffers. # Add a new 'default' entry for each new driver. diff --git a/drivers/bluetooth/h4.c b/drivers/bluetooth/h4.c index 6fbf7f2..0fc3abd 100644 --- a/drivers/bluetooth/h4.c +++ b/drivers/bluetooth/h4.c @@ -123,7 +123,7 @@ static struct net_buf *h4_acl_recv(int *remaining) return buf; } -void bt_uart_isr(void *unused) +static void bt_uart_isr(struct device *unused) { static struct net_buf *buf; static int remaining; @@ -223,9 +223,6 @@ static int h4_open(void) uart_irq_rx_disable(h4_dev); uart_irq_tx_disable(h4_dev); - IRQ_CONNECT(CONFIG_BLUETOOTH_UART_IRQ, CONFIG_BLUETOOTH_UART_IRQ_PRI, - bt_uart_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_BLUETOOTH_UART_IRQ); /* Drain the fifo */ while (uart_irq_rx_ready(h4_dev)) { @@ -234,6 +231,8 @@ static int h4_open(void) uart_fifo_read(h4_dev, &c, 1); } + uart_irq_callback_set(h4_dev, bt_uart_isr); + uart_irq_rx_enable(h4_dev); return 0; diff --git a/drivers/bluetooth/h5.c b/drivers/bluetooth/h5.c index 5a6a4ba..562b0e7 100644 --- a/drivers/bluetooth/h5.c +++ b/drivers/bluetooth/h5.c @@ -445,7 +445,7 @@ static void h5_process_complete_packet(uint8_t *hdr) } } -void bt_uart_isr(void *unused) +static void bt_uart_isr(struct device *unused) { static int remaining; uint8_t byte; @@ -748,10 +748,6 @@ static int h5_open(void) uart_irq_rx_disable(h5_dev); uart_irq_tx_disable(h5_dev); - IRQ_CONNECT(CONFIG_BLUETOOTH_UART_IRQ, CONFIG_BLUETOOTH_UART_IRQ_PRI, - bt_uart_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_BLUETOOTH_UART_IRQ); - /* Drain the fifo */ while (uart_irq_rx_ready(h5_dev)) { unsigned char c; @@ -759,6 +755,8 @@ static int h5_open(void) uart_fifo_read(h5_dev, &c, 1); } + uart_irq_callback_set(h5_dev, bt_uart_isr); + h5_init(); uart_irq_rx_enable(h5_dev); diff --git a/drivers/console/Kconfig b/drivers/console/Kconfig index c8dc686..0638f70 100644 --- a/drivers/console/Kconfig +++ b/drivers/console/Kconfig @@ -73,20 +73,6 @@ config UART_CONSOLE_ON_DEV_NAME This option specifies the name of UART device to be used for UART console. -config UART_CONSOLE_IRQ - int "IRQ of UART Device for UART Console" - depends on UART_CONSOLE - help - This option specifies the IRQ of UART device to be used for - UART console. - -config UART_CONSOLE_IRQ_PRI - int "IRQ of UART Device for UART Console" - depends on UART_CONSOLE - help - This option specifies the IRQ priorityof UART device to be - used for UART console. - config UART_CONSOLE_PRIORITY int prompt "Init priority" @@ -160,18 +146,4 @@ config UART_PIPE_ON_DEV_NAME This option specifies the name of UART device to be used for pipe UART. -config UART_PIPE_IRQ - int "IRQ for pipe UART" - depends on UART_PIPE - help - This option specifies the IRQ of UART device to be used - for pipe UART. - -config UART_PIPE_IRQ_PRI - int "IRQ Priority for pipe UART" - depends on UART_PIPE - help - This option specifies the IRQ priority of UART device - to be used for pipe UART. - endif diff --git a/drivers/console/uart_console.c b/drivers/console/uart_console.c index 762b7aa..72c5631 100644 --- a/drivers/console/uart_console.c +++ b/drivers/console/uart_console.c @@ -278,7 +278,7 @@ ansi_cmd: atomic_clear_bit(&esc_state, ESC_ANSI); } -void uart_console_isr(void *unused) +void uart_console_isr(struct device *unused) { ARG_UNUSED(unused); @@ -373,9 +373,8 @@ static void console_input_init(void) uart_irq_rx_disable(uart_console_dev); uart_irq_tx_disable(uart_console_dev); - IRQ_CONNECT(CONFIG_UART_CONSOLE_IRQ, CONFIG_UART_CONSOLE_IRQ_PRI, - uart_console_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_UART_CONSOLE_IRQ); + + uart_irq_callback_set(uart_console_dev, uart_console_isr); /* Drain the fifo */ while (uart_irq_rx_ready(uart_console_dev)) { diff --git a/drivers/console/uart_pipe.c b/drivers/console/uart_pipe.c index f56f9b1..c8c89ae 100644 --- a/drivers/console/uart_pipe.c +++ b/drivers/console/uart_pipe.c @@ -36,7 +36,7 @@ static size_t recv_buf_len; static uart_pipe_recv_cb app_cb; static size_t recv_off; -void uart_pipe_isr(void *unused) +static void uart_pipe_isr(struct device *unused) { ARG_UNUSED(unused); @@ -77,10 +77,6 @@ static void uart_pipe_setup(struct device *uart) uart_irq_rx_disable(uart); uart_irq_tx_disable(uart); - IRQ_CONNECT(CONFIG_UART_PIPE_IRQ, CONFIG_UART_PIPE_IRQ_PRI, - uart_pipe_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_UART_PIPE_IRQ); - /* Drain the fifo */ while (uart_irq_rx_ready(uart)) { unsigned char c; @@ -88,6 +84,8 @@ static void uart_pipe_setup(struct device *uart) uart_fifo_read(uart, &c, 1); } + uart_irq_callback_set(uart, uart_pipe_isr); + uart_irq_rx_enable(uart); } diff --git a/drivers/nble/Kconfig b/drivers/nble/Kconfig index c7cfa7e..e52e3ed 100644 --- a/drivers/nble/Kconfig +++ b/drivers/nble/Kconfig @@ -120,18 +120,4 @@ config NBLE_UART_ON_DEV_NAME This option specifies the name of UART device to be used for Nordic BLE. -config NBLE_UART_IRQ - int "IRQ of UART Device for Nordic BLE" - depends on NBLE - help - This option specifies the IRQ of UART device to be used - for Nordic BLE. - -config NBLE_UART_IRQ_PRI - int "IRQ Priority of UART Device for Nordic BLE" - depends on NBLE - help - This option specifies the IRQ priority of UART device to be used - for Nordic BLE. - endif diff --git a/drivers/nble/uart.c b/drivers/nble/uart.c index f42904c..378c580 100644 --- a/drivers/nble/uart.c +++ b/drivers/nble/uart.c @@ -125,7 +125,7 @@ static size_t nble_discard(struct device *uart, size_t len) return uart_fifo_read(uart, buf, min(len, sizeof(buf))); } -void bt_uart_isr(void *unused) +static void bt_uart_isr(struct device *unused) { static struct net_buf *buf; @@ -206,10 +206,6 @@ int nble_open(void) uart_irq_rx_disable(nble_dev); uart_irq_tx_disable(nble_dev); - IRQ_CONNECT(CONFIG_NBLE_UART_IRQ, CONFIG_NBLE_UART_IRQ_PRI, - bt_uart_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_NBLE_UART_IRQ); - /* Drain the fifo */ while (uart_irq_rx_ready(nble_dev)) { unsigned char c; @@ -217,6 +213,8 @@ int nble_open(void) uart_fifo_read(nble_dev, &c, 1); } + uart_irq_callback_set(nble_dev, bt_uart_isr); + uart_irq_rx_enable(nble_dev); return 0; diff --git a/drivers/serial/uart_k20.c b/drivers/serial/uart_k20.c index 3f0985e..5c261f0 100644 --- a/drivers/serial/uart_k20.c +++ b/drivers/serial/uart_k20.c @@ -31,6 +31,7 @@ #include <toolchain.h> #include <sections.h> +#include "uart_k20.h" #include "uart_k20_priv.h" /* convenience defines */ @@ -45,6 +46,10 @@ /* Device data structure */ struct uart_k20_dev_data_t { uint32_t baud_rate; /* Baud rate */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_t cb; /**< Callback function pointer */ +#endif }; static struct uart_driver_api uart_k20_driver_api; @@ -90,6 +95,10 @@ static int uart_k20_init(struct device *dev) /* restore interrupt state */ irq_unlock(old_level); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + dev_cfg->irq_config_func(dev); +#endif + dev->driver_api = &uart_k20_driver_api; return DEV_OK; @@ -339,6 +348,41 @@ static int uart_k20_irq_update(struct device *dev) return 1; } +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * + * @return N/A + */ +static void uart_k20_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_k20_dev_data_t * const dev_data = DEV_DATA(dev); + + dev_data->cb = cb; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + * + * @return N/A + */ +void uart_k20_isr(void *arg) +{ + struct device *dev = arg; + struct uart_k20_dev_data_t * const dev_data = DEV_DATA(dev); + + if (dev_data->cb) { + dev_data->cb(dev); + } +} + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -360,6 +404,7 @@ static struct uart_driver_api uart_k20_driver_api = { .irq_err_disable = uart_k20_irq_err_disable, .irq_is_pending = uart_k20_irq_is_pending, .irq_update = uart_k20_irq_update, + .irq_callback_set = uart_k20_irq_callback_set, #endif }; @@ -367,9 +412,17 @@ static struct uart_driver_api uart_k20_driver_api = { #ifdef CONFIG_UART_K20_PORT_0 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_0 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_0_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_0_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_0, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_0 = { @@ -380,13 +433,32 @@ DEVICE_INIT(uart_k20_0, CONFIG_UART_K20_PORT_0_NAME, &uart_k20_init, &uart_k20_dev_data_0, &uart_k20_dev_cfg_0, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_0_IRQ, + CONFIG_UART_K20_PORT_0_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_0), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_0_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_0 */ #ifdef CONFIG_UART_K20_PORT_1 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_1 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_1_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_1_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_1, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_1 = { @@ -397,13 +469,32 @@ DEVICE_INIT(uart_k20_1, CONFIG_UART_K20_PORT_1_NAME, &uart_k20_init, &uart_k20_dev_data_1, &uart_k20_dev_cfg_1, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_1_IRQ, + CONFIG_UART_K20_PORT_1_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_1), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_1_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_1 */ #ifdef CONFIG_UART_K20_PORT_2 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_2 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_2_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_2_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_2, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_2 = { @@ -414,13 +505,32 @@ DEVICE_INIT(uart_k20_2, CONFIG_UART_K20_PORT_2_NAME, &uart_k20_init, &uart_k20_dev_data_2, &uart_k20_dev_cfg_2, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_2_IRQ, + CONFIG_UART_K20_PORT_2_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_2), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_2_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_2 */ #ifdef CONFIG_UART_K20_PORT_3 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_3(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_3 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_3_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_3_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_3, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_3 = { @@ -431,13 +541,32 @@ DEVICE_INIT(uart_k20_3, CONFIG_UART_K20_PORT_3_NAME, &uart_k20_init, &uart_k20_dev_data_3, &uart_k20_dev_cfg_3, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_3(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_3_IRQ, + CONFIG_UART_K20_PORT_3_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_3), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_3_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_3 */ #ifdef CONFIG_UART_K20_PORT_4 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_4(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_4 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_4_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_4_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_4, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_4 = { @@ -448,4 +577,15 @@ DEVICE_INIT(uart_k20_4, CONFIG_UART_K20_PORT_4_NAME, &uart_k20_init, &uart_k20_dev_data_4, &uart_k20_dev_cfg_4, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_4(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_4_IRQ, + CONFIG_UART_K20_PORT_4_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_4), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_4_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_4 */ diff --git a/drivers/serial/uart_k20.h b/drivers/serial/uart_k20.h new file mode 100644 index 0000000..ca92859 --- /dev/null +++ b/drivers/serial/uart_k20.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file UART header file for the K20 family of microprocessors.. + */ + +#ifndef _UART_K20_H_ +#define _UART_K20_H_ + +void uart_k20_isr(void *arg); + +#endif /* _UART_K20_H_ */ diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 543f7a0..f6b0b2e 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -210,6 +210,7 @@ struct uart_ns16550_dev_data_t { #ifdef CONFIG_UART_INTERRUPT_DRIVEN uint8_t iir_cache; /**< cache of IIR since it clears when read */ + uart_irq_callback_t cb; /**< Callback function pointer */ #endif #ifdef CONFIG_UART_NS16550_DLF @@ -336,6 +337,10 @@ static int uart_ns16550_init(struct device *dev) irq_unlock(old_level); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + DEV_CFG(dev)->irq_config_func(dev); +#endif + dev->driver_api = &uart_ns16550_driver_api; return DEV_OK; @@ -576,6 +581,41 @@ static int uart_ns16550_irq_update(struct device *dev) return 1; } +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * + * @return N/A + */ +static void uart_ns16550_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); + + dev_data->cb = cb; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + * + * @return N/A + */ +static void uart_ns16550_isr(void *arg) +{ + struct device *dev = arg; + struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); + + if (dev_data->cb) { + dev_data->cb(dev); + } +} + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #ifdef CONFIG_UART_NS16550_LINE_CTRL @@ -671,6 +711,7 @@ static struct uart_driver_api uart_ns16550_driver_api = { .irq_err_disable = uart_ns16550_irq_err_disable, .irq_is_pending = uart_ns16550_irq_is_pending, .irq_update = uart_ns16550_irq_update, + .irq_callback_set = uart_ns16550_irq_callback_set, #endif @@ -685,6 +726,10 @@ static struct uart_driver_api uart_ns16550_driver_api = { #ifdef CONFIG_UART_NS16550_PORT_0 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *port); +#endif + struct uart_device_config uart_ns16550_dev_cfg_0 = { .port = CONFIG_UART_NS16550_PORT_0_BASE_ADDR, .sys_clk_freq = CONFIG_UART_NS16550_PORT_0_CLK_FREQ, @@ -698,6 +743,10 @@ struct uart_device_config uart_ns16550_dev_cfg_0 = { .pci_dev.function = CONFIG_UART_NS16550_PORT_0_PCI_FUNC, .pci_dev.bar = CONFIG_UART_NS16550_PORT_0_PCI_BAR, #endif /* CONFIG_UART_NS16550_PORT_0_PCI */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_0, +#endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_0 = { @@ -713,10 +762,25 @@ DEVICE_INIT(uart_ns16550_0, CONFIG_UART_NS16550_PORT_0_NAME, &uart_ns16550_init, &uart_ns16550_dev_data_0, &uart_ns16550_dev_cfg_0, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_NS16550_PORT_0_IRQ, + CONFIG_UART_NS16550_PORT_0_IRQ_PRI, + uart_ns16550_isr, DEVICE_GET(uart_ns16550_0), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_NS16550_PORT_0_IRQ); +} +#endif + #endif /* CONFIG_UART_NS16550_PORT_0 */ #ifdef CONFIG_UART_NS16550_PORT_1 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *port); +#endif + struct uart_device_config uart_ns16550_dev_cfg_1 = { .port = CONFIG_UART_NS16550_PORT_1_BASE_ADDR, .sys_clk_freq = CONFIG_UART_NS16550_PORT_1_CLK_FREQ, @@ -730,6 +794,10 @@ struct uart_device_config uart_ns16550_dev_cfg_1 = { .pci_dev.function = CONFIG_UART_NS16550_PORT_1_PCI_FUNC, .pci_dev.bar = CONFIG_UART_NS16550_PORT_1_PCI_BAR, #endif /* CONFIG_UART_NS16550_PORT_1_PCI */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_1, +#endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_1 = { @@ -745,4 +813,15 @@ DEVICE_INIT(uart_ns16550_1, CONFIG_UART_NS16550_PORT_1_NAME, &uart_ns16550_init, &uart_ns16550_dev_data_1, &uart_ns16550_dev_cfg_1, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_NS16550_PORT_1_IRQ, + CONFIG_UART_NS16550_PORT_1_IRQ_PRI, + uart_ns16550_isr, DEVICE_GET(uart_ns16550_1), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_NS16550_PORT_1_IRQ); +} +#endif + #endif /* CONFIG_UART_NS16550_PORT_1 */ diff --git a/drivers/serial/uart_stellaris.c b/drivers/serial/uart_stellaris.c index 3a6ea16..eaaa10e 100644 --- a/drivers/serial/uart_stellaris.c +++ b/drivers/serial/uart_stellaris.c @@ -34,6 +34,8 @@ #include <uart.h> #include <sections.h> +#include "uart_stellaris.h" + /* definitions */ /* Stellaris UART module */ @@ -76,6 +78,10 @@ struct _uart { /* Device data structure */ struct uart_stellaris_dev_data_t { uint32_t baud_rate; /* Baud rate */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_t cb; /**< Callback function pointer */ +#endif }; /* convenience defines */ @@ -271,6 +277,10 @@ static int uart_stellaris_init(struct device *dev) line_control_defaults_set(dev); enable(dev); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + DEV_CFG(dev)->irq_config_func(dev); +#endif + dev->driver_api = &uart_stellaris_driver_api; return DEV_OK; @@ -565,6 +575,41 @@ static int uart_stellaris_irq_update(struct device *dev) return 1; } +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * + * @return N/A + */ +static void uart_stellaris_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_stellaris_dev_data_t * const dev_data = DEV_DATA(dev); + + dev_data->cb = cb; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + * + * @return N/A + */ +void uart_stellaris_isr(void *arg) +{ + struct device *dev = arg; + struct uart_stellaris_dev_data_t * const dev_data = DEV_DATA(dev); + + if (dev_data->cb) { + dev_data->cb(dev); + } +} + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -586,6 +631,7 @@ static struct uart_driver_api uart_stellaris_driver_api = { .irq_err_disable = uart_stellaris_irq_err_disable, .irq_is_pending = uart_stellaris_irq_is_pending, .irq_update = uart_stellaris_irq_update, + .irq_callback_set = uart_stellaris_irq_callback_set, #endif }; @@ -593,9 +639,17 @@ static struct uart_driver_api uart_stellaris_driver_api = { #ifdef CONFIG_UART_STELLARIS_PORT_0 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *port); +#endif + static struct uart_device_config uart_stellaris_dev_cfg_0 = { .base = (uint8_t *)CONFIG_UART_STELLARIS_PORT_0_BASE_ADDR, .sys_clk_freq = CONFIG_UART_STELLARIS_PORT_0_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_0, +#endif }; static struct uart_stellaris_dev_data_t uart_stellaris_dev_data_0 = { @@ -606,13 +660,32 @@ DEVICE_INIT(uart_stellaris0, CONFIG_UART_STELLARIS_PORT_0_NAME, &uart_stellaris_ &uart_stellaris_dev_data_0, &uart_stellaris_dev_cfg_0, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_STELLARIS_PORT_0_IRQ, + CONFIG_UART_STELLARIS_PORT_0_IRQ_PRI, + uart_stellaris_isr, DEVICE_GET(uart_stellaris0), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_STELLARIS_PORT_0_IRQ); +} +#endif + #endif /* CONFIG_UART_STELLARIS_PORT_0 */ #ifdef CONFIG_UART_STELLARIS_PORT_1 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *port); +#endif + static struct uart_device_config uart_stellaris_dev_cfg_1 = { .base = (uint8_t *)CONFIG_UART_STELLARIS_PORT_1_BASE_ADDR, .sys_clk_freq = CONFIG_UART_STELLARIS_PORT_1_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_1, +#endif }; static struct uart_stellaris_dev_data_t uart_stellaris_dev_data_1 = { @@ -623,13 +696,32 @@ DEVICE_INIT(uart_stellaris1, CONFIG_UART_STELLARIS_PORT_1_NAME, &uart_stellaris_ &uart_stellaris_dev_data_1, &uart_stellaris_dev_cfg_1, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_STELLARIS_PORT_1_IRQ, + CONFIG_UART_STELLARIS_PORT_1_IRQ_PRI, + uart_stellaris_isr, DEVICE_GET(uart_stellaris1), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_STELLARIS_PORT_1_IRQ); +} +#endif + #endif /* CONFIG_UART_STELLARIS_PORT_1 */ #ifdef CONFIG_UART_STELLARIS_PORT_2 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *port); +#endif + static struct uart_device_config uart_stellaris_dev_cfg_2 = { .base = (uint8_t *)CONFIG_UART_STELLARIS_PORT_2_BASE_ADDR, .sys_clk_freq = CONFIG_UART_STELLARIS_PORT_2_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_2, +#endif }; static struct uart_stellaris_dev_data_t uart_stellaris_dev_data_2 = { @@ -640,4 +732,15 @@ DEVICE_INIT(uart_stellaris2, CONFIG_UART_STELLARIS_PORT_2_NAME, &uart_stellaris_ &uart_stellaris_dev_data_2, &uart_stellaris_dev_cfg_2, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_STELLARIS_PORT_2_IRQ, + CONFIG_UART_STELLARIS_PORT_2_IRQ_PRI, + uart_stellaris_isr, DEVICE_GET(uart_stellaris2), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_STELLARIS_PORT_2_IRQ); +} +#endif + #endif /* CONFIG_UART_STELLARIS_PORT_2 */ diff --git a/drivers/serial/uart_stellaris.h b/drivers/serial/uart_stellaris.h new file mode 100644 index 0000000..4a14ef3 --- /dev/null +++ b/drivers/serial/uart_stellaris.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Header file for Stellaris UART. + */ + +#ifndef _UART_STELLARIS_H_ +#define _UART_STELLARIS_H_ + +void uart_console_isr(void *arg); + +#endif /* _UART_STELLARIS_H_ */ diff --git a/include/drivers/console/uart_console.h b/include/drivers/console/uart_console.h index 4634e33..963e8af 100644 --- a/include/drivers/console/uart_console.h +++ b/include/drivers/console/uart_console.h @@ -46,8 +46,6 @@ struct uart_console_input { */ void uart_register_input(struct nano_fifo *avail, struct nano_fifo *lines); -void uart_console_isr(void *unused); - #ifdef __cplusplus } #endif diff --git a/include/drivers/console/uart_pipe.h b/include/drivers/console/uart_pipe.h index 3b7594a..2391bbd 100644 --- a/include/drivers/console/uart_pipe.h +++ b/include/drivers/console/uart_pipe.h @@ -62,15 +62,6 @@ void uart_pipe_register(uint8_t *buf, size_t len, uart_pipe_recv_cb cb); */ int uart_pipe_send(const uint8_t *data, int len); -/** @brief Simple UART interrupt handler. - * - * This function is called from an interrupt and should not be called by - * an application directly. - * - * @param unused unused - */ -void uart_pipe_isr(void *unused); - #ifdef __cplusplus } #endif diff --git a/include/uart.h b/include/uart.h index 66e5123..cba33c3 100644 --- a/include/uart.h +++ b/include/uart.h @@ -71,6 +71,16 @@ extern "C" { */ #define UART_ERROR_BREAK (1 << 3) +/** + * @brief Define the application callback function signature for UART. + * + * @param port Device struct for the UART device. + */ +typedef void (*uart_irq_callback_t)(struct device *port); + +/* For configuring IRQ on each individual UART device. Internal use only. */ +typedef void (*uart_irq_config_func_t)(struct device *port); + /** @brief UART device configuration.*/ struct uart_device_config { /** @@ -90,6 +100,10 @@ struct uart_device_config { #ifdef CONFIG_PCI struct pci_dev_info pci_dev; #endif /* CONFIG_PCI */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_config_func_t irq_config_func; +#endif }; /** @brief Driver API structure. */ @@ -145,6 +159,9 @@ struct uart_driver_api { /** Interrupt driven input hook function */ int (*irq_input_hook)(struct device *dev, uint8_t byte); + /** Set the callback function */ + void (*irq_callback_set)(struct device *dev, uart_irq_callback_t cb); + #endif #ifdef CONFIG_UART_LINE_CTRL @@ -516,6 +533,30 @@ static inline void uart_irq_input_hook_set(struct device *dev, } } + +/** + * @brief Set the IRQ callback function pointer. + * + * This sets up the callback for IRQ. When an IRQ is triggered, + * the specified function will be called. + * + * @param dev UART device structure. + * @param cb Pointer to the callback function. + * + * @return N/A + */ +static inline void uart_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_driver_api *api; + + api = (struct uart_driver_api *)dev->driver_api; + + if ((api != NULL) && (api->irq_callback_set != NULL)) { + api->irq_callback_set(dev, cb); + } +} + #endif #ifdef CONFIG_UART_LINE_CTRL -- 2.7.2 |
|
Benjamin Walsh <benjamin.walsh@...>
On Tue, Mar 01, 2016 at 04:04:02PM -0800, Daniel Leung wrote:
The peripherals utilizing UART were required to register their ownBecause of the pointer dereference, the check for NULL and the function call ? It's probably OK. And you could turn the check into an __ASSERT() if you want to save a bit or both code space and time. I'm OK with this change. Note that this patch breaks backward compatibility in terms of-- Benjamin Walsh, SMTS Wind River Rocket www.windriver.com Zephyr kernel maintainer www.zephyrproject.org |
|
Andre Guedes <andre.guedes@...>
Hi Daniel,
Quoting Daniel Leung (2016-03-01 21:04:02) The peripherals utilizing UART were required to register their ownThis is actually a nice improvement on the UART API since it moves the burden of registering the ISR from the user layer to the driver layer, which is the right place, IMO. Actually, the UART API is very low level when we compare it with other APIs such as SPI and I2C. For instance, the UART API exposes functions to manipulate the FIFOs and check for interrupt flags. Is there any plan to add higher level APIs such as "transmit the characters from this buffer and call this callback once the transmission finishes" or "read 10 characters into this buffer and call this callback once it is done"? Regards, Andre
|
|
Daniel Leung <daniel.leung@...>
On Wed, Mar 02, 2016 at 10:14:02PM -0300, Andre Guedes wrote:
Hi Daniel,This is something I have thought about, but there is no concrete plan. Is there anything particular you are looking for? Use cases would be a good start. This helps me to understand what needs to be done. ----- Daniel Leung |
|
Andre Guedes <andre.guedes@...>
Hi Daniel,
Quoting Daniel Leung (2016-03-02 22:35:24) No, I don't have anything in particular. Probably the bluetooth driversThis is actually a nice improvement on the UART API since it moves theThis is something I have thought about, but there is no concrete plan. and the console_uart driver are a good source of use cases. For instance, they all have their own implementation of a mechanism read data asynchronously. An API such as uart_read(dev, callback, buf, len) might be useful. Regards, Andre |
|
Daniel Leung <daniel.leung@...>
On Thu, Mar 03, 2016 at 12:30:09PM -0300, Andre Guedes wrote:
Hi Daniel,I have created a JIRA to address this @ https://jira.zephyrproject.org/browse/ZEP-89 ----- Daniel Leung |
|