|
@@ -207,20 +207,19 @@ __irq_startup_managed(struct irq_desc *desc, struct cpumask *aff, bool force)
|
|
|
* Catch code which fiddles with enable_irq() on a managed
|
|
|
* and potentially shutdown IRQ. Chained interrupt
|
|
|
* installment or irq auto probing should not happen on
|
|
|
- * managed irqs either. Emit a warning, break the affinity
|
|
|
- * and start it up as a normal interrupt.
|
|
|
+ * managed irqs either.
|
|
|
*/
|
|
|
if (WARN_ON_ONCE(force))
|
|
|
- return IRQ_STARTUP_NORMAL;
|
|
|
+ return IRQ_STARTUP_ABORT;
|
|
|
/*
|
|
|
* The interrupt was requested, but there is no online CPU
|
|
|
* in it's affinity mask. Put it into managed shutdown
|
|
|
* state and let the cpu hotplug mechanism start it up once
|
|
|
* a CPU in the mask becomes available.
|
|
|
*/
|
|
|
- irqd_set_managed_shutdown(d);
|
|
|
return IRQ_STARTUP_ABORT;
|
|
|
}
|
|
|
+ irq_domain_activate_irq(d);
|
|
|
return IRQ_STARTUP_MANAGED;
|
|
|
}
|
|
|
#else
|
|
@@ -236,7 +235,9 @@ static int __irq_startup(struct irq_desc *desc)
|
|
|
struct irq_data *d = irq_desc_get_irq_data(desc);
|
|
|
int ret = 0;
|
|
|
|
|
|
- irq_domain_activate_irq(d);
|
|
|
+ /* Warn if this interrupt is not activated but try nevertheless */
|
|
|
+ WARN_ON_ONCE(!irqd_is_activated(d));
|
|
|
+
|
|
|
if (d->chip->irq_startup) {
|
|
|
ret = d->chip->irq_startup(d);
|
|
|
irq_state_clr_disabled(desc);
|
|
@@ -269,6 +270,7 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
|
|
|
irq_set_affinity_locked(d, aff, false);
|
|
|
break;
|
|
|
case IRQ_STARTUP_ABORT:
|
|
|
+ irqd_set_managed_shutdown(d);
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
@@ -278,6 +280,22 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+int irq_activate(struct irq_desc *desc)
|
|
|
+{
|
|
|
+ struct irq_data *d = irq_desc_get_irq_data(desc);
|
|
|
+
|
|
|
+ if (!irqd_affinity_is_managed(d))
|
|
|
+ irq_domain_activate_irq(d);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void irq_activate_and_startup(struct irq_desc *desc, bool resend)
|
|
|
+{
|
|
|
+ if (WARN_ON(irq_activate(desc)))
|
|
|
+ return;
|
|
|
+ irq_startup(desc, resend, IRQ_START_FORCE);
|
|
|
+}
|
|
|
+
|
|
|
static void __irq_disable(struct irq_desc *desc, bool mask);
|
|
|
|
|
|
void irq_shutdown(struct irq_desc *desc)
|
|
@@ -953,7 +971,7 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
|
|
|
irq_settings_set_norequest(desc);
|
|
|
irq_settings_set_nothread(desc);
|
|
|
desc->action = &chained_action;
|
|
|
- irq_startup(desc, IRQ_RESEND, IRQ_START_FORCE);
|
|
|
+ irq_activate_and_startup(desc, IRQ_RESEND);
|
|
|
}
|
|
|
}
|
|
|
|