|
@@ -1682,28 +1682,35 @@ void irq_domain_free_irqs_parent(struct irq_domain *domain,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(irq_domain_free_irqs_parent);
|
|
|
|
|
|
-static void __irq_domain_activate_irq(struct irq_data *irq_data)
|
|
|
+static void __irq_domain_deactivate_irq(struct irq_data *irq_data)
|
|
|
{
|
|
|
if (irq_data && irq_data->domain) {
|
|
|
struct irq_domain *domain = irq_data->domain;
|
|
|
|
|
|
+ if (domain->ops->deactivate)
|
|
|
+ domain->ops->deactivate(domain, irq_data);
|
|
|
if (irq_data->parent_data)
|
|
|
- __irq_domain_activate_irq(irq_data->parent_data);
|
|
|
- if (domain->ops->activate)
|
|
|
- domain->ops->activate(domain, irq_data, false);
|
|
|
+ __irq_domain_deactivate_irq(irq_data->parent_data);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void __irq_domain_deactivate_irq(struct irq_data *irq_data)
|
|
|
+static int __irq_domain_activate_irq(struct irq_data *irqd)
|
|
|
{
|
|
|
- if (irq_data && irq_data->domain) {
|
|
|
- struct irq_domain *domain = irq_data->domain;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
- if (domain->ops->deactivate)
|
|
|
- domain->ops->deactivate(domain, irq_data);
|
|
|
- if (irq_data->parent_data)
|
|
|
- __irq_domain_deactivate_irq(irq_data->parent_data);
|
|
|
+ if (irqd && irqd->domain) {
|
|
|
+ struct irq_domain *domain = irqd->domain;
|
|
|
+
|
|
|
+ if (irqd->parent_data)
|
|
|
+ ret = __irq_domain_activate_irq(irqd->parent_data);
|
|
|
+ if (!ret && domain->ops->activate) {
|
|
|
+ ret = domain->ops->activate(domain, irqd, false);
|
|
|
+ /* Rollback in case of error */
|
|
|
+ if (ret && irqd->parent_data)
|
|
|
+ __irq_domain_deactivate_irq(irqd->parent_data);
|
|
|
+ }
|
|
|
}
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1714,12 +1721,15 @@ static void __irq_domain_deactivate_irq(struct irq_data *irq_data)
|
|
|
* This is the second step to call domain_ops->activate to program interrupt
|
|
|
* controllers, so the interrupt could actually get delivered.
|
|
|
*/
|
|
|
-void irq_domain_activate_irq(struct irq_data *irq_data)
|
|
|
+int irq_domain_activate_irq(struct irq_data *irq_data)
|
|
|
{
|
|
|
- if (!irqd_is_activated(irq_data)) {
|
|
|
- __irq_domain_activate_irq(irq_data);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ if (!irqd_is_activated(irq_data))
|
|
|
+ ret = __irq_domain_activate_irq(irq_data);
|
|
|
+ if (!ret)
|
|
|
irqd_set_activated(irq_data);
|
|
|
- }
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/**
|