Skip to content

Commit 44b68de

Browse files
hcodinaKAGA-KOKO
authored andcommitted
irqdomain: Introduce init() and exit() hooks
The current API does not allow additional initialization before the domain is published. This can lead to a race condition between consumers and supplier as a domain can be available for consumers before being fully ready. Introduce the init() hook to allow additional initialization before plublishing the domain. Also introduce the exit() hook to revert operations done in init() on domain removal. Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Herve Codina <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0b21add commit 44b68de

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

include/linux/irqdomain.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ struct irq_domain_chip_generic;
141141
* purposes related to the irq domain.
142142
* @parent: Pointer to parent irq_domain to support hierarchy irq_domains
143143
* @msi_parent_ops: Pointer to MSI parent domain methods for per device domain init
144+
* @exit: Function called when the domain is destroyed
144145
*
145146
* Revmap data, used internally by the irq domain code:
146147
* @revmap_size: Size of the linear map table @revmap[]
@@ -169,6 +170,7 @@ struct irq_domain {
169170
#ifdef CONFIG_GENERIC_MSI_IRQ
170171
const struct msi_parent_ops *msi_parent_ops;
171172
#endif
173+
void (*exit)(struct irq_domain *d);
172174

173175
/* reverse map data. The linear map gets appended to the irq_domain */
174176
irq_hw_number_t hwirq_max;
@@ -268,6 +270,10 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
268270
* @bus_token: Domain bus token
269271
* @ops: Domain operation callbacks
270272
* @host_data: Controller private data pointer
273+
* @init: Function called when the domain is created.
274+
* Allow to do some additional domain initialisation.
275+
* @exit: Function called when the domain is destroyed.
276+
* Allow to do some additional cleanup operation.
271277
*/
272278
struct irq_domain_info {
273279
struct fwnode_handle *fwnode;
@@ -284,6 +290,8 @@ struct irq_domain_info {
284290
*/
285291
struct irq_domain *parent;
286292
#endif
293+
int (*init)(struct irq_domain *d);
294+
void (*exit)(struct irq_domain *d);
287295
};
288296

289297
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info);

kernel/irq/irqdomain.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,14 @@ static void irq_domain_free(struct irq_domain *domain)
276276
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
277277
{
278278
struct irq_domain *domain;
279+
int err;
279280

280281
domain = __irq_domain_create(info);
281282
if (IS_ERR(domain))
282283
return domain;
283284

284285
domain->flags |= info->domain_flags;
286+
domain->exit = info->exit;
285287

286288
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
287289
if (info->parent) {
@@ -290,9 +292,19 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
290292
}
291293
#endif
292294

295+
if (info->init) {
296+
err = info->init(domain);
297+
if (err)
298+
goto err_domain_free;
299+
}
300+
293301
__irq_domain_publish(domain);
294302

295303
return domain;
304+
305+
err_domain_free:
306+
irq_domain_free(domain);
307+
return ERR_PTR(err);
296308
}
297309
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
298310

@@ -339,6 +351,9 @@ EXPORT_SYMBOL_GPL(__irq_domain_add);
339351
*/
340352
void irq_domain_remove(struct irq_domain *domain)
341353
{
354+
if (domain->exit)
355+
domain->exit(domain);
356+
342357
mutex_lock(&irq_domain_mutex);
343358
debugfs_remove_domain_dir(domain);
344359

0 commit comments

Comments
 (0)