Add Shared IRQ support for UART w/multi port.

Signed-off-by: Anton D. Kachalov <mouse@yandex-team.ru>
This commit is contained in:
Anton D. Kachalov 2015-08-10 18:13:35 +03:00
parent a8fc587d87
commit 46444388fa
6 changed files with 51 additions and 7 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);