mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
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: Philippe Mathieu-Daudé <philmd@linaro.org> Tested-by: Hsin-Yi Wang <hsinyi@chromium.org> Tested-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com> Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230213104302.17307-12-johan+linaro@kernel.org
This commit is contained in:
parent
4e0d86df93
commit
930a1bbbef
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user