summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2011-03-07 10:42:28 +0300
committerGreg Ungerer <gerg@uclinux.org>2011-03-15 14:01:55 +0300
commit6d0f33fa80ed530168161fd2f226a3e5cf27cf81 (patch)
tree487daf5e2d049608ece6291bfd2dc594e0ef9e28
parent49bc6deace5a0a774678212097474b27b27e44fb (diff)
downloadlinux-6d0f33fa80ed530168161fd2f226a3e5cf27cf81.tar.xz
m68knommu: move some init code out of unmask routine for ColdFire intc-2
Use a proper irq_startup() routine to intialize the interrupt priority and level register in the ColdFire intc-2 controller code. We shouldn't be checking if the priority/level has been set on every unmask operation. Signed-off-by: Greg Ungerer <gerg@uclinux.org>
-rw-r--r--arch/m68knommu/platform/coldfire/intc-2.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
index 4d172a7a6fbc..66d4e47dd8d0 100644
--- a/arch/m68knommu/platform/coldfire/intc-2.c
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -30,13 +30,6 @@
#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */
#define MCFSIM_ICR_PRI(p) (p) /* Priority p intr */
-/*
- * Each vector needs a unique priority and level associated with it.
- * We don't really care so much what they are, we don't rely on the
- * traditional priority interrupt scheme of the m68k/ColdFire.
- */
-static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
-
#ifdef MCFICM_INTC1
#define NR_VECS 128
#else
@@ -64,25 +57,21 @@ static void intc_irq_mask(struct irq_data *d)
static void intc_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - MCFINT_VECBASE;
- unsigned long intaddr, imraddr, icraddr;
+ unsigned long imraddr;
u32 val, imrbit;
#ifdef MCFICM_INTC1
- intaddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+ imraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
#else
- intaddr = MCFICM_INTC0;
+ imraddr = MCFICM_INTC0;
#endif
- imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
- icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
+ imraddr += ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
imrbit = 0x1 << (irq & 0x1f);
/* Don't set the "maskall" bit! */
if ((irq & 0x20) == 0)
imrbit |= 0x1;
- if (__raw_readb(icraddr) == 0)
- __raw_writeb(intc_intpri--, icraddr);
-
val = __raw_readl(imraddr);
__raw_writel(val & ~imrbit, imraddr);
}
@@ -92,8 +81,36 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type)
return 0;
}
+/*
+ * Each vector needs a unique priority and level associated with it.
+ * We don't really care so much what they are, we don't rely on the
+ * traditional priority interrupt scheme of the m68k/ColdFire. This
+ * only needs to be set once for an interrupt, and we will never change
+ * these values once we have set them.
+ */
+static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
+
+static unsigned int intc_irq_startup(struct irq_data *d)
+{
+ unsigned int irq = d->irq - MCFINT_VECBASE;
+ unsigned long icraddr;
+
+#ifdef MCFICM_INTC1
+ icraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+#else
+ icraddr = MCFICM_INTC0;
+#endif
+ icraddr += MCFINTC_ICR0 + (irq & 0x3f);
+ if (__raw_readb(icraddr) == 0)
+ __raw_writeb(intc_intpri--, icraddr);
+
+ intc_irq_unmask(d);
+ return 0;
+}
+
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
+ .irq_startup = intc_irq_startup,
.irq_mask = intc_irq_mask,
.irq_unmask = intc_irq_unmask,
.irq_set_type = intc_irq_set_type,