aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/irq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-09 12:33:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-09 12:33:18 -0400
commite853ccf08b9ac32ce731600de9618c1a462e8b70 (patch)
tree9abe6729a914aee5621297c49066c58c854c809e /arch/arc/kernel/irq.c
parentd7b1fd9140c266c956bf1b4a2c3329aff8da5323 (diff)
parent2a5e95d4181c3f177a41b7c141a816859478c4d7 (diff)
Merge tag 'arc-v3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull ARC changes from Vineet Gupta: "Mostly cleanup/refactoring in core intc, cache flush, IPI send..." * tag 'arc-v3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: mm, arc: remove obsolete pagefault oom killer comment ARC: help gcc elide icache helper for !SMP ARC: move common ops for line/full cache into helpers ARC: cache boot reporting updates ARC: [intc] mask/unmask can be hidden again ARC: [plat-arcfpga] No need for init_irq hack ARC: [intc] don't mask all IRQ by default ARC: prune extra header includes from smp.c ARC: update some comments ARC: [SMP] unify cpu private IRQ requests (TIMER/IPI)
Diffstat (limited to 'arch/arc/kernel/irq.c')
-rw-r--r--arch/arc/kernel/irq.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 7d653c0d0773..620ec2fe32a9 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -19,21 +19,16 @@
19 19
20/* 20/*
21 * Early Hardware specific Interrupt setup 21 * Early Hardware specific Interrupt setup
22 * -Platform independent, needed for each CPU (not foldable into init_IRQ)
22 * -Called very early (start_kernel -> setup_arch -> setup_processor) 23 * -Called very early (start_kernel -> setup_arch -> setup_processor)
23 * -Platform Independent (must for any ARC700)
24 * -Needed for each CPU (hence not foldable into init_IRQ)
25 * 24 *
26 * what it does ? 25 * what it does ?
27 * -Disable all IRQs (on CPU side)
28 * -Optionally, setup the High priority Interrupts as Level 2 IRQs 26 * -Optionally, setup the High priority Interrupts as Level 2 IRQs
29 */ 27 */
30void arc_init_IRQ(void) 28void arc_init_IRQ(void)
31{ 29{
32 int level_mask = 0; 30 int level_mask = 0;
33 31
34 /* Disable all IRQs: enable them as devices request */
35 write_aux_reg(AUX_IENABLE, 0);
36
37 /* setup any high priority Interrupts (Level2 in ARCompact jargon) */ 32 /* setup any high priority Interrupts (Level2 in ARCompact jargon) */
38 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3; 33 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
39 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5; 34 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
@@ -60,20 +55,28 @@ void arc_init_IRQ(void)
60 * below, per IRQ. 55 * below, per IRQ.
61 */ 56 */
62 57
63static void arc_mask_irq(struct irq_data *data) 58static void arc_irq_mask(struct irq_data *data)
64{ 59{
65 arch_mask_irq(data->irq); 60 unsigned int ienb;
61
62 ienb = read_aux_reg(AUX_IENABLE);
63 ienb &= ~(1 << data->irq);
64 write_aux_reg(AUX_IENABLE, ienb);
66} 65}
67 66
68static void arc_unmask_irq(struct irq_data *data) 67static void arc_irq_unmask(struct irq_data *data)
69{ 68{
70 arch_unmask_irq(data->irq); 69 unsigned int ienb;
70
71 ienb = read_aux_reg(AUX_IENABLE);
72 ienb |= (1 << data->irq);
73 write_aux_reg(AUX_IENABLE, ienb);
71} 74}
72 75
73static struct irq_chip onchip_intc = { 76static struct irq_chip onchip_intc = {
74 .name = "ARC In-core Intc", 77 .name = "ARC In-core Intc",
75 .irq_mask = arc_mask_irq, 78 .irq_mask = arc_irq_mask,
76 .irq_unmask = arc_unmask_irq, 79 .irq_unmask = arc_irq_unmask,
77}; 80};
78 81
79static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq, 82static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
@@ -150,6 +153,32 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
150 set_irq_regs(old_regs); 153 set_irq_regs(old_regs);
151} 154}
152 155
156void arc_request_percpu_irq(int irq, int cpu,
157 irqreturn_t (*isr)(int irq, void *dev),
158 const char *irq_nm,
159 void *percpu_dev)
160{
161 /* Boot cpu calls request, all call enable */
162 if (!cpu) {
163 int rc;
164
165 /*
166 * These 2 calls are essential to making percpu IRQ APIs work
167 * Ideally these details could be hidden in irq chip map function
168 * but the issue is IPIs IRQs being static (non-DT) and platform
169 * specific, so we can't identify them there.
170 */
171 irq_set_percpu_devid(irq);
172 irq_modify_status(irq, IRQ_NOAUTOEN, 0); /* @irq, @clr, @set */
173
174 rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
175 if (rc)
176 panic("Percpu IRQ request failed for %d\n", irq);
177 }
178
179 enable_percpu_irq(irq, 0);
180}
181
153/* 182/*
154 * arch_local_irq_enable - Enable interrupts. 183 * arch_local_irq_enable - Enable interrupts.
155 * 184 *