summaryrefslogtreecommitdiffstats
path: root/arch/m68knommu/platform/coldfire/intc.c
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2009-05-22 13:33:35 +1000
committerGreg Ungerer <gerg@uclinux.org>2009-09-16 09:43:52 +1000
commit39f0fb6a3448cfc316e0d5295ed1b121db50037e (patch)
tree657db8073835e8d499708a898a36f1d3a1e39a32 /arch/m68knommu/platform/coldfire/intc.c
parentf6a66276f5fdc018d2a9378c71de3bae13c588d7 (diff)
m68knommu: map ColdFire interrupts to correct masking bits
The older simple ColdFire interrupt controller has no one-to-one mapping of interrupt numbers to bits in the interrupt mask register. Create a mapping array that each ColdFire CPU type can populate with its available interrupts and the bits that each use in the interrupt mask register. Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Diffstat (limited to 'arch/m68knommu/platform/coldfire/intc.c')
-rw-r--r--arch/m68knommu/platform/coldfire/intc.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
index 14db26bf6e2..a4560c86db7 100644
--- a/arch/m68knommu/platform/coldfire/intc.c
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -19,9 +19,17 @@
#include <asm/mcfsim.h>
/*
- * Define the vector numbers for the basic 7 interrupt sources.
- * These are often referred to as the "external" interrupts in
- * the ColdFire documentation (for the early ColdFire cores at least).
+ * The mapping of irq number to a mask register bit is not one-to-one.
+ * The irq numbers are either based on "level" of interrupt or fixed
+ * for an autovector-able interrupt. So we keep a local data structure
+ * that maps from irq to mask register. Not all interrupts will have
+ * an IMR bit.
+ */
+unsigned char mcf_irq2imr[NR_IRQS];
+
+/*
+ * Define the miniumun and maximum external interrupt numbers.
+ * This is also used as the "level" interrupt numbers.
*/
#define EIRQ1 25
#define EIRQ7 31
@@ -36,22 +44,22 @@
void mcf_setimr(int index)
{
- u16 imr;
- imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+ u16 imr;
+ imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
__raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_clrimr(int index)
{
- u16 imr;
- imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+ u16 imr;
+ imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
__raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_maskimr(unsigned int mask)
{
u16 imr;
- imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
imr |= mask;
__raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
}
@@ -60,22 +68,22 @@ void mcf_maskimr(unsigned int mask)
void mcf_setimr(int index)
{
- u32 imr;
- imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+ u32 imr;
+ imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
__raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_clrimr(int index)
{
- u32 imr;
- imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+ u32 imr;
+ imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
__raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_maskimr(unsigned int mask)
{
u32 imr;
- imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
imr |= mask;
__raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
}
@@ -93,24 +101,26 @@ void mcf_maskimr(unsigned int mask)
*/
void mcf_autovector(int irq)
{
+#ifdef MCFSIM_AVR
if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
u8 avec;
avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
avec |= (0x1 << (irq - EIRQ1 + 1));
__raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
}
+#endif
}
static void intc_irq_mask(unsigned int irq)
{
- if ((irq >= EIRQ1) && (irq <= EIRQ7))
- mcf_setimr(irq - EIRQ1 + 1);
+ if (mcf_irq2imr[irq])
+ mcf_setimr(mcf_irq2imr[irq]);
}
static void intc_irq_unmask(unsigned int irq)
{
- if ((irq >= EIRQ1) && (irq <= EIRQ7))
- mcf_clrimr(irq - EIRQ1 + 1);
+ if (mcf_irq2imr[irq])
+ mcf_clrimr(mcf_irq2imr[irq]);
}
static int intc_irq_set_type(unsigned int irq, unsigned int type)