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

Commit 39f0fb6a authored by Greg Ungerer's avatar Greg Ungerer
Browse files

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: default avatarGreg Ungerer <gerg@uclinux.org>
parent f6a66276
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -24,11 +24,6 @@
 * interrupt control purposes.
 */

/*
 * Define the base address of the SIM within the MBAR address space.
 */
#define	MCFSIM_BASE		0x0		/* Base address within SIM */

/*
 * Bit definitions for the ICR family of registers.
 */
@@ -48,7 +43,9 @@
#define	MCFSIM_ICR_PRI3		0x03		/* Priority 3 intr */

/*
 * IMR bit position definitions.
 * IMR bit position definitions. Not all ColdFire parts with this interrupt
 * controller actually support all of these interrupt sources. But the bit
 * numbers are the same in all cores.
 */
#define	MCFINTC_EINT1		1		/* External int #1 */
#define	MCFINTC_EINT2		2		/* External int #2 */
@@ -70,6 +67,19 @@
#define	MCFINTC_QSPI		18

#ifndef __ASSEMBLER__

/*
 * There is no one-is-one correspondance between the interrupt number (irq)
 * and the bit fields on the mask register. So we create a per-cpu type
 * mapping of irq to mask bit. The CPU platform code needs to register
 * its supported irq's at init time, using this function.
 */
extern unsigned char mcf_irq2imr[];
static inline void mcf_mapirq2imr(int irq, int imr)
{
	mcf_irq2imr[irq] = imr;
}

void mcf_autovector(int irq);
void mcf_setimr(int index);
void mcf_clrimr(int index);
+10 −3
Original line number Diff line number Diff line
@@ -49,11 +49,11 @@ static void __init m5206_uart_init_line(int line, int irq)
	if (line == 0) {
		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART0);
		mcf_mapirq2imr(irq, MCFINTC_UART0);
	} else if (line == 1) {
		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART1);
		mcf_mapirq2imr(irq, MCFINTC_UART1);
	}
}

@@ -73,11 +73,13 @@ static void __init m5206_timers_init(void)
	/* Timer1 is always used as system timer */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER1ICR);
	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);

#ifdef CONFIG_HIGHPROFILE
	/* Timer2 is to be used as a high speed profile timer  */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER2ICR);
	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}

@@ -98,13 +100,18 @@ void __init config_BSP(char *commandp, int size)
{
	mach_reset = m5206_cpu_reset;
	m5206_timers_init();
	m5206_uarts_init();

	/* Only support the external interrupts on their primary level */
	mcf_mapirq2imr(25, MCFINTC_EINT1);
	mcf_mapirq2imr(28, MCFINTC_EINT4);
	mcf_mapirq2imr(31, MCFINTC_EINT7);
}

/***************************************************************************/

static int __init init_BSP(void)
{
	m5206_uarts_init();
	platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices));
	return 0;
}
+10 −3
Original line number Diff line number Diff line
@@ -50,11 +50,11 @@ static void __init m5206e_uart_init_line(int line, int irq)
	if (line == 0) {
		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART0);
		mcf_mapirq2imr(irq, MCFINTC_UART0);
	} else if (line == 1) {
		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART1);
		mcf_mapirq2imr(irq, MCFINTC_UART1);
	}
}

@@ -74,11 +74,13 @@ static void __init m5206e_timers_init(void)
	/* Timer1 is always used as system timer */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER1ICR);
	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);

#ifdef CONFIG_HIGHPROFILE
	/* Timer2 is to be used as a high speed profile timer  */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER2ICR);
	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}

@@ -105,13 +107,18 @@ void __init config_BSP(char *commandp, int size)

	mach_reset = m5206e_cpu_reset;
	m5206e_timers_init();
	m5206e_uarts_init();

	/* Only support the external interrupts on their primary level */
	mcf_mapirq2imr(25, MCFINTC_EINT1);
	mcf_mapirq2imr(28, MCFINTC_EINT4);
	mcf_mapirq2imr(31, MCFINTC_EINT7);
}

/***************************************************************************/

static int __init init_BSP(void)
{
	m5206e_uarts_init();
	platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices));
	return 0;
}
+5 −3
Original line number Diff line number Diff line
@@ -48,11 +48,11 @@ static void __init m5249_uart_init_line(int line, int irq)
	if (line == 0) {
		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART0);
		mcf_mapirq2imr(irq, MCFINTC_UART0);
	} else if (line == 1) {
		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART1);
		mcf_mapirq2imr(irq, MCFINTC_UART1);
	}
}

@@ -72,11 +72,13 @@ static void __init m5249_timers_init(void)
	/* Timer1 is always used as system timer */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER1ICR);
	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);

#ifdef CONFIG_HIGHPROFILE
	/* Timer2 is to be used as a high speed profile timer  */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER2ICR);
	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}

@@ -97,13 +99,13 @@ void __init config_BSP(char *commandp, int size)
{
	mach_reset = m5249_cpu_reset;
	m5249_timers_init();
	m5249_uarts_init();
}

/***************************************************************************/

static int __init init_BSP(void)
{
	m5249_uarts_init();
	platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
	return 0;
}
+11 −3
Original line number Diff line number Diff line
@@ -58,11 +58,11 @@ static void __init m5307_uart_init_line(int line, int irq)
	if (line == 0) {
		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART0);
		mcf_mapirq2imr(irq, MCFINTC_UART0);
	} else if (line == 1) {
		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
		mcf_clrimr(MCFINTC_UART1);
		mcf_mapirq2imr(irq, MCFINTC_UART1);
	}
}

@@ -82,11 +82,13 @@ static void __init m5307_timers_init(void)
	/* Timer1 is always used as system timer */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER1ICR);
	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);

#ifdef CONFIG_HIGHPROFILE
	/* Timer2 is to be used as a high speed profile timer  */
	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
		MCF_MBAR + MCFSIM_TIMER2ICR);
	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}

@@ -114,6 +116,13 @@ void __init config_BSP(char *commandp, int size)

	mach_reset = m5307_cpu_reset;
	m5307_timers_init();
	m5307_uarts_init();

	/* Only support the external interrupts on their primary level */
	mcf_mapirq2imr(25, MCFINTC_EINT1);
	mcf_mapirq2imr(27, MCFINTC_EINT3);
	mcf_mapirq2imr(29, MCFINTC_EINT5);
	mcf_mapirq2imr(31, MCFINTC_EINT7);

#ifdef CONFIG_BDM_DISABLE
	/*
@@ -129,7 +138,6 @@ void __init config_BSP(char *commandp, int size)

static int __init init_BSP(void)
{
	m5307_uarts_init();
	platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices));
	return 0;
}
Loading