aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r--kernel/irq/chip.c126
1 files changed, 21 insertions, 105 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3aca9f29d30..dc5114b4c16 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -16,8 +16,6 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18 18
19#include <trace/events/irq.h>
20
21#include "internals.h" 19#include "internals.h"
22 20
23/** 21/**
@@ -28,7 +26,7 @@
28int irq_set_chip(unsigned int irq, struct irq_chip *chip) 26int irq_set_chip(unsigned int irq, struct irq_chip *chip)
29{ 27{
30 unsigned long flags; 28 unsigned long flags;
31 struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); 29 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
32 30
33 if (!desc) 31 if (!desc)
34 return -EINVAL; 32 return -EINVAL;
@@ -56,14 +54,15 @@ EXPORT_SYMBOL(irq_set_chip);
56int irq_set_irq_type(unsigned int irq, unsigned int type) 54int irq_set_irq_type(unsigned int irq, unsigned int type)
57{ 55{
58 unsigned long flags; 56 unsigned long flags;
59 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL); 57 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
60 int ret = 0; 58 int ret = 0;
61 59
62 if (!desc) 60 if (!desc)
63 return -EINVAL; 61 return -EINVAL;
64 62
65 type &= IRQ_TYPE_SENSE_MASK; 63 type &= IRQ_TYPE_SENSE_MASK;
66 ret = __irq_set_trigger(desc, irq, type); 64 if (type != IRQ_TYPE_NONE)
65 ret = __irq_set_trigger(desc, irq, type);
67 irq_put_desc_busunlock(desc, flags); 66 irq_put_desc_busunlock(desc, flags);
68 return ret; 67 return ret;
69} 68}
@@ -79,7 +78,7 @@ EXPORT_SYMBOL(irq_set_irq_type);
79int irq_set_handler_data(unsigned int irq, void *data) 78int irq_set_handler_data(unsigned int irq, void *data)
80{ 79{
81 unsigned long flags; 80 unsigned long flags;
82 struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); 81 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
83 82
84 if (!desc) 83 if (!desc)
85 return -EINVAL; 84 return -EINVAL;
@@ -99,7 +98,7 @@ EXPORT_SYMBOL(irq_set_handler_data);
99int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry) 98int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
100{ 99{
101 unsigned long flags; 100 unsigned long flags;
102 struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL); 101 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
103 102
104 if (!desc) 103 if (!desc)
105 return -EINVAL; 104 return -EINVAL;
@@ -120,7 +119,7 @@ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
120int irq_set_chip_data(unsigned int irq, void *data) 119int irq_set_chip_data(unsigned int irq, void *data)
121{ 120{
122 unsigned long flags; 121 unsigned long flags;
123 struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); 122 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
124 123
125 if (!desc) 124 if (!desc)
126 return -EINVAL; 125 return -EINVAL;
@@ -158,22 +157,19 @@ static void irq_state_set_masked(struct irq_desc *desc)
158 irqd_set(&desc->irq_data, IRQD_IRQ_MASKED); 157 irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
159} 158}
160 159
161int irq_startup(struct irq_desc *desc, bool resend) 160int irq_startup(struct irq_desc *desc)
162{ 161{
163 int ret = 0;
164
165 irq_state_clr_disabled(desc); 162 irq_state_clr_disabled(desc);
166 desc->depth = 0; 163 desc->depth = 0;
167 164
168 if (desc->irq_data.chip->irq_startup) { 165 if (desc->irq_data.chip->irq_startup) {
169 ret = desc->irq_data.chip->irq_startup(&desc->irq_data); 166 int ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
170 irq_state_clr_masked(desc); 167 irq_state_clr_masked(desc);
171 } else { 168 return ret;
172 irq_enable(desc);
173 } 169 }
174 if (resend) 170
175 check_irq_resend(desc, desc->irq_data.irq); 171 irq_enable(desc);
176 return ret; 172 return 0;
177} 173}
178 174
179void irq_shutdown(struct irq_desc *desc) 175void irq_shutdown(struct irq_desc *desc)
@@ -208,24 +204,6 @@ void irq_disable(struct irq_desc *desc)
208 } 204 }
209} 205}
210 206
211void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu)
212{
213 if (desc->irq_data.chip->irq_enable)
214 desc->irq_data.chip->irq_enable(&desc->irq_data);
215 else
216 desc->irq_data.chip->irq_unmask(&desc->irq_data);
217 cpumask_set_cpu(cpu, desc->percpu_enabled);
218}
219
220void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
221{
222 if (desc->irq_data.chip->irq_disable)
223 desc->irq_data.chip->irq_disable(&desc->irq_data);
224 else
225 desc->irq_data.chip->irq_mask(&desc->irq_data);
226 cpumask_clear_cpu(cpu, desc->percpu_enabled);
227}
228
229static inline void mask_ack_irq(struct irq_desc *desc) 207static inline void mask_ack_irq(struct irq_desc *desc)
230{ 208{
231 if (desc->irq_data.chip->irq_mask_ack) 209 if (desc->irq_data.chip->irq_mask_ack)
@@ -272,14 +250,11 @@ void handle_nested_irq(unsigned int irq)
272 250
273 raw_spin_lock_irq(&desc->lock); 251 raw_spin_lock_irq(&desc->lock);
274 252
275 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
276 kstat_incr_irqs_this_cpu(irq, desc); 253 kstat_incr_irqs_this_cpu(irq, desc);
277 254
278 action = desc->action; 255 action = desc->action;
279 if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) { 256 if (unlikely(!action || irqd_irq_disabled(&desc->irq_data)))
280 desc->istate |= IRQS_PENDING;
281 goto out_unlock; 257 goto out_unlock;
282 }
283 258
284 irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); 259 irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
285 raw_spin_unlock_irq(&desc->lock); 260 raw_spin_unlock_irq(&desc->lock);
@@ -327,10 +302,8 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
327 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); 302 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
328 kstat_incr_irqs_this_cpu(irq, desc); 303 kstat_incr_irqs_this_cpu(irq, desc);
329 304
330 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { 305 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
331 desc->istate |= IRQS_PENDING;
332 goto out_unlock; 306 goto out_unlock;
333 }
334 307
335 handle_irq_event(desc); 308 handle_irq_event(desc);
336 309
@@ -339,24 +312,6 @@ out_unlock:
339} 312}
340EXPORT_SYMBOL_GPL(handle_simple_irq); 313EXPORT_SYMBOL_GPL(handle_simple_irq);
341 314
342/*
343 * Called unconditionally from handle_level_irq() and only for oneshot
344 * interrupts from handle_fasteoi_irq()
345 */
346static void cond_unmask_irq(struct irq_desc *desc)
347{
348 /*
349 * We need to unmask in the following cases:
350 * - Standard level irq (IRQF_ONESHOT is not set)
351 * - Oneshot irq which did not wake the thread (caused by a
352 * spurious interrupt or a primary handler handling it
353 * completely).
354 */
355 if (!irqd_irq_disabled(&desc->irq_data) &&
356 irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot)
357 unmask_irq(desc);
358}
359
360/** 315/**
361 * handle_level_irq - Level type irq handler 316 * handle_level_irq - Level type irq handler
362 * @irq: the interrupt number 317 * @irq: the interrupt number
@@ -384,15 +339,13 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
384 * If its disabled or no action available 339 * If its disabled or no action available
385 * keep it masked and get out of here 340 * keep it masked and get out of here
386 */ 341 */
387 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { 342 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
388 desc->istate |= IRQS_PENDING;
389 goto out_unlock; 343 goto out_unlock;
390 }
391 344
392 handle_irq_event(desc); 345 handle_irq_event(desc);
393 346
394 cond_unmask_irq(desc); 347 if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
395 348 unmask_irq(desc);
396out_unlock: 349out_unlock:
397 raw_spin_unlock(&desc->lock); 350 raw_spin_unlock(&desc->lock);
398} 351}
@@ -446,9 +399,6 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
446 preflow_handler(desc); 399 preflow_handler(desc);
447 handle_irq_event(desc); 400 handle_irq_event(desc);
448 401
449 if (desc->istate & IRQS_ONESHOT)
450 cond_unmask_irq(desc);
451
452out_eoi: 402out_eoi:
453 desc->irq_data.chip->irq_eoi(&desc->irq_data); 403 desc->irq_data.chip->irq_eoi(&desc->irq_data);
454out_unlock: 404out_unlock:
@@ -525,7 +475,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
525out_unlock: 475out_unlock:
526 raw_spin_unlock(&desc->lock); 476 raw_spin_unlock(&desc->lock);
527} 477}
528EXPORT_SYMBOL(handle_edge_irq);
529 478
530#ifdef CONFIG_IRQ_EDGE_EOI_HANDLER 479#ifdef CONFIG_IRQ_EDGE_EOI_HANDLER
531/** 480/**
@@ -595,44 +544,12 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
595 chip->irq_eoi(&desc->irq_data); 544 chip->irq_eoi(&desc->irq_data);
596} 545}
597 546
598/**
599 * handle_percpu_devid_irq - Per CPU local irq handler with per cpu dev ids
600 * @irq: the interrupt number
601 * @desc: the interrupt description structure for this irq
602 *
603 * Per CPU interrupts on SMP machines without locking requirements. Same as
604 * handle_percpu_irq() above but with the following extras:
605 *
606 * action->percpu_dev_id is a pointer to percpu variables which
607 * contain the real device id for the cpu on which this handler is
608 * called
609 */
610void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
611{
612 struct irq_chip *chip = irq_desc_get_chip(desc);
613 struct irqaction *action = desc->action;
614 void *dev_id = __this_cpu_ptr(action->percpu_dev_id);
615 irqreturn_t res;
616
617 kstat_incr_irqs_this_cpu(irq, desc);
618
619 if (chip->irq_ack)
620 chip->irq_ack(&desc->irq_data);
621
622 trace_irq_handler_entry(irq, action);
623 res = action->handler(irq, dev_id);
624 trace_irq_handler_exit(irq, action, res);
625
626 if (chip->irq_eoi)
627 chip->irq_eoi(&desc->irq_data);
628}
629
630void 547void
631__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, 548__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
632 const char *name) 549 const char *name)
633{ 550{
634 unsigned long flags; 551 unsigned long flags;
635 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0); 552 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
636 553
637 if (!desc) 554 if (!desc)
638 return; 555 return;
@@ -658,7 +575,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
658 irq_settings_set_noprobe(desc); 575 irq_settings_set_noprobe(desc);
659 irq_settings_set_norequest(desc); 576 irq_settings_set_norequest(desc);
660 irq_settings_set_nothread(desc); 577 irq_settings_set_nothread(desc);
661 irq_startup(desc, true); 578 irq_startup(desc);
662 } 579 }
663out: 580out:
664 irq_put_desc_busunlock(desc, flags); 581 irq_put_desc_busunlock(desc, flags);
@@ -672,12 +589,11 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
672 irq_set_chip(irq, chip); 589 irq_set_chip(irq, chip);
673 __irq_set_handler(irq, handle, 0, name); 590 __irq_set_handler(irq, handle, 0, name);
674} 591}
675EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name);
676 592
677void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) 593void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
678{ 594{
679 unsigned long flags; 595 unsigned long flags;
680 struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); 596 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
681 597
682 if (!desc) 598 if (!desc)
683 return; 599 return;