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:
Родитель
49bc6deace
Коммит
6d0f33fa80
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче