Commit 930a1bbb authored by Johan Hovold's avatar Johan Hovold Committed by Marc Zyngier

irqdomain: Clean up irq_domain_push/pop_irq()

The irq_domain_push_irq() interface is used to add a new (outmost) level
to a hierarchical domain after IRQs have been allocated.

Possibly due to differing mental images of hierarchical domains, the
names used for the irq_data variables make these functions much harder
to understand than what they need to be.

Rename the struct irq_data pointer to the data embedded in the
descriptor as simply 'irq_data' and refer to the data allocated by this
interface as 'parent_irq_data' so that the names reflect how
hierarchical domains are implemented.
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: default avatarHsin-Yi Wang <hsinyi@chromium.org>
Tested-by: default avatarMark-PK Tsai <mark-pk.tsai@mediatek.com>
Signed-off-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230213104302.17307-12-johan+linaro@kernel.org
parent 4e0d86df
......@@ -1598,8 +1598,8 @@ static void irq_domain_fix_revmap(struct irq_data *d)
*/
int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg)
{
struct irq_data *child_irq_data;
struct irq_data *root_irq_data = irq_get_irq_data(virq);
struct irq_data *irq_data = irq_get_irq_data(virq);
struct irq_data *parent_irq_data;
struct irq_desc *desc;
int rv = 0;
......@@ -1624,45 +1624,44 @@ int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg)
if (WARN_ON(!irq_domain_is_hierarchy(domain)))
return -EINVAL;
if (!root_irq_data)
if (!irq_data)
return -EINVAL;
if (domain->parent != root_irq_data->domain)
if (domain->parent != irq_data->domain)
return -EINVAL;
child_irq_data = kzalloc_node(sizeof(*child_irq_data), GFP_KERNEL,
irq_data_get_node(root_irq_data));
if (!child_irq_data)
parent_irq_data = kzalloc_node(sizeof(*parent_irq_data), GFP_KERNEL,
irq_data_get_node(irq_data));
if (!parent_irq_data)
return -ENOMEM;
mutex_lock(&irq_domain_mutex);
/* Copy the original irq_data. */
*child_irq_data = *root_irq_data;
*parent_irq_data = *irq_data;
/*
* Overwrite the root_irq_data, which is embedded in struct
* irq_desc, with values for this domain.
* Overwrite the irq_data, which is embedded in struct irq_desc, with
* values for this domain.
*/
root_irq_data->parent_data = child_irq_data;
root_irq_data->domain = domain;
root_irq_data->mask = 0;
root_irq_data->hwirq = 0;
root_irq_data->chip = NULL;
root_irq_data->chip_data = NULL;
irq_data->parent_data = parent_irq_data;
irq_data->domain = domain;
irq_data->mask = 0;
irq_data->hwirq = 0;
irq_data->chip = NULL;
irq_data->chip_data = NULL;
/* May (probably does) set hwirq, chip, etc. */
rv = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg);
if (rv) {
/* Restore the original irq_data. */
*root_irq_data = *child_irq_data;
kfree(child_irq_data);
*irq_data = *parent_irq_data;
kfree(parent_irq_data);
goto error;
}
irq_domain_fix_revmap(child_irq_data);
irq_domain_set_mapping(domain, root_irq_data->hwirq, root_irq_data);
irq_domain_fix_revmap(parent_irq_data);
irq_domain_set_mapping(domain, irq_data->hwirq, irq_data);
error:
mutex_unlock(&irq_domain_mutex);
......@@ -1680,8 +1679,8 @@ EXPORT_SYMBOL_GPL(irq_domain_push_irq);
*/
int irq_domain_pop_irq(struct irq_domain *domain, int virq)
{
struct irq_data *root_irq_data = irq_get_irq_data(virq);
struct irq_data *child_irq_data;
struct irq_data *irq_data = irq_get_irq_data(virq);
struct irq_data *parent_irq_data;
struct irq_data *tmp_irq_data;
struct irq_desc *desc;
......@@ -1703,37 +1702,37 @@ int irq_domain_pop_irq(struct irq_domain *domain, int virq)
if (domain == NULL)
return -EINVAL;
if (!root_irq_data)
if (!irq_data)
return -EINVAL;
tmp_irq_data = irq_domain_get_irq_data(domain, virq);
/* We can only "pop" if this domain is at the top of the list */
if (WARN_ON(root_irq_data != tmp_irq_data))
if (WARN_ON(irq_data != tmp_irq_data))
return -EINVAL;
if (WARN_ON(root_irq_data->domain != domain))
if (WARN_ON(irq_data->domain != domain))
return -EINVAL;
child_irq_data = root_irq_data->parent_data;
if (WARN_ON(!child_irq_data))
parent_irq_data = irq_data->parent_data;
if (WARN_ON(!parent_irq_data))
return -EINVAL;
mutex_lock(&irq_domain_mutex);
root_irq_data->parent_data = NULL;
irq_data->parent_data = NULL;
irq_domain_clear_mapping(domain, root_irq_data->hwirq);
irq_domain_clear_mapping(domain, irq_data->hwirq);
irq_domain_free_irqs_hierarchy(domain, virq, 1);
/* Restore the original irq_data. */
*root_irq_data = *child_irq_data;
*irq_data = *parent_irq_data;
irq_domain_fix_revmap(root_irq_data);
irq_domain_fix_revmap(irq_data);
mutex_unlock(&irq_domain_mutex);
kfree(child_irq_data);
kfree(parent_irq_data);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment