Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d0f33fa authored by Greg Ungerer's avatar Greg Ungerer
Browse files

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: default avatarGreg Ungerer <gerg@uclinux.org>
parent 49bc6dea
Loading
Loading
Loading
Loading
+32 −15
Original line number Diff line number Diff line
@@ -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,