From 46444388faed3198b8eb4010105f43e295f1a6bb Mon Sep 17 00:00:00 2001 From: "Anton D. Kachalov" Date: Mon, 10 Aug 2015 18:13:35 +0300 Subject: [PATCH] Add Shared IRQ support for UART w/multi port. Signed-off-by: Anton D. Kachalov --- arch/arm/Kconfig | 1 + arch/arm/include/moxart/irq.h | 5 +++-- arch/arm/src/moxart/Kconfig | 9 +++++++++ arch/arm/src/moxart/moxart_16550.c | 29 +++++++++++++++++++++++++++-- arch/arm/src/moxart/moxart_irq.c | 11 +++++++++++ arch/arm/src/moxart/moxart_timer.c | 3 --- 6 files changed, 51 insertions(+), 7 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0b44c79f2b..2ba434667d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -227,6 +227,7 @@ config ARCH_CHIP_MOXART bool "MoxART" select ARCH_ARM7TDMI select ARCH_HAVE_RESET + select ARCH_HAVE_SERIAL_TERMIOS ---help--- MoxART family diff --git a/arch/arm/include/moxart/irq.h b/arch/arm/include/moxart/irq.h index 31c92ed5d3..238d47761e 100644 --- a/arch/arm/include/moxart/irq.h +++ b/arch/arm/include/moxart/irq.h @@ -81,7 +81,8 @@ extern "C" #define IRQ_SYSTIMER 19 -#define NR_IRQS 32 +#define VIRQ_START 32 + +#define NR_IRQS (VIRQ_START+2) #endif /* __ARCH_ARM_INCLUDE_MOXART_IRQ_H */ - diff --git a/arch/arm/src/moxart/Kconfig b/arch/arm/src/moxart/Kconfig index 3c8166499f..d7487ee8a0 100644 --- a/arch/arm/src/moxart/Kconfig +++ b/arch/arm/src/moxart/Kconfig @@ -7,3 +7,12 @@ comment "MoxART Configuration Options" config UART_MOXA_MODE_REG hex "16550 UART mode register address" + default 0x982000E0 + +config UART_MOXA_IRQ_STATUS_REG + hex "16550 UART shared IRQ status register address" + default 0x982000C0 + +config UART_MOXA_SHARED_IRQ + int "16550 UART shared IRQ number" + default 31 diff --git a/arch/arm/src/moxart/moxart_16550.c b/arch/arm/src/moxart/moxart_16550.c index ac911d6bce..4f505f00e1 100644 --- a/arch/arm/src/moxart/moxart_16550.c +++ b/arch/arm/src/moxart/moxart_16550.c @@ -67,6 +67,30 @@ void uart_putreg(uart_addrwidth_t base, unsigned int offset, uart_datawidth_t va *((volatile uart_addrwidth_t *)base + offset) = value; } +void uart_decodeirq(int irq, FAR void *context) +{ + int i; + uint32_t status; + static int os = 0; + + status = *((volatile uart_addrwidth_t *)CONFIG_UART_MOXA_IRQ_STATUS_REG); + + if ((status & 0x3f) == 0x3f) + { + return; + } + + i = 0; + do + { + if (!(status & 0x1)) { + irq_dispatch(VIRQ_START + i, context); + } + status >>= 1; + } + while (++i <= 4); +} + #ifdef CONFIG_SERIAL_UART_ARCH_IOCTL int uart_ioctl(struct file *filep, int cmd, unsigned long arg) { @@ -109,8 +133,9 @@ int uart_ioctl(struct file *filep, int cmd, unsigned long arg) /* Update mode register with requested mode */ vmode = getreg32(CONFIG_UART_MOXA_MODE_REG); - vmode = (vmode & ~(OP_MODE_MASK << 2 * bitm_off)) | ((opmode << 2 * bitm_off) & 0xffff); - putreg32(vmode, CONFIG_UART_MOXA_MODE_REG); + putreg32(vmode & ~(OP_MODE_MASK << 2 * bitm_off), CONFIG_UART_MOXA_MODE_REG); + vmode = opmode << 2 * bitm_off; + putreg32(getreg32(CONFIG_UART_MOXA_MODE_REG) | vmode, CONFIG_UART_MOXA_MODE_REG); irqrestore(flags); ret = OK; diff --git a/arch/arm/src/moxart/moxart_irq.c b/arch/arm/src/moxart/moxart_irq.c index a29f5b2c4a..fc2a5a3dae 100644 --- a/arch/arm/src/moxart/moxart_irq.c +++ b/arch/arm/src/moxart/moxart_irq.c @@ -81,6 +81,8 @@ volatile uint32_t *current_regs; * Public Functions ****************************************************************************/ +extern void uart_decodeirq(int irq, uint32_t *regs); + /**************************************************************************** * Name: up_irqinitialize * @@ -93,6 +95,9 @@ void up_irqinitialize(void) { /* Prepare hardware */ + *(volatile int *)0x98700000 |= 0x3f; + + /* PMU setup */ (*(volatile uint32_t *)0x98100008) &= ~0x9; while (!((*(volatile uint32_t *)0x98100008) & 0x2)) { ; } @@ -101,6 +106,8 @@ void up_irqinitialize(void) (*(volatile uint32_t *)0x98800100) = 0xDFF8003F; + /* Check board type */ + /* Mask all interrupts off */ putreg32(0, IRQ_REG(IRQ__MASK)); @@ -119,6 +126,10 @@ void up_irqinitialize(void) current_regs = NULL; + /* Setup UART shared interrupt */ + irq_attach(CONFIG_UART_MOXA_SHARED_IRQ, uart_decodeirq); + up_enable_irq(CONFIG_UART_MOXA_SHARED_IRQ); + /* And finally, enable interrupts */ #if 1 diff --git a/arch/arm/src/moxart/moxart_timer.c b/arch/arm/src/moxart/moxart_timer.c index b085e63115..e2c115bee8 100644 --- a/arch/arm/src/moxart/moxart_timer.c +++ b/arch/arm/src/moxart/moxart_timer.c @@ -132,9 +132,6 @@ void up_timer_initialize(void) uint32_t tmp; // up_disable_irq(IRQ_SYSTIMER); - - *(volatile int *)0x98700000 = 0x3f; - putreg32(0, TM1_ADDR + CNTL_TIMER); putreg32(0, TM1_ADDR + INTR_STATE_TIMER); putreg32(0x1ff, TM1_ADDR + INTR_MASK_TIMER);