diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2012-04-28 09:33:47 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-05-04 11:53:37 -0400 |
commit | 3108e6ab21a9b9dbd88f0b2ff99f73e95b8b1580 (patch) | |
tree | 9e87e1e4196849090103317d109dc95ba9d159f8 /arch/arm/mach-integrator | |
parent | 69964ea4c7b68c9399f7977aa5b9aa6539a6a98a (diff) |
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: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r-- | arch/arm/mach-integrator/include/mach/entry-macro.S | 39 | ||||
-rw-r--r-- | arch/arm/mach-integrator/include/mach/irqs.h | 63 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 33 |
4 files changed, 44 insertions, 101 deletions
diff --git a/arch/arm/mach-integrator/include/mach/entry-macro.S b/arch/arm/mach-integrator/include/mach/entry-macro.S deleted file mode 100644 index 5cc7b85ad9df..000000000000 --- a/arch/arm/mach-integrator/include/mach/entry-macro.S +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-integrator/include/mach/entry-macro.S | ||
3 | * | ||
4 | * Low-level IRQ helper macros for Integrator platforms | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | #include <mach/hardware.h> | ||
11 | #include <mach/platform.h> | ||
12 | #include <mach/irqs.h> | ||
13 | |||
14 | .macro get_irqnr_preamble, base, tmp | ||
15 | .endm | ||
16 | |||
17 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
18 | /* FIXME: should not be using soo many LDRs here */ | ||
19 | ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE) | ||
20 | mov \irqnr, #IRQ_PIC_START | ||
21 | ldr \irqstat, [\base, #IRQ_STATUS] @ get masked status | ||
22 | ldr \base, =IO_ADDRESS(INTEGRATOR_HDR_BASE) | ||
23 | teq \irqstat, #0 | ||
24 | ldreq \irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] | ||
25 | moveq \irqnr, #IRQ_CIC_START | ||
26 | |||
27 | 1001: tst \irqstat, #15 | ||
28 | bne 1002f | ||
29 | add \irqnr, \irqnr, #4 | ||
30 | movs \irqstat, \irqstat, lsr #4 | ||
31 | bne 1001b | ||
32 | 1002: tst \irqstat, #1 | ||
33 | bne 1003f | ||
34 | add \irqnr, \irqnr, #1 | ||
35 | movs \irqstat, \irqstat, lsr #1 | ||
36 | bne 1002b | ||
37 | 1003: /* EQ will be set if no irqs pending */ | ||
38 | .endm | ||
39 | |||
diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h index a19a1a2fcf6b..7371018455d2 100644 --- a/arch/arm/mach-integrator/include/mach/irqs.h +++ b/arch/arm/mach-integrator/include/mach/irqs.h | |||
@@ -22,37 +22,37 @@ | |||
22 | /* | 22 | /* |
23 | * Interrupt numbers | 23 | * Interrupt numbers |
24 | */ | 24 | */ |
25 | #define IRQ_PIC_START 0 | 25 | #define IRQ_PIC_START 1 |
26 | #define IRQ_SOFTINT 0 | 26 | #define IRQ_SOFTINT 1 |
27 | #define IRQ_UARTINT0 1 | 27 | #define IRQ_UARTINT0 2 |
28 | #define IRQ_UARTINT1 2 | 28 | #define IRQ_UARTINT1 3 |
29 | #define IRQ_KMIINT0 3 | 29 | #define IRQ_KMIINT0 4 |
30 | #define IRQ_KMIINT1 4 | 30 | #define IRQ_KMIINT1 5 |
31 | #define IRQ_TIMERINT0 5 | 31 | #define IRQ_TIMERINT0 6 |
32 | #define IRQ_TIMERINT1 6 | 32 | #define IRQ_TIMERINT1 7 |
33 | #define IRQ_TIMERINT2 7 | 33 | #define IRQ_TIMERINT2 8 |
34 | #define IRQ_RTCINT 8 | 34 | #define IRQ_RTCINT 9 |
35 | #define IRQ_AP_EXPINT0 9 | 35 | #define IRQ_AP_EXPINT0 10 |
36 | #define IRQ_AP_EXPINT1 10 | 36 | #define IRQ_AP_EXPINT1 11 |
37 | #define IRQ_AP_EXPINT2 11 | 37 | #define IRQ_AP_EXPINT2 12 |
38 | #define IRQ_AP_EXPINT3 12 | 38 | #define IRQ_AP_EXPINT3 13 |
39 | #define IRQ_AP_PCIINT0 13 | 39 | #define IRQ_AP_PCIINT0 14 |
40 | #define IRQ_AP_PCIINT1 14 | 40 | #define IRQ_AP_PCIINT1 15 |
41 | #define IRQ_AP_PCIINT2 15 | 41 | #define IRQ_AP_PCIINT2 16 |
42 | #define IRQ_AP_PCIINT3 16 | 42 | #define IRQ_AP_PCIINT3 17 |
43 | #define IRQ_AP_V3INT 17 | 43 | #define IRQ_AP_V3INT 18 |
44 | #define IRQ_AP_CPINT0 18 | 44 | #define IRQ_AP_CPINT0 19 |
45 | #define IRQ_AP_CPINT1 19 | 45 | #define IRQ_AP_CPINT1 20 |
46 | #define IRQ_AP_LBUSTIMEOUT 20 | 46 | #define IRQ_AP_LBUSTIMEOUT 21 |
47 | #define IRQ_AP_APCINT 21 | 47 | #define IRQ_AP_APCINT 22 |
48 | #define IRQ_CP_CLCDCINT 22 | 48 | #define IRQ_CP_CLCDCINT 23 |
49 | #define IRQ_CP_MMCIINT0 23 | 49 | #define IRQ_CP_MMCIINT0 24 |
50 | #define IRQ_CP_MMCIINT1 24 | 50 | #define IRQ_CP_MMCIINT1 25 |
51 | #define IRQ_CP_AACIINT 25 | 51 | #define IRQ_CP_AACIINT 26 |
52 | #define IRQ_CP_CPPLDINT 26 | 52 | #define IRQ_CP_CPPLDINT 27 |
53 | #define IRQ_CP_ETHINT 27 | 53 | #define IRQ_CP_ETHINT 28 |
54 | #define IRQ_CP_TSPENINT 28 | 54 | #define IRQ_CP_TSPENINT 29 |
55 | #define IRQ_PIC_END 31 | 55 | #define IRQ_PIC_END 29 |
56 | 56 | ||
57 | #define IRQ_CIC_START 32 | 57 | #define IRQ_CIC_START 32 |
58 | #define IRQ_CM_SOFTINT 32 | 58 | #define IRQ_CM_SOFTINT 32 |
@@ -80,4 +80,3 @@ | |||
80 | 80 | ||
81 | #define NR_IRQS_INTEGRATOR_AP 34 | 81 | #define NR_IRQS_INTEGRATOR_AP 34 |
82 | #define NR_IRQS_INTEGRATOR_CP 47 | 82 | #define NR_IRQS_INTEGRATOR_CP 47 |
83 | |||
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 871f148ffd72..c857501c5783 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -162,12 +162,6 @@ static void __init ap_map_io(void) | |||
162 | 162 | ||
163 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | 163 | #define INTEGRATOR_SC_VALID_INT 0x003fffff |
164 | 164 | ||
165 | static struct fpga_irq_data sc_irq_data = { | ||
166 | .base = VA_IC_BASE, | ||
167 | .irq_start = 0, | ||
168 | .chip.name = "SC", | ||
169 | }; | ||
170 | |||
171 | static void __init ap_init_irq(void) | 165 | static void __init ap_init_irq(void) |
172 | { | 166 | { |
173 | /* Disable all interrupts initially. */ | 167 | /* Disable all interrupts initially. */ |
@@ -178,7 +172,8 @@ static void __init ap_init_irq(void) | |||
178 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | 172 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); |
179 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | 173 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); |
180 | 174 | ||
181 | fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data); | 175 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, |
176 | -1, INTEGRATOR_SC_VALID_INT, NULL); | ||
182 | } | 177 | } |
183 | 178 | ||
184 | #ifdef CONFIG_PM | 179 | #ifdef CONFIG_PM |
@@ -478,6 +473,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") | |||
478 | .nr_irqs = NR_IRQS_INTEGRATOR_AP, | 473 | .nr_irqs = NR_IRQS_INTEGRATOR_AP, |
479 | .init_early = integrator_init_early, | 474 | .init_early = integrator_init_early, |
480 | .init_irq = ap_init_irq, | 475 | .init_irq = ap_init_irq, |
476 | .handle_irq = fpga_handle_irq, | ||
481 | .timer = &ap_timer, | 477 | .timer = &ap_timer, |
482 | .init_machine = ap_init, | 478 | .init_machine = ap_init, |
483 | .restart = integrator_restart, | 479 | .restart = integrator_restart, |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 48a115a91d9d..a56c53608939 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -143,30 +143,14 @@ static void __init intcp_map_io(void) | |||
143 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); | 143 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); |
144 | } | 144 | } |
145 | 145 | ||
146 | static struct fpga_irq_data cic_irq_data = { | ||
147 | .base = INTCP_VA_CIC_BASE, | ||
148 | .irq_start = IRQ_CIC_START, | ||
149 | .chip.name = "CIC", | ||
150 | }; | ||
151 | |||
152 | static struct fpga_irq_data pic_irq_data = { | ||
153 | .base = INTCP_VA_PIC_BASE, | ||
154 | .irq_start = IRQ_PIC_START, | ||
155 | .chip.name = "PIC", | ||
156 | }; | ||
157 | |||
158 | static struct fpga_irq_data sic_irq_data = { | ||
159 | .base = INTCP_VA_SIC_BASE, | ||
160 | .irq_start = IRQ_SIC_START, | ||
161 | .chip.name = "SIC", | ||
162 | }; | ||
163 | |||
164 | static void __init intcp_init_irq(void) | 146 | static void __init intcp_init_irq(void) |
165 | { | 147 | { |
166 | u32 pic_mask, sic_mask; | 148 | u32 pic_mask, cic_mask, sic_mask; |
167 | 149 | ||
150 | /* These masks are for the HW IRQ registers */ | ||
168 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | 151 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); |
169 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | 152 | pic_mask |= (~((~0u) << (29 - 22))) << 22; |
153 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
170 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | 154 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); |
171 | 155 | ||
172 | /* | 156 | /* |
@@ -179,12 +163,14 @@ static void __init intcp_init_irq(void) | |||
179 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | 163 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); |
180 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | 164 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); |
181 | 165 | ||
182 | fpga_irq_init(-1, pic_mask, &pic_irq_data); | 166 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, |
167 | -1, pic_mask, NULL); | ||
183 | 168 | ||
184 | fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)), | 169 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, |
185 | &cic_irq_data); | 170 | -1, cic_mask, NULL); |
186 | 171 | ||
187 | fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data); | 172 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, |
173 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
188 | } | 174 | } |
189 | 175 | ||
190 | /* | 176 | /* |
@@ -467,6 +453,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") | |||
467 | .nr_irqs = NR_IRQS_INTEGRATOR_CP, | 453 | .nr_irqs = NR_IRQS_INTEGRATOR_CP, |
468 | .init_early = intcp_init_early, | 454 | .init_early = intcp_init_early, |
469 | .init_irq = intcp_init_irq, | 455 | .init_irq = intcp_init_irq, |
456 | .handle_irq = fpga_handle_irq, | ||
470 | .timer = &cp_timer, | 457 | .timer = &cp_timer, |
471 | .init_machine = intcp_init, | 458 | .init_machine = intcp_init, |
472 | .restart = integrator_restart, | 459 | .restart = integrator_restart, |