diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2014-04-22 17:26:26 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-04-26 15:45:06 -0400 |
commit | deac3d874ea1e1ef50604cec33ddfb01edb0c976 (patch) | |
tree | 7524fce14d00fb8d76cb56ac453f36517889d3fd | |
parent | 0180ed45da5198e0e7362c56b3a107d3278666f6 (diff) |
ARM: orion: switch to a per-platform handle_irq() function
Moving to the Device Tree implies having CONFIG_MULTI_IRQ_HANDLER
enabled, even for non-DT platforms (if we want both DT and non-DT
platforms to be supported in a single kernel).
However, the common CONFIG_MULTI_IRQ_HANDLER handler for non-DT
platforms in plat-orion/irq.c doesn't match the needs of
Orion5x. Also, it doesn't make much sense for orion_irq_init() to
register the multi-IRQ handler: orion_irq_init() is called once for
each IRQ cause/mask tuple, while the multi-IRQ handler only needs to
be registered once.
To solve this problem, we move the multi-IRQ handle in per-platform
code: mach-kirkwood/irq.c and mach-dove/irq.c. The Orion5x variant
will be introduced in a followup commit. Of course, this code will
ultimately be completely removed once all boards are converted to the
Device Tree.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Link: https://lkml.kernel.org/r/1398202002-28530-23-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r-- | arch/arm/mach-dove/irq.c | 36 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/irq.c | 37 | ||||
-rw-r--r-- | arch/arm/plat-orion/irq.c | 45 |
3 files changed, 73 insertions, 45 deletions
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index bc4344aa1009..4a5a7aedcb76 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c | |||
@@ -108,6 +108,38 @@ static int __initdata gpio2_irqs[4] = { | |||
108 | 0, | 108 | 0, |
109 | }; | 109 | }; |
110 | 110 | ||
111 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
112 | /* | ||
113 | * Compiling with both non-DT and DT support enabled, will | ||
114 | * break asm irq handler used by non-DT boards. Therefore, | ||
115 | * we provide a C-style irq handler even for non-DT boards, | ||
116 | * if MULTI_IRQ_HANDLER is set. | ||
117 | */ | ||
118 | |||
119 | static void __iomem *dove_irq_base = IRQ_VIRT_BASE; | ||
120 | |||
121 | static asmlinkage void | ||
122 | __exception_irq_entry dove_legacy_handle_irq(struct pt_regs *regs) | ||
123 | { | ||
124 | u32 stat; | ||
125 | |||
126 | stat = readl_relaxed(dove_irq_base + IRQ_CAUSE_LOW_OFF); | ||
127 | stat &= readl_relaxed(dove_irq_base + IRQ_MASK_LOW_OFF); | ||
128 | if (stat) { | ||
129 | unsigned int hwirq = __fls(stat); | ||
130 | handle_IRQ(hwirq, regs); | ||
131 | return; | ||
132 | } | ||
133 | stat = readl_relaxed(dove_irq_base + IRQ_CAUSE_HIGH_OFF); | ||
134 | stat &= readl_relaxed(dove_irq_base + IRQ_MASK_HIGH_OFF); | ||
135 | if (stat) { | ||
136 | unsigned int hwirq = 32 + __fls(stat); | ||
137 | handle_IRQ(hwirq, regs); | ||
138 | return; | ||
139 | } | ||
140 | } | ||
141 | #endif | ||
142 | |||
111 | void __init dove_init_irq(void) | 143 | void __init dove_init_irq(void) |
112 | { | 144 | { |
113 | int i; | 145 | int i; |
@@ -115,6 +147,10 @@ void __init dove_init_irq(void) | |||
115 | orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); | 147 | orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); |
116 | orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); | 148 | orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); |
117 | 149 | ||
150 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
151 | set_handle_irq(dove_legacy_handle_irq); | ||
152 | #endif | ||
153 | |||
118 | /* | 154 | /* |
119 | * Initialize gpiolib for GPIOs 0-71. | 155 | * Initialize gpiolib for GPIOs 0-71. |
120 | */ | 156 | */ |
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c index 2a97a2e4163c..2c47a8ad0e27 100644 --- a/arch/arm/mach-kirkwood/irq.c +++ b/arch/arm/mach-kirkwood/irq.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | #include <asm/exception.h> | ||
10 | #include <linux/gpio.h> | 11 | #include <linux/gpio.h> |
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
@@ -30,11 +31,47 @@ static int __initdata gpio1_irqs[4] = { | |||
30 | 0, | 31 | 0, |
31 | }; | 32 | }; |
32 | 33 | ||
34 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
35 | /* | ||
36 | * Compiling with both non-DT and DT support enabled, will | ||
37 | * break asm irq handler used by non-DT boards. Therefore, | ||
38 | * we provide a C-style irq handler even for non-DT boards, | ||
39 | * if MULTI_IRQ_HANDLER is set. | ||
40 | */ | ||
41 | |||
42 | static void __iomem *kirkwood_irq_base = IRQ_VIRT_BASE; | ||
43 | |||
44 | asmlinkage void | ||
45 | __exception_irq_entry kirkwood_legacy_handle_irq(struct pt_regs *regs) | ||
46 | { | ||
47 | u32 stat; | ||
48 | |||
49 | stat = readl_relaxed(kirkwood_irq_base + IRQ_CAUSE_LOW_OFF); | ||
50 | stat &= readl_relaxed(kirkwood_irq_base + IRQ_MASK_LOW_OFF); | ||
51 | if (stat) { | ||
52 | unsigned int hwirq = __fls(stat); | ||
53 | handle_IRQ(hwirq, regs); | ||
54 | return; | ||
55 | } | ||
56 | stat = readl_relaxed(kirkwood_irq_base + IRQ_CAUSE_HIGH_OFF); | ||
57 | stat &= readl_relaxed(kirkwood_irq_base + IRQ_MASK_HIGH_OFF); | ||
58 | if (stat) { | ||
59 | unsigned int hwirq = 32 + __fls(stat); | ||
60 | handle_IRQ(hwirq, regs); | ||
61 | return; | ||
62 | } | ||
63 | } | ||
64 | #endif | ||
65 | |||
33 | void __init kirkwood_init_irq(void) | 66 | void __init kirkwood_init_irq(void) |
34 | { | 67 | { |
35 | orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); | 68 | orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); |
36 | orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); | 69 | orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); |
37 | 70 | ||
71 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
72 | set_handle_irq(kirkwood_legacy_handle_irq); | ||
73 | #endif | ||
74 | |||
38 | /* | 75 | /* |
39 | * Initialize gpiolib for GPIOs 0-49. | 76 | * Initialize gpiolib for GPIOs 0-49. |
40 | */ | 77 | */ |
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c index 807df142444b..27ec18b53595 100644 --- a/arch/arm/plat-orion/irq.c +++ b/arch/arm/plat-orion/irq.c | |||
@@ -20,47 +20,6 @@ | |||
20 | #include <plat/orion-gpio.h> | 20 | #include <plat/orion-gpio.h> |
21 | #include <mach/bridge-regs.h> | 21 | #include <mach/bridge-regs.h> |
22 | 22 | ||
23 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
24 | /* | ||
25 | * Compiling with both non-DT and DT support enabled, will | ||
26 | * break asm irq handler used by non-DT boards. Therefore, | ||
27 | * we provide a C-style irq handler even for non-DT boards, | ||
28 | * if MULTI_IRQ_HANDLER is set. | ||
29 | * | ||
30 | * Notes: | ||
31 | * - this is prepared for Kirkwood and Dove only, update | ||
32 | * accordingly if you add Orion5x or MV78x00. | ||
33 | * - Orion5x uses different macro names and has only one | ||
34 | * set of CAUSE/MASK registers. | ||
35 | * - MV78x00 uses the same macro names but has a third | ||
36 | * set of CAUSE/MASK registers. | ||
37 | * | ||
38 | */ | ||
39 | |||
40 | static void __iomem *orion_irq_base = IRQ_VIRT_BASE; | ||
41 | |||
42 | asmlinkage void | ||
43 | __exception_irq_entry orion_legacy_handle_irq(struct pt_regs *regs) | ||
44 | { | ||
45 | u32 stat; | ||
46 | |||
47 | stat = readl_relaxed(orion_irq_base + IRQ_CAUSE_LOW_OFF); | ||
48 | stat &= readl_relaxed(orion_irq_base + IRQ_MASK_LOW_OFF); | ||
49 | if (stat) { | ||
50 | unsigned int hwirq = __fls(stat); | ||
51 | handle_IRQ(hwirq, regs); | ||
52 | return; | ||
53 | } | ||
54 | stat = readl_relaxed(orion_irq_base + IRQ_CAUSE_HIGH_OFF); | ||
55 | stat &= readl_relaxed(orion_irq_base + IRQ_MASK_HIGH_OFF); | ||
56 | if (stat) { | ||
57 | unsigned int hwirq = 32 + __fls(stat); | ||
58 | handle_IRQ(hwirq, regs); | ||
59 | return; | ||
60 | } | ||
61 | } | ||
62 | #endif | ||
63 | |||
64 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | 23 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) |
65 | { | 24 | { |
66 | struct irq_chip_generic *gc; | 25 | struct irq_chip_generic *gc; |
@@ -78,10 +37,6 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | |||
78 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 37 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
79 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, | 38 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, |
80 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 39 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
81 | |||
82 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
83 | set_handle_irq(orion_legacy_handle_irq); | ||
84 | #endif | ||
85 | } | 40 | } |
86 | 41 | ||
87 | #ifdef CONFIG_OF | 42 | #ifdef CONFIG_OF |