Commit e6f67ce3 authored by Herve Codina's avatar Herve Codina Committed by Thomas Gleixner

irqdomain: Add support for generic irq chips creation before publishing a domain

The current API functions create an irq_domain and also publish this
newly created to domain. Once an irq_domain is published, consumers can
request IRQ in order to use them.

Some interrupt controller drivers have to perform some more operations
with the created irq_domain in order to have it ready to be used.
For instance:
   - Allocate generic irq chips with irq_alloc_domain_generic_chips()
   - Retrieve the generic irq chips with irq_get_domain_generic_chip()
   - Initialize retrieved chips: set register base address and offsets,
     set several hooks such as irq_mask, irq_unmask, ...

With the newly introduced irq_domain_alloc_generic_chips(), an interrupt
controller driver can use the irq_domain_chip_generic_info structure and
set the init() hook to perform its generic chips initialization.

In order to avoid a window where the domain is published but not yet
ready to be used, handle the generic chip creation (i.e the
irq_domain_alloc_generic_chips() call) before the domain is published.
Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarHerve Codina <herve.codina@bootlin.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240614173232.1184015-16-herve.codina@bootlin.com
parent fea922ee
......@@ -210,6 +210,9 @@ enum {
/* Irq domain is a MSI device domain */
IRQ_DOMAIN_FLAG_MSI_DEVICE = (1 << 9),
/* Irq domain must destroy generic chips when removed */
IRQ_DOMAIN_FLAG_DESTROY_GC = (1 << 10),
/*
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
* for implementation specific purposes and ignored by the
......@@ -259,6 +262,9 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
}
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
struct irq_domain_chip_generic_info;
/**
* struct irq_domain_info - Domain information structure
* @fwnode: firmware node for the interrupt controller
......@@ -270,6 +276,8 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
* @bus_token: Domain bus token
* @ops: Domain operation callbacks
* @host_data: Controller private data pointer
* @dgc_info: Geneneric chip information structure pointer used to
* create generic chips for the domain if not NULL.
* @init: Function called when the domain is created.
* Allow to do some additional domain initialisation.
* @exit: Function called when the domain is destroyed.
......@@ -290,6 +298,7 @@ struct irq_domain_info {
*/
struct irq_domain *parent;
#endif
struct irq_domain_chip_generic_info *dgc_info;
int (*init)(struct irq_domain *d);
void (*exit)(struct irq_domain *d);
};
......
......@@ -292,16 +292,25 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
}
#endif
if (info->dgc_info) {
err = irq_domain_alloc_generic_chips(domain, info->dgc_info);
if (err)
goto err_domain_free;
}
if (info->init) {
err = info->init(domain);
if (err)
goto err_domain_free;
goto err_domain_gc_remove;
}
__irq_domain_publish(domain);
return domain;
err_domain_gc_remove:
if (info->dgc_info)
irq_domain_remove_generic_chips(domain);
err_domain_free:
irq_domain_free(domain);
return ERR_PTR(err);
......@@ -369,6 +378,9 @@ void irq_domain_remove(struct irq_domain *domain)
mutex_unlock(&irq_domain_mutex);
if (domain->flags & IRQ_DOMAIN_FLAG_DESTROY_GC)
irq_domain_remove_generic_chips(domain);
pr_debug("Removed domain %s\n", domain->name);
irq_domain_free(domain);
}
......
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