Commit 5cc90896 authored by David Brownell's avatar David Brownell Committed by Kevin Hilman

irq cleanup

Some tweaks and cleanups for the DaVinci IRQ framework:

  - Don't bother storing a table of integers in SRAM and using it during
    IRQ dispatch.  Just do math on the IRQENTRY register to get the irq
    number with fewer and faster instructions, freeing that SRAM.

  - Provide a mechanism to use IRQ prioritization, and to let boards set it
    up as appropriate for the product at hand; there's a default mapping.
    (This approach to handling IRQ priorities, and the initial table, is
    modeled on how AT91 does this.)

  - Comment out declarations of bogus or reserved (per docs) IRQs.

  - Minor fixes to genirq setup:  only handle the AINTC irqs here; use
    genirq-style dispatcher names; and cleanup by merging both routines.

I'm certain the default irq priority table could stand tweaking.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarKevin Hilman <khilman@mvista.com>
parent 524fda60
......@@ -265,7 +265,7 @@ static __init void davinci_evm_init(void)
static __init void davinci_evm_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
davinci_irq_init(NULL);
}
MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
......
......@@ -31,10 +31,8 @@
#include <asm/io.h>
#include <asm/mach/irq.h>
#define IRQ_BIT(irq) ((irq) & 0x1f)
#define INTC_IDT_BASE DAVINCI_IRAM_VIRT
#define INTC_VECT_OFFSET 0x100
#define IRQ_BIT(irq) ((irq) & 0x1f)
#define FIQ_REG0_OFFSET 0x0000
#define FIQ_REG1_OFFSET 0x0004
......@@ -44,8 +42,8 @@
#define IRQ_ENT_REG1_OFFSET 0x001C
#define IRQ_INCTL_REG_OFFSET 0x0020
#define IRQ_EABASE_REG_OFFSET 0x0024
static void __init davinci_intcinit(void);
#define IRQ_INTPRI0_REG_OFFSET 0x0030 /* intpri0..intpri7 */
#define IRQ_INTPRI7_REG_OFFSET 0x004C
static inline unsigned int davinci_irq_readl(int offset)
{
......@@ -115,38 +113,80 @@ static struct irq_chip davinci_irq_chip_0 = {
.unmask = davinci_unmask_irq,
};
void __init davinci_irq_init(void)
{
int i;
unsigned int *idtbase = (unsigned int *)INTC_IDT_BASE;
unsigned int *eabase;
davinci_intcinit();
eabase = idtbase + INTC_VECT_OFFSET / sizeof(*idtbase);
*eabase = ~0x0;
eabase++;
for (i = 1; i < NR_IRQS; i++) {
*eabase = i - 1;
eabase++;
}
/* Proggam the irqchip structures for ARM INTC */
for (i = 0; i < NR_IRQS; i++) {
set_irq_chip(i, &davinci_irq_chip_0);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
if (i != IRQ_TINT1_TINT34)
set_irq_handler(i, do_edge_IRQ);
else
set_irq_handler(i, do_level_IRQ);
}
}
/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
[IRQ_VDINT0] = 0, /* always fiq */
[IRQ_VDINT1] = 6,
[IRQ_VDINT2] = 6,
[IRQ_HISTINT] = 6,
[IRQ_H3AINT] = 6,
[IRQ_PRVUINT] = 6,
[IRQ_RSZINT] = 6,
[7] = 7,
[IRQ_VENCINT] = 6,
[IRQ_ASQINT] = 6,
[IRQ_IMXINT] = 6,
[IRQ_VLCDINT] = 6,
[IRQ_USBINT] = 4,
[IRQ_EMACINT] = 4,
[14] = 7,
[15] = 7,
[IRQ_CCINT0] = 5, /* dma */
[IRQ_CCERRINT] = 5, /* dma */
[IRQ_TCERRINT0] = 5, /* dma */
[IRQ_TCERRINT] = 5, /* dma */
[IRQ_PSCIN] = 7,
[21] = 7,
[IRQ_IDE] = 4,
[23] = 7,
[IRQ_MBXINT] = 7,
[IRQ_MBRINT] = 7,
[IRQ_MMCINT] = 7,
[IRQ_SDIOINT] = 7,
[28] = 7,
[IRQ_DDRINT] = 7,
[IRQ_AEMIFINT] = 7,
[IRQ_VLQINT] = 4,
[IRQ_TINT0_TINT12] = 2, /* free run timer */
[IRQ_TINT0_TINT34] = 2, /* hi res timer */
[IRQ_TINT1_TINT12] = 7, /* DSP timer */
[IRQ_TINT1_TINT34] = 2, /* system tick */
[IRQ_PWMINT0] = 7,
[IRQ_PWMINT1] = 7,
[IRQ_PWMINT2] = 7,
[IRQ_I2C] = 3,
[IRQ_UARTINT0] = 3,
[IRQ_UARTINT1] = 3,
[IRQ_UARTINT2] = 3,
[IRQ_SPINT0] = 3,
[IRQ_SPINT1] = 3,
[45] = 7,
[IRQ_DSP2ARM0] = 4,
[IRQ_DSP2ARM1] = 4,
[IRQ_GPIO0] = 7,
[IRQ_GPIO1] = 7,
[IRQ_GPIO2] = 7,
[IRQ_GPIO3] = 7,
[IRQ_GPIO4] = 7,
[IRQ_GPIO5] = 7,
[IRQ_GPIO6] = 7,
[IRQ_GPIO7] = 7,
[IRQ_GPIOBNK0] = 7,
[IRQ_GPIOBNK1] = 7,
[IRQ_GPIOBNK2] = 7,
[IRQ_GPIOBNK3] = 7,
[IRQ_GPIOBNK4] = 7,
[IRQ_COMMTX] = 7,
[IRQ_COMMRX] = 7,
[IRQ_EMUINT] = 7,
};
/* ARM Interrupt Controller Initialize */
static void __init davinci_intcinit(void)
/* ARM Interrupt Controller Initialization */
void __init davinci_irq_init(const u8 priority[DAVINCI_N_AINTC_IRQ])
{
unsigned i;
/* Clear all interrupt requests */
davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
......@@ -160,12 +200,35 @@ static void __init davinci_intcinit(void)
/* Interrupts disabled immediately. IRQ entry reflects all interrupts */
davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET);
/* Set vector table base address - 4 byte entry */
davinci_irq_writel(INTC_VECT_OFFSET, IRQ_EABASE_REG_OFFSET);
/* we don't use the hardware vector table, just its entry addresses */
davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET);
/* Clear all interrupt requests */
davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
/* initialize irq priorities from hw default all=7 */
if (priority == NULL)
priority = default_priorities;
for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
unsigned j;
u32 pri;
for (j = 0, pri = 0; j < 32; j += 4, priority++)
pri |= (*priority & 0x07) << j;
davinci_irq_writel(pri, i);
}
/* set up genirq dispatch for ARM INTC */
for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
set_irq_chip(i, &davinci_irq_chip_0);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
if (i != IRQ_TINT1_TINT34)
set_irq_handler(i, handle_edge_irq);
else
set_irq_handler(i, handle_level_irq);
}
}
......@@ -14,7 +14,7 @@
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* GIVEN:
* IRQ Entry Table Base Address
* EABASE = 0 ... so IRQNR = (IRQENTRY/4) - 1
* RETURN:
* irqnr: Interrupt number. Zero corresponds
* to bit 0 of the status register
......@@ -24,11 +24,9 @@
*/
ldr \base, =IO_ADDRESS(DAVINCI_ARM_INTC_BASE)
ldr \tmp, [\base, #0x14]
ldr \irqstat, =DAVINCI_IRAM_VIRT
add \tmp, \irqstat, \tmp
ldr \irqnr, [\tmp]
ldr \irqstat, =0xFFFFFFFF
cmp \irqnr, \irqstat
mov \tmp, \tmp, lsr #2
sub \irqnr, \tmp, #1
cmp \tmp, #0
.endm
.macro irq_prio_table
......
......@@ -43,28 +43,28 @@
#define IRQ_H3AINT 4
#define IRQ_PRVUINT 5
#define IRQ_RSZINT 6
#define IRQ_VFOCINT 7
//#define IRQ_VFOCINT 7
#define IRQ_VENCINT 8
#define IRQ_ASQINT 9
#define IRQ_IMXINT 10
#define IRQ_VLCDINT 11
#define IRQ_USBINT 12
#define IRQ_EMACINT 13
#define IRQ_IEEE1394INT 14
#define IRQ_IEEE1394WK 15
//#define IRQ_IEEE1394INT 14
//#define IRQ_IEEE1394WK 15
#define IRQ_CCINT0 16
#define IRQ_CCERRINT 17
#define IRQ_TCERRINT0 18
#define IRQ_TCERRINT 19
#define IRQ_PSCIN 20
#define IRQ_RESERVED 21
//#define IRQ_RESERVED 21
#define IRQ_IDE 22
#define IRQ_HPIINT 23
//#define IRQ_HPIINT 23
#define IRQ_MBXINT 24
#define IRQ_MBRINT 25
#define IRQ_MMCINT 26
#define IRQ_SDIOINT 27
#define IRQ_MSINT 28
//#define IRQ_MSINT 28
#define IRQ_DDRINT 29
#define IRQ_AEMIFINT 30
#define IRQ_VLQINT 31
......@@ -81,7 +81,7 @@
#define IRQ_UARTINT2 42
#define IRQ_SPINT0 43
#define IRQ_SPINT1 44
#define IRQ_RESERVED_2 45
//#define IRQ_RESERVED_2 45
#define IRQ_DSP2ARM0 46
#define IRQ_DSP2ARM1 47
#define IRQ_GPIO0 48
......@@ -111,7 +111,8 @@
#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
#ifndef __ASSEMBLY__
extern void davinci_irq_init(void);
extern void
davinci_irq_init(const unsigned char priority[DAVINCI_N_AINTC_IRQ]);
#endif
#endif /* __ASM_ARCH_IRQS_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment