summaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:33:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:33:11 -0500
commit670310dfbae0eefe7318ff6a61e29e67a7a7bbce (patch)
treeeb3ce3aa3e6786a64fec93d410bb6f0b9a56be77 /kernel/irq/chip.c
parent43ff2f4db9d0f76452b77cfa645f02b471143b24 (diff)
parentffc661c99f621152d5fdcf53f9df0d48c326318b (diff)
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner: "A rather large update for the interrupt core code and the irq chip drivers: - Add a new bitmap matrix allocator and supporting changes, which is used to replace the x86 vector allocator which comes with separate pull request. This allows to replace the convoluted nested loop allocation function in x86 with a facility which supports the recently added property of managed interrupts proper and allows to switch to a best effort vector reservation scheme, which addresses problems with vector exhaustion. - A large update to the ARM GIC-V3-ITS driver adding support for range selectors. - New interrupt controllers: - Meson and Meson8 GPIO - BCM7271 L2 - Socionext EXIU If you expected that this will stop at some point, I have to disappoint you. There are new ones posted already. Sigh! - STM32 interrupt controller support for new platforms. - A pile of fixes, cleanups and updates to the MIPS GIC driver - The usual small fixes, cleanups and updates all over the place. Most visible one is to move the irq chip drivers Kconfig switches into a separate Kconfig menu" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits) genirq: Fix type of shifting literal 1 in __setup_irq() irqdomain: Drop pointless NULL check in virq_debug_show_one genirq/proc: Return proper error code when irq_set_affinity() fails irq/work: Use llist_for_each_entry_safe irqchip: mips-gic: Print warning if inherited GIC base is used irqchip/mips-gic: Add pr_fmt and reword pr_* messages irqchip/stm32: Move the wakeup on interrupt mask irqchip/stm32: Fix initial values irqchip/stm32: Add stm32h7 support dt-bindings/interrupt-controllers: Add compatible string for stm32h7 irqchip/stm32: Add multi-bank management irqchip/stm32: Select GENERIC_IRQ_CHIP irqchip/exiu: Add support for Socionext Synquacer EXIU controller dt-bindings: Add description of Socionext EXIU interrupt controller irqchip/gic-v3-its: Fix VPE activate callback return value irqchip: mips-gic: Make IPI bitmaps static irqchip: mips-gic: Share register writes in gic_set_type() irqchip: mips-gic: Remove gic_vpes variable irqchip: mips-gic: Use num_possible_cpus() to reserve IPIs irqchip: mips-gic: Configure EIC when CPUs come online ...
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r--kernel/irq/chip.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 5a2ef92c2782..043bfc35b353 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -207,20 +207,24 @@ __irq_startup_managed(struct irq_desc *desc, struct cpumask *aff, bool force)
207 * Catch code which fiddles with enable_irq() on a managed 207 * Catch code which fiddles with enable_irq() on a managed
208 * and potentially shutdown IRQ. Chained interrupt 208 * and potentially shutdown IRQ. Chained interrupt
209 * installment or irq auto probing should not happen on 209 * installment or irq auto probing should not happen on
210 * managed irqs either. Emit a warning, break the affinity 210 * managed irqs either.
211 * and start it up as a normal interrupt.
212 */ 211 */
213 if (WARN_ON_ONCE(force)) 212 if (WARN_ON_ONCE(force))
214 return IRQ_STARTUP_NORMAL; 213 return IRQ_STARTUP_ABORT;
215 /* 214 /*
216 * The interrupt was requested, but there is no online CPU 215 * The interrupt was requested, but there is no online CPU
217 * in it's affinity mask. Put it into managed shutdown 216 * in it's affinity mask. Put it into managed shutdown
218 * state and let the cpu hotplug mechanism start it up once 217 * state and let the cpu hotplug mechanism start it up once
219 * a CPU in the mask becomes available. 218 * a CPU in the mask becomes available.
220 */ 219 */
221 irqd_set_managed_shutdown(d);
222 return IRQ_STARTUP_ABORT; 220 return IRQ_STARTUP_ABORT;
223 } 221 }
222 /*
223 * Managed interrupts have reserved resources, so this should not
224 * happen.
225 */
226 if (WARN_ON(irq_domain_activate_irq(d, false)))
227 return IRQ_STARTUP_ABORT;
224 return IRQ_STARTUP_MANAGED; 228 return IRQ_STARTUP_MANAGED;
225} 229}
226#else 230#else
@@ -236,7 +240,9 @@ static int __irq_startup(struct irq_desc *desc)
236 struct irq_data *d = irq_desc_get_irq_data(desc); 240 struct irq_data *d = irq_desc_get_irq_data(desc);
237 int ret = 0; 241 int ret = 0;
238 242
239 irq_domain_activate_irq(d); 243 /* Warn if this interrupt is not activated but try nevertheless */
244 WARN_ON_ONCE(!irqd_is_activated(d));
245
240 if (d->chip->irq_startup) { 246 if (d->chip->irq_startup) {
241 ret = d->chip->irq_startup(d); 247 ret = d->chip->irq_startup(d);
242 irq_state_clr_disabled(desc); 248 irq_state_clr_disabled(desc);
@@ -269,6 +275,7 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
269 ret = __irq_startup(desc); 275 ret = __irq_startup(desc);
270 break; 276 break;
271 case IRQ_STARTUP_ABORT: 277 case IRQ_STARTUP_ABORT:
278 irqd_set_managed_shutdown(d);
272 return 0; 279 return 0;
273 } 280 }
274 } 281 }
@@ -278,6 +285,22 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
278 return ret; 285 return ret;
279} 286}
280 287
288int irq_activate(struct irq_desc *desc)
289{
290 struct irq_data *d = irq_desc_get_irq_data(desc);
291
292 if (!irqd_affinity_is_managed(d))
293 return irq_domain_activate_irq(d, false);
294 return 0;
295}
296
297void irq_activate_and_startup(struct irq_desc *desc, bool resend)
298{
299 if (WARN_ON(irq_activate(desc)))
300 return;
301 irq_startup(desc, resend, IRQ_START_FORCE);
302}
303
281static void __irq_disable(struct irq_desc *desc, bool mask); 304static void __irq_disable(struct irq_desc *desc, bool mask);
282 305
283void irq_shutdown(struct irq_desc *desc) 306void irq_shutdown(struct irq_desc *desc)
@@ -953,7 +976,7 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
953 irq_settings_set_norequest(desc); 976 irq_settings_set_norequest(desc);
954 irq_settings_set_nothread(desc); 977 irq_settings_set_nothread(desc);
955 desc->action = &chained_action; 978 desc->action = &chained_action;
956 irq_startup(desc, IRQ_RESEND, IRQ_START_FORCE); 979 irq_activate_and_startup(desc, IRQ_RESEND);
957 } 980 }
958} 981}
959 982