diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-09 12:33:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-09 12:33:18 -0400 |
commit | e853ccf08b9ac32ce731600de9618c1a462e8b70 (patch) | |
tree | 9abe6729a914aee5621297c49066c58c854c809e /arch/arc/kernel/irq.c | |
parent | d7b1fd9140c266c956bf1b4a2c3329aff8da5323 (diff) | |
parent | 2a5e95d4181c3f177a41b7c141a816859478c4d7 (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.c | 53 |
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 | */ |
30 | void arc_init_IRQ(void) | 28 | void 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 | ||
63 | static void arc_mask_irq(struct irq_data *data) | 58 | static 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 | ||
68 | static void arc_unmask_irq(struct irq_data *data) | 67 | static 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 | ||
73 | static struct irq_chip onchip_intc = { | 76 | static 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 | ||
79 | static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq, | 82 | static 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 | ||
156 | void 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 | * |