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

Commit 3108e6ab authored by Linus Walleij's avatar Linus Walleij Committed by Russell King
Browse files

ARM: 7389/2: plat-versatile: modernize FPGA IRQ controller



This does two things to the FPGA IRQ controller in the versatile
family:

- Convert to MULTI_IRQ_HANDLER so we can drop the entry macro
  from the Integrator. The C IRQ handler was inspired from
  arch/arm/common/vic.c, recent bug discovered in this handler was
  accounted for.
- Convert to using IRQ domains so we can get rid of the NO_IRQ
  mess and proceed with device tree and such stuff.

As part of the exercise, bump all the low IRQ numbers on the
Integrator PIC to start from 1 rather than 0, since IRQ 0 is
now NO_IRQ. The Linux IRQ numbers are thus entirely decoupled
from the hardware IRQ numbers in this controller.

I was unable to split this patch. The main reason is the half-done
conversion to device tree in Versatile.

Tested on Integrator/AP and Integrator/CP.

Cc: Grant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarRob Herring <rob.herring@calxeda.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 69964ea4
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -280,6 +280,7 @@ config ARCH_INTEGRATOR
	select NEED_MACH_IO_H
	select NEED_MACH_IO_H
	select NEED_MACH_MEMORY_H
	select NEED_MACH_MEMORY_H
	select SPARSE_IRQ
	select SPARSE_IRQ
	select MULTI_IRQ_HANDLER
	help
	help
	  Support for ARM's Integrator platform.
	  Support for ARM's Integrator platform.


+0 −39
Original line number Original line Diff line number Diff line
/*
 * arch/arm/mach-integrator/include/mach/entry-macro.S
 *
 * Low-level IRQ helper macros for Integrator platforms
 *
 * This file is licensed under  the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */
#include <mach/hardware.h>
#include <mach/platform.h>
#include <mach/irqs.h>

		.macro  get_irqnr_preamble, base, tmp
		.endm

		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
/* FIXME: should not be using soo many LDRs here */
		ldr	\base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
		mov	\irqnr, #IRQ_PIC_START
		ldr	\irqstat, [\base, #IRQ_STATUS]		@ get masked status
		ldr	\base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
		teq	\irqstat, #0
		ldreq	\irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
		moveq	\irqnr, #IRQ_CIC_START

1001:		tst	\irqstat, #15
		bne	1002f
		add	\irqnr, \irqnr, #4
		movs	\irqstat, \irqstat, lsr #4
		bne	1001b
1002:		tst	\irqstat, #1
		bne	1003f
		add	\irqnr, \irqnr, #1
		movs	\irqstat, \irqstat, lsr #1
		bne	1002b
1003:		/* EQ will be set if no irqs pending */
		.endm
+31 −32
Original line number Original line Diff line number Diff line
@@ -22,37 +22,37 @@
/* 
/* 
 *  Interrupt numbers
 *  Interrupt numbers
 */
 */
#define IRQ_PIC_START			0
#define IRQ_PIC_START			1
#define IRQ_SOFTINT			0
#define IRQ_SOFTINT			1
#define IRQ_UARTINT0			1
#define IRQ_UARTINT0			2
#define IRQ_UARTINT1			2
#define IRQ_UARTINT1			3
#define IRQ_KMIINT0			3
#define IRQ_KMIINT0			4
#define IRQ_KMIINT1			4
#define IRQ_KMIINT1			5
#define IRQ_TIMERINT0			5
#define IRQ_TIMERINT0			6
#define IRQ_TIMERINT1			6
#define IRQ_TIMERINT1			7
#define IRQ_TIMERINT2			7
#define IRQ_TIMERINT2			8
#define IRQ_RTCINT			8
#define IRQ_RTCINT			9
#define IRQ_AP_EXPINT0			9
#define IRQ_AP_EXPINT0			10
#define IRQ_AP_EXPINT1			10
#define IRQ_AP_EXPINT1			11
#define IRQ_AP_EXPINT2			11
#define IRQ_AP_EXPINT2			12
#define IRQ_AP_EXPINT3			12
#define IRQ_AP_EXPINT3			13
#define IRQ_AP_PCIINT0			13
#define IRQ_AP_PCIINT0			14
#define IRQ_AP_PCIINT1			14
#define IRQ_AP_PCIINT1			15
#define IRQ_AP_PCIINT2			15
#define IRQ_AP_PCIINT2			16
#define IRQ_AP_PCIINT3			16
#define IRQ_AP_PCIINT3			17
#define IRQ_AP_V3INT			17
#define IRQ_AP_V3INT			18
#define IRQ_AP_CPINT0			18
#define IRQ_AP_CPINT0			19
#define IRQ_AP_CPINT1			19
#define IRQ_AP_CPINT1			20
#define IRQ_AP_LBUSTIMEOUT 		20
#define IRQ_AP_LBUSTIMEOUT 		21
#define IRQ_AP_APCINT			21
#define IRQ_AP_APCINT			22
#define IRQ_CP_CLCDCINT			22
#define IRQ_CP_CLCDCINT			23
#define IRQ_CP_MMCIINT0			23
#define IRQ_CP_MMCIINT0			24
#define IRQ_CP_MMCIINT1			24
#define IRQ_CP_MMCIINT1			25
#define IRQ_CP_AACIINT			25
#define IRQ_CP_AACIINT			26
#define IRQ_CP_CPPLDINT			26
#define IRQ_CP_CPPLDINT			27
#define IRQ_CP_ETHINT			27
#define IRQ_CP_ETHINT			28
#define IRQ_CP_TSPENINT			28
#define IRQ_CP_TSPENINT			29
#define IRQ_PIC_END			31
#define IRQ_PIC_END			29


#define IRQ_CIC_START			32
#define IRQ_CIC_START			32
#define IRQ_CM_SOFTINT			32
#define IRQ_CM_SOFTINT			32
@@ -80,4 +80,3 @@


#define NR_IRQS_INTEGRATOR_AP		34
#define NR_IRQS_INTEGRATOR_AP		34
#define NR_IRQS_INTEGRATOR_CP		47
#define NR_IRQS_INTEGRATOR_CP		47
+3 −7
Original line number Original line Diff line number Diff line
@@ -162,12 +162,6 @@ static void __init ap_map_io(void)


#define INTEGRATOR_SC_VALID_INT	0x003fffff
#define INTEGRATOR_SC_VALID_INT	0x003fffff


static struct fpga_irq_data sc_irq_data = {
	.base		= VA_IC_BASE,
	.irq_start	= 0,
	.chip.name	= "SC",
};

static void __init ap_init_irq(void)
static void __init ap_init_irq(void)
{
{
	/* Disable all interrupts initially. */
	/* Disable all interrupts initially. */
@@ -178,7 +172,8 @@ static void __init ap_init_irq(void)
	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);


	fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data);
	fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
		-1, INTEGRATOR_SC_VALID_INT, NULL);
}
}


#ifdef CONFIG_PM
#ifdef CONFIG_PM
@@ -478,6 +473,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
	.nr_irqs	= NR_IRQS_INTEGRATOR_AP,
	.nr_irqs	= NR_IRQS_INTEGRATOR_AP,
	.init_early	= integrator_init_early,
	.init_early	= integrator_init_early,
	.init_irq	= ap_init_irq,
	.init_irq	= ap_init_irq,
	.handle_irq	= fpga_handle_irq,
	.timer		= &ap_timer,
	.timer		= &ap_timer,
	.init_machine	= ap_init,
	.init_machine	= ap_init,
	.restart	= integrator_restart,
	.restart	= integrator_restart,
+10 −23
Original line number Original line Diff line number Diff line
@@ -143,30 +143,14 @@ static void __init intcp_map_io(void)
	iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
	iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
}
}


static struct fpga_irq_data cic_irq_data = {
	.base		= INTCP_VA_CIC_BASE,
	.irq_start	= IRQ_CIC_START,
	.chip.name	= "CIC",
};

static struct fpga_irq_data pic_irq_data = {
	.base		= INTCP_VA_PIC_BASE,
	.irq_start	= IRQ_PIC_START,
	.chip.name	= "PIC",
};

static struct fpga_irq_data sic_irq_data = {
	.base		= INTCP_VA_SIC_BASE,
	.irq_start	= IRQ_SIC_START,
	.chip.name	= "SIC",
};

static void __init intcp_init_irq(void)
static void __init intcp_init_irq(void)
{
{
	u32 pic_mask, sic_mask;
	u32 pic_mask, cic_mask, sic_mask;


	/* These masks are for the HW IRQ registers */
	pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
	pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
	pic_mask |= (~((~0u) << (29 - 22))) << 22;
	pic_mask |= (~((~0u) << (29 - 22))) << 22;
	cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
	sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
	sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));


	/*
	/*
@@ -179,12 +163,14 @@ static void __init intcp_init_irq(void)
	writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
	writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
	writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
	writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);


	fpga_irq_init(-1, pic_mask, &pic_irq_data);
	fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
		      -1, pic_mask, NULL);


	fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)),
	fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
		&cic_irq_data);
		      -1, cic_mask, NULL);


	fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data);
	fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
		      IRQ_CP_CPPLDINT, sic_mask, NULL);
}
}


/*
/*
@@ -467,6 +453,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
	.nr_irqs	= NR_IRQS_INTEGRATOR_CP,
	.nr_irqs	= NR_IRQS_INTEGRATOR_CP,
	.init_early	= intcp_init_early,
	.init_early	= intcp_init_early,
	.init_irq	= intcp_init_irq,
	.init_irq	= intcp_init_irq,
	.handle_irq	= fpga_handle_irq,
	.timer		= &cp_timer,
	.timer		= &cp_timer,
	.init_machine	= intcp_init,
	.init_machine	= intcp_init,
	.restart	= integrator_restart,
	.restart	= integrator_restart,
Loading