Skip to content

Commit 70114e7

Browse files
M-VaittinenKAGA-KOKO
authored andcommitted
irqdomain: Simplify simple and legacy domain creation
irq_domain_create_simple() and irq_domain_create_legacy() use __irq_domain_instantiate(), but have extra handling of allocating interrupt descriptors and associating interrupts in them. Some of that is duplicated. There are also call sites which have conditonals to invoke different interrupt domain creator functions, where one of them is usually irq_domain_create_legacy(). Alternatively they associate the interrupts for the legacy case after creating the domain. Moving the extra logic of irq_domain_create_simple()/legacy() into __irq_domain_instantiate() allows to consolidate that. Introduce hwirq_base and virq_base members in the irq_domain_info structure, which allows to transport the required information and add the conditional interrupt descriptor allocation and interrupt association into __irq_domain_instantiate(). This reduces irq_domain_create_legacy() and irq_domain_create_simple() to trivial wrappers which fill in the info structure and allows call sites which must support the legacy case along with more modern mechanism to select the domain type via the parameters of the info struct. [ tglx: Massaged change log ] Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Matti Vaittinen <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/32d07bd79eb2b5416e24da9e9e8fe5955423dcf9.1723120028.git.mazziesaccount@gmail.com
1 parent 8400291 commit 70114e7

File tree

2 files changed

+46
-33
lines changed

2 files changed

+46
-33
lines changed

include/linux/irqdomain.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ struct irq_domain_chip_generic_info;
291291
* @hwirq_max: Maximum number of interrupts supported by controller
292292
* @direct_max: Maximum value of direct maps;
293293
* Use ~0 for no limit; 0 for no direct mapping
294+
* @hwirq_base: The first hardware interrupt number (legacy domains only)
295+
* @virq_base: The first Linux interrupt number for legacy domains to
296+
* immediately associate the interrupts after domain creation
294297
* @bus_token: Domain bus token
295298
* @ops: Domain operation callbacks
296299
* @host_data: Controller private data pointer
@@ -307,6 +310,8 @@ struct irq_domain_info {
307310
unsigned int size;
308311
irq_hw_number_t hwirq_max;
309312
int direct_max;
313+
unsigned int hwirq_base;
314+
unsigned int virq_base;
310315
enum irq_domain_bus_token bus_token;
311316
const struct irq_domain_ops *ops;
312317
void *host_data;

kernel/irq/irqdomain.c

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,20 @@ static void irq_domain_free(struct irq_domain *domain)
267267
kfree(domain);
268268
}
269269

270-
/**
271-
* irq_domain_instantiate() - Instantiate a new irq domain data structure
272-
* @info: Domain information pointer pointing to the information for this domain
273-
*
274-
* Return: A pointer to the instantiated irq domain or an ERR_PTR value.
275-
*/
276-
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
270+
static void irq_domain_instantiate_descs(const struct irq_domain_info *info)
271+
{
272+
if (!IS_ENABLED(CONFIG_SPARSE_IRQ))
273+
return;
274+
275+
if (irq_alloc_descs(info->virq_base, info->virq_base, info->size,
276+
of_node_to_nid(to_of_node(info->fwnode))) < 0) {
277+
pr_info("Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
278+
info->virq_base);
279+
}
280+
}
281+
282+
static struct irq_domain *__irq_domain_instantiate(const struct irq_domain_info *info,
283+
bool cond_alloc_descs)
277284
{
278285
struct irq_domain *domain;
279286
int err;
@@ -306,6 +313,15 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
306313

307314
__irq_domain_publish(domain);
308315

316+
if (cond_alloc_descs && info->virq_base > 0)
317+
irq_domain_instantiate_descs(info);
318+
319+
/* Legacy interrupt domains have a fixed Linux interrupt number */
320+
if (info->virq_base > 0) {
321+
irq_domain_associate_many(domain, info->virq_base, info->hwirq_base,
322+
info->size - info->hwirq_base);
323+
}
324+
309325
return domain;
310326

311327
err_domain_gc_remove:
@@ -315,6 +331,17 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
315331
irq_domain_free(domain);
316332
return ERR_PTR(err);
317333
}
334+
335+
/**
336+
* irq_domain_instantiate() - Instantiate a new irq domain data structure
337+
* @info: Domain information pointer pointing to the information for this domain
338+
*
339+
* Return: A pointer to the instantiated irq domain or an ERR_PTR value.
340+
*/
341+
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
342+
{
343+
return __irq_domain_instantiate(info, false);
344+
}
318345
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
319346

320347
/**
@@ -413,28 +440,13 @@ struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
413440
.fwnode = fwnode,
414441
.size = size,
415442
.hwirq_max = size,
443+
.virq_base = first_irq,
416444
.ops = ops,
417445
.host_data = host_data,
418446
};
419-
struct irq_domain *domain;
420-
421-
domain = irq_domain_instantiate(&info);
422-
if (IS_ERR(domain))
423-
return NULL;
447+
struct irq_domain *domain = __irq_domain_instantiate(&info, true);
424448

425-
if (first_irq > 0) {
426-
if (IS_ENABLED(CONFIG_SPARSE_IRQ)) {
427-
/* attempt to allocated irq_descs */
428-
int rc = irq_alloc_descs(first_irq, first_irq, size,
429-
of_node_to_nid(to_of_node(fwnode)));
430-
if (rc < 0)
431-
pr_info("Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
432-
first_irq);
433-
}
434-
irq_domain_associate_many(domain, first_irq, 0, size);
435-
}
436-
437-
return domain;
449+
return IS_ERR(domain) ? NULL : domain;
438450
}
439451
EXPORT_SYMBOL_GPL(irq_domain_create_simple);
440452

@@ -476,18 +488,14 @@ struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
476488
.fwnode = fwnode,
477489
.size = first_hwirq + size,
478490
.hwirq_max = first_hwirq + size,
491+
.hwirq_base = first_hwirq,
492+
.virq_base = first_irq,
479493
.ops = ops,
480494
.host_data = host_data,
481495
};
482-
struct irq_domain *domain;
496+
struct irq_domain *domain = irq_domain_instantiate(&info);
483497

484-
domain = irq_domain_instantiate(&info);
485-
if (IS_ERR(domain))
486-
return NULL;
487-
488-
irq_domain_associate_many(domain, first_irq, first_hwirq, size);
489-
490-
return domain;
498+
return IS_ERR(domain) ? NULL : domain;
491499
}
492500
EXPORT_SYMBOL_GPL(irq_domain_create_legacy);
493501

0 commit comments

Comments
 (0)