Skip to content

Commit

Permalink
mxc irq: make architecture runtime dependent
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sascha Hauer committed May 7, 2009
1 parent ec996ba commit 84c9fa4
Showing 1 changed file with 39 additions and 35 deletions.
74 changes: 39 additions & 35 deletions arch/arm/plat-mxc/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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 = {
Expand All @@ -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);
Expand All @@ -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();
Expand All @@ -149,3 +152,4 @@ void __init mxc_init_irq(void)

printk(KERN_INFO "MXC IRQ initialized\n");
}

0 comments on commit 84c9fa4

Please sign in to comment.