mxc irq: make architecture runtime dependent

Currently we depend on hardcoded base addresses for the interrupt
controller. This prevents us from compiling in more than one i.MX
architecture at a time. This patch changes the base address to a
runtime calculated one.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2009-02-18 20:59:04 +01:00
parent ec996ba9b5
commit 84c9fa4304
1 changed files with 39 additions and 35 deletions

View File

@ -24,26 +24,27 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR)
#define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */
#define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */
#define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */
#define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */
#define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */
#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */
#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */
#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */
#define AVIC_NIPRIORITY(x) (AVIC_BASE + (0x20 + 4 * (7 - (x)))) /* int priority */
#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */
#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */
#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */
#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */
#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */
#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */
#define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */
#define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */
#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */
#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */
#define AVIC_INTCNTL 0x00 /* int control reg */
#define AVIC_NIMASK 0x04 /* int mask reg */
#define AVIC_INTENNUM 0x08 /* int enable number reg */
#define AVIC_INTDISNUM 0x0C /* int disable number reg */
#define AVIC_INTENABLEH 0x10 /* int enable reg high */
#define AVIC_INTENABLEL 0x14 /* int enable reg low */
#define AVIC_INTTYPEH 0x18 /* int type reg high */
#define AVIC_INTTYPEL 0x1C /* int type reg low */
#define AVIC_NIPRIORITY(x) (0x20 + 4 * (7 - (x))) /* int priority */
#define AVIC_NIVECSR 0x40 /* norm int vector/status */
#define AVIC_FIVECSR 0x44 /* fast int vector/status */
#define AVIC_INTSRCH 0x48 /* int source reg high */
#define AVIC_INTSRCL 0x4C /* int source reg low */
#define AVIC_INTFRCH 0x50 /* int force reg high */
#define AVIC_INTFRCL 0x54 /* int force reg low */
#define AVIC_NIPNDH 0x58 /* norm int pending high */
#define AVIC_NIPNDL 0x5C /* norm int pending low */
#define AVIC_FIPNDH 0x60 /* fast int pending high */
#define AVIC_FIPNDL 0x64 /* fast int pending low */
static void __iomem *avic_base;
int imx_irq_set_priority(unsigned char irq, unsigned char prio)
{
@ -54,11 +55,11 @@ int imx_irq_set_priority(unsigned char irq, unsigned char prio)
if (irq >= MXC_INTERNAL_IRQS)
return -EINVAL;;
temp = __raw_readl(AVIC_NIPRIORITY(irq / 8));
temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8));
temp &= ~mask;
temp |= prio & mask;
__raw_writel(temp, AVIC_NIPRIORITY(irq / 8));
__raw_writel(temp, avic_base + AVIC_NIPRIORITY(irq / 8));
return 0;
#else
@ -76,12 +77,12 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
return -EINVAL;
if (irq < MXC_INTERNAL_IRQS / 2) {
irqt = __raw_readl(AVIC_INTTYPEL) & ~(1 << irq);
__raw_writel(irqt | (!!type << irq), AVIC_INTTYPEL);
irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq);
__raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL);
} else {
irq -= MXC_INTERNAL_IRQS / 2;
irqt = __raw_readl(AVIC_INTTYPEH) & ~(1 << irq);
__raw_writel(irqt | (!!type << irq), AVIC_INTTYPEH);
irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq);
__raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH);
}
return 0;
@ -92,13 +93,13 @@ EXPORT_SYMBOL(mxc_set_irq_fiq);
/* Disable interrupt number "irq" in the AVIC */
static void mxc_mask_irq(unsigned int irq)
{
__raw_writel(irq, AVIC_INTDISNUM);
__raw_writel(irq, avic_base + AVIC_INTDISNUM);
}
/* Enable interrupt number "irq" in the AVIC */
static void mxc_unmask_irq(unsigned int irq)
{
__raw_writel(irq, AVIC_INTENNUM);
__raw_writel(irq, avic_base + AVIC_INTENNUM);
}
static struct irq_chip mxc_avic_chip = {
@ -116,19 +117,21 @@ void __init mxc_init_irq(void)
{
int i;
avic_base = IO_ADDRESS(AVIC_BASE_ADDR);
/* put the AVIC into the reset value with
* all interrupts disabled
*/
__raw_writel(0, AVIC_INTCNTL);
__raw_writel(0x1f, AVIC_NIMASK);
__raw_writel(0, avic_base + AVIC_INTCNTL);
__raw_writel(0x1f, avic_base + AVIC_NIMASK);
/* disable all interrupts */
__raw_writel(0, AVIC_INTENABLEH);
__raw_writel(0, AVIC_INTENABLEL);
__raw_writel(0, avic_base + AVIC_INTENABLEH);
__raw_writel(0, avic_base + AVIC_INTENABLEL);
/* all IRQ no FIQ */
__raw_writel(0, AVIC_INTTYPEH);
__raw_writel(0, AVIC_INTTYPEL);
__raw_writel(0, avic_base + AVIC_INTTYPEH);
__raw_writel(0, avic_base + AVIC_INTTYPEL);
for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
set_irq_chip(i, &mxc_avic_chip);
set_irq_handler(i, handle_level_irq);
@ -137,7 +140,7 @@ void __init mxc_init_irq(void)
/* Set default priority value (0) for all IRQ's */
for (i = 0; i < 8; i++)
__raw_writel(0, AVIC_NIPRIORITY(i));
__raw_writel(0, avic_base + AVIC_NIPRIORITY(i));
/* init architectures chained interrupt handler */
mxc_register_gpios();
@ -149,3 +152,4 @@ void __init mxc_init_irq(void)
printk(KERN_INFO "MXC IRQ initialized\n");
}