diff options
author | Magnus Damm <damm@opensource.se> | 2010-12-28 03:27:01 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-06 20:42:50 -0500 |
commit | 863b171952dba1a3ce9d345cfe4e93c9fdd42f49 (patch) | |
tree | 8181acaff12a0040ca6e86cfec380f54e4a2fd51 | |
parent | 60f1435c3bab8b88712a4f96806e5ac9396aa49c (diff) |
ARM: mach-shmobile: Run-time IRQ handler for INTCA
Break-out INTC specific IRQ demux code from the file
entry-macro-intc.S and register during run-time.
Covers sh7367, sh7377 and sh7372.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/arm/mach-shmobile/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-g3evm.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-g4evm.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/entry-intc.S | 57 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/common.h | 1 |
7 files changed, 67 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index ab100e4bddd6..e385ef03d5bd 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -18,6 +18,11 @@ pfc-$(CONFIG_ARCH_SH7377) += pfc-sh7377.o | |||
18 | pfc-$(CONFIG_ARCH_SH7372) += pfc-sh7372.o | 18 | pfc-$(CONFIG_ARCH_SH7372) += pfc-sh7372.o |
19 | pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o | 19 | pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o |
20 | 20 | ||
21 | # IRQ objects | ||
22 | obj-$(CONFIG_ARCH_SH7367) += entry-intc.o | ||
23 | obj-$(CONFIG_ARCH_SH7377) += entry-intc.o | ||
24 | obj-$(CONFIG_ARCH_SH7372) += entry-intc.o | ||
25 | |||
21 | # Board objects | 26 | # Board objects |
22 | obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o | 27 | obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o |
23 | obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o | 28 | obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 86edc772f82a..cd79d7c1ba0d 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -1361,6 +1361,7 @@ static struct sys_timer ap4evb_timer = { | |||
1361 | MACHINE_START(AP4EVB, "ap4evb") | 1361 | MACHINE_START(AP4EVB, "ap4evb") |
1362 | .map_io = ap4evb_map_io, | 1362 | .map_io = ap4evb_map_io, |
1363 | .init_irq = sh7372_init_irq, | 1363 | .init_irq = sh7372_init_irq, |
1364 | .handle_irq = shmobile_handle_irq_intc, | ||
1364 | .init_machine = ap4evb_init, | 1365 | .init_machine = ap4evb_init, |
1365 | .timer = &ap4evb_timer, | 1366 | .timer = &ap4evb_timer, |
1366 | MACHINE_END | 1367 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 3b83d6320bec..686b304a7708 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c | |||
@@ -367,6 +367,7 @@ static struct sys_timer g3evm_timer = { | |||
367 | MACHINE_START(G3EVM, "g3evm") | 367 | MACHINE_START(G3EVM, "g3evm") |
368 | .map_io = g3evm_map_io, | 368 | .map_io = g3evm_map_io, |
369 | .init_irq = sh7367_init_irq, | 369 | .init_irq = sh7367_init_irq, |
370 | .handle_irq = shmobile_handle_irq_intc, | ||
370 | .init_machine = g3evm_init, | 371 | .init_machine = g3evm_init, |
371 | .timer = &g3evm_timer, | 372 | .timer = &g3evm_timer, |
372 | MACHINE_END | 373 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 5b3b582ef3f2..c13f01280b7e 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c | |||
@@ -394,6 +394,7 @@ static struct sys_timer g4evm_timer = { | |||
394 | MACHINE_START(G4EVM, "g4evm") | 394 | MACHINE_START(G4EVM, "g4evm") |
395 | .map_io = g4evm_map_io, | 395 | .map_io = g4evm_map_io, |
396 | .init_irq = sh7377_init_irq, | 396 | .init_irq = sh7377_init_irq, |
397 | .handle_irq = shmobile_handle_irq_intc, | ||
397 | .init_machine = g4evm_init, | 398 | .init_machine = g4evm_init, |
398 | .timer = &g4evm_timer, | 399 | .timer = &g4evm_timer, |
399 | MACHINE_END | 400 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 6a5ce9a0dcf3..5bcf5c1e1399 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -1194,6 +1194,7 @@ static struct sys_timer mackerel_timer = { | |||
1194 | MACHINE_START(MACKEREL, "mackerel") | 1194 | MACHINE_START(MACKEREL, "mackerel") |
1195 | .map_io = mackerel_map_io, | 1195 | .map_io = mackerel_map_io, |
1196 | .init_irq = sh7372_init_irq, | 1196 | .init_irq = sh7372_init_irq, |
1197 | .handle_irq = shmobile_handle_irq_intc, | ||
1197 | .init_machine = mackerel_init, | 1198 | .init_machine = mackerel_init, |
1198 | .timer = &mackerel_timer, | 1199 | .timer = &mackerel_timer, |
1199 | MACHINE_END | 1200 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S new file mode 100644 index 000000000000..cac0a7ae2084 --- /dev/null +++ b/arch/arm/mach-shmobile/entry-intc.S | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * ARM Interrupt demux handler using INTC | ||
3 | * | ||
4 | * Copyright (C) 2010 Magnus Damm | ||
5 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <asm/entry-macro-multi.S> | ||
13 | |||
14 | #define INTCA_BASE 0xe6980000 | ||
15 | #define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */ | ||
16 | #define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */ | ||
17 | #define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */ | ||
18 | #define INTLVLB_OFFS 0x00000034 /* previous priority level */ | ||
19 | |||
20 | .macro get_irqnr_preamble, base, tmp | ||
21 | ldr \base, =INTCA_BASE | ||
22 | .endm | ||
23 | |||
24 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
25 | /* The single INTFLGA read access below results in the following: | ||
26 | * | ||
27 | * 1. INTLVLB is updated with old priority value from INTLVLA | ||
28 | * 2. Highest priority interrupt is accepted | ||
29 | * 3. INTLVLA is updated to contain priority of accepted interrupt | ||
30 | * 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA | ||
31 | */ | ||
32 | ldr \irqnr, [\base, #INTFLGA_OFFS] | ||
33 | |||
34 | /* Restore INTLVLA with the value saved in INTLVLB. | ||
35 | * This is required to support interrupt priorities properly. | ||
36 | */ | ||
37 | ldrb \tmp, [\base, #INTLVLB_OFFS] | ||
38 | strb \tmp, [\base, #INTLVLA_OFFS] | ||
39 | |||
40 | /* Handle invalid vector number case */ | ||
41 | cmp \irqnr, #0 | ||
42 | beq 1000f | ||
43 | |||
44 | /* Convert vector to irq number, same as the evt2irq() macro */ | ||
45 | lsr \irqnr, \irqnr, #0x5 | ||
46 | subs \irqnr, \irqnr, #16 | ||
47 | |||
48 | 1000: | ||
49 | .endm | ||
50 | |||
51 | .macro test_for_ipi, irqnr, irqstat, base, tmp | ||
52 | .endm | ||
53 | |||
54 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
55 | .endm | ||
56 | |||
57 | arch_irq_handler shmobile_handle_irq_intc | ||
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 49ac8ebdc184..ab75183bfd76 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h | |||
@@ -5,6 +5,7 @@ extern struct sys_timer shmobile_timer; | |||
5 | extern void shmobile_setup_console(void); | 5 | extern void shmobile_setup_console(void); |
6 | struct clk; | 6 | struct clk; |
7 | extern int clk_init(void); | 7 | extern int clk_init(void); |
8 | extern void shmobile_handle_irq_intc(struct pt_regs *); | ||
8 | 9 | ||
9 | extern void sh7367_init_irq(void); | 10 | extern void sh7367_init_irq(void); |
10 | extern void sh7367_add_early_devices(void); | 11 | extern void sh7367_add_early_devices(void); |