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>
This commit is contained in:
@@ -30,13 +30,6 @@
|
|||||||
#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */
|
#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */
|
||||||
#define MCFSIM_ICR_PRI(p) (p) /* Priority p 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
|
#ifdef MCFICM_INTC1
|
||||||
#define NR_VECS 128
|
#define NR_VECS 128
|
||||||
#else
|
#else
|
||||||
@@ -64,25 +57,21 @@ static void intc_irq_mask(struct irq_data *d)
|
|||||||
static void intc_irq_unmask(struct irq_data *d)
|
static void intc_irq_unmask(struct irq_data *d)
|
||||||
{
|
{
|
||||||
unsigned int irq = d->irq - MCFINT_VECBASE;
|
unsigned int irq = d->irq - MCFINT_VECBASE;
|
||||||
unsigned long intaddr, imraddr, icraddr;
|
unsigned long imraddr;
|
||||||
u32 val, imrbit;
|
u32 val, imrbit;
|
||||||
|
|
||||||
#ifdef MCFICM_INTC1
|
#ifdef MCFICM_INTC1
|
||||||
intaddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
|
imraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
|
||||||
#else
|
#else
|
||||||
intaddr = MCFICM_INTC0;
|
imraddr = MCFICM_INTC0;
|
||||||
#endif
|
#endif
|
||||||
imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
|
imraddr += ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
|
||||||
icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
|
|
||||||
imrbit = 0x1 << (irq & 0x1f);
|
imrbit = 0x1 << (irq & 0x1f);
|
||||||
|
|
||||||
/* Don't set the "maskall" bit! */
|
/* Don't set the "maskall" bit! */
|
||||||
if ((irq & 0x20) == 0)
|
if ((irq & 0x20) == 0)
|
||||||
imrbit |= 0x1;
|
imrbit |= 0x1;
|
||||||
|
|
||||||
if (__raw_readb(icraddr) == 0)
|
|
||||||
__raw_writeb(intc_intpri--, icraddr);
|
|
||||||
|
|
||||||
val = __raw_readl(imraddr);
|
val = __raw_readl(imraddr);
|
||||||
__raw_writel(val & ~imrbit, 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;
|
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 = {
|
static struct irq_chip intc_irq_chip = {
|
||||||
.name = "CF-INTC",
|
.name = "CF-INTC",
|
||||||
|
.irq_startup = intc_irq_startup,
|
||||||
.irq_mask = intc_irq_mask,
|
.irq_mask = intc_irq_mask,
|
||||||
.irq_unmask = intc_irq_unmask,
|
.irq_unmask = intc_irq_unmask,
|
||||||
.irq_set_type = intc_irq_set_type,
|
.irq_set_type = intc_irq_set_type,
|
||||||
|
Reference in New Issue
Block a user