Skip to content

Commit e25f553

Browse files
hcodinaKAGA-KOKO
authored andcommitted
genirq/generic_chip: Introduce irq_domain_{alloc,remove}_generic_chips()
The existing __irq_alloc_domain_generic_chips() uses a bunch of parameters to describe the generic chips that need to be allocated. Adding more parameters and wrappers to hide new parameters in the existing code leads to more and more code without any relevant values and without any flexibility. Introduce irq_domain_alloc_generic_chips() where the generic chips description is done using the irq_domain_chip_generic_info structure instead of the bunch of parameters to allow flexibility and easy evolution. Also introduce irq_domain_remove_generic_chips() to revert the operations done by irq_domain_alloc_generic_chips(). 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 44b68de commit e25f553

File tree

2 files changed

+93
-23
lines changed

2 files changed

+93
-23
lines changed

include/linux/irq.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,27 @@ struct irq_domain_chip_generic {
11171117
struct irq_chip_generic *gc[];
11181118
};
11191119

1120+
/**
1121+
* struct irq_domain_chip_generic_info - Generic chip information structure
1122+
* @name: Name of the generic interrupt chip
1123+
* @handler: Interrupt handler used by the generic interrupt chip
1124+
* @irqs_per_chip: Number of interrupts each chip handles (max 32)
1125+
* @num_ct: Number of irq_chip_type instances associated with each
1126+
* chip
1127+
* @irq_flags_to_clear: IRQ_* bits to clear in the mapping function
1128+
* @irq_flags_to_set: IRQ_* bits to set in the mapping function
1129+
* @gc_flags: Generic chip specific setup flags
1130+
*/
1131+
struct irq_domain_chip_generic_info {
1132+
const char *name;
1133+
irq_flow_handler_t handler;
1134+
unsigned int irqs_per_chip;
1135+
unsigned int num_ct;
1136+
unsigned int irq_flags_to_clear;
1137+
unsigned int irq_flags_to_set;
1138+
enum irq_gc_flags gc_flags;
1139+
};
1140+
11201141
/* Generic chip callback functions */
11211142
void irq_gc_noop(struct irq_data *d);
11221143
void irq_gc_mask_disable_reg(struct irq_data *d);
@@ -1153,6 +1174,10 @@ int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
11531174

11541175
struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
11551176

1177+
int irq_domain_alloc_generic_chips(struct irq_domain *d,
1178+
const struct irq_domain_chip_generic_info *info);
1179+
void irq_domain_remove_generic_chips(struct irq_domain *d);
1180+
11561181
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
11571182
int num_ct, const char *name,
11581183
irq_flow_handler_t handler,

kernel/irq/generic-chip.c

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -276,21 +276,14 @@ irq_gc_init_mask_cache(struct irq_chip_generic *gc, enum irq_gc_flags flags)
276276
}
277277

278278
/**
279-
* __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
280-
* @d: irq domain for which to allocate chips
281-
* @irqs_per_chip: Number of interrupts each chip handles (max 32)
282-
* @num_ct: Number of irq_chip_type instances associated with this
283-
* @name: Name of the irq chip
284-
* @handler: Default flow handler associated with these chips
285-
* @clr: IRQ_* bits to clear in the mapping function
286-
* @set: IRQ_* bits to set in the mapping function
287-
* @gcflags: Generic chip specific setup flags
279+
* irq_domain_alloc_generic_chips - Allocate generic chips for an irq domain
280+
* @d: irq domain for which to allocate chips
281+
* @info: Generic chip information
282+
*
283+
* Return: 0 on success, negative error code on failure
288284
*/
289-
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
290-
int num_ct, const char *name,
291-
irq_flow_handler_t handler,
292-
unsigned int clr, unsigned int set,
293-
enum irq_gc_flags gcflags)
285+
int irq_domain_alloc_generic_chips(struct irq_domain *d,
286+
const struct irq_domain_chip_generic_info *info)
294287
{
295288
struct irq_domain_chip_generic *dgc;
296289
struct irq_chip_generic *gc;
@@ -304,35 +297,36 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
304297
if (d->gc)
305298
return -EBUSY;
306299

307-
numchips = DIV_ROUND_UP(d->revmap_size, irqs_per_chip);
300+
numchips = DIV_ROUND_UP(d->revmap_size, info->irqs_per_chip);
308301
if (!numchips)
309302
return -EINVAL;
310303

311304
/* Allocate a pointer, generic chip and chiptypes for each chip */
312-
gc_sz = struct_size(gc, chip_types, num_ct);
305+
gc_sz = struct_size(gc, chip_types, info->num_ct);
313306
dgc_sz = struct_size(dgc, gc, numchips);
314307
sz = dgc_sz + numchips * gc_sz;
315308

316309
tmp = dgc = kzalloc(sz, GFP_KERNEL);
317310
if (!dgc)
318311
return -ENOMEM;
319-
dgc->irqs_per_chip = irqs_per_chip;
312+
dgc->irqs_per_chip = info->irqs_per_chip;
320313
dgc->num_chips = numchips;
321-
dgc->irq_flags_to_set = set;
322-
dgc->irq_flags_to_clear = clr;
323-
dgc->gc_flags = gcflags;
314+
dgc->irq_flags_to_set = info->irq_flags_to_set;
315+
dgc->irq_flags_to_clear = info->irq_flags_to_clear;
316+
dgc->gc_flags = info->gc_flags;
324317
d->gc = dgc;
325318

326319
/* Calc pointer to the first generic chip */
327320
tmp += dgc_sz;
328321
for (i = 0; i < numchips; i++) {
329322
/* Store the pointer to the generic chip */
330323
dgc->gc[i] = gc = tmp;
331-
irq_init_generic_chip(gc, name, num_ct, i * irqs_per_chip,
332-
NULL, handler);
324+
irq_init_generic_chip(gc, info->name, info->num_ct,
325+
i * dgc->irqs_per_chip, NULL,
326+
info->handler);
333327

334328
gc->domain = d;
335-
if (gcflags & IRQ_GC_BE_IO) {
329+
if (dgc->gc_flags & IRQ_GC_BE_IO) {
336330
gc->reg_readl = &irq_readl_be;
337331
gc->reg_writel = &irq_writel_be;
338332
}
@@ -345,6 +339,57 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
345339
}
346340
return 0;
347341
}
342+
EXPORT_SYMBOL_GPL(irq_domain_alloc_generic_chips);
343+
344+
/**
345+
* irq_domain_remove_generic_chips - Remove generic chips from an irq domain
346+
* @d: irq domain for which generic chips are to be removed
347+
*/
348+
void irq_domain_remove_generic_chips(struct irq_domain *d)
349+
{
350+
struct irq_domain_chip_generic *dgc = d->gc;
351+
unsigned int i;
352+
353+
if (!dgc)
354+
return;
355+
356+
for (i = 0; i < dgc->num_chips; i++)
357+
irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0);
358+
359+
d->gc = NULL;
360+
kfree(dgc);
361+
}
362+
EXPORT_SYMBOL_GPL(irq_domain_remove_generic_chips);
363+
364+
/**
365+
* __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
366+
* @d: irq domain for which to allocate chips
367+
* @irqs_per_chip: Number of interrupts each chip handles (max 32)
368+
* @num_ct: Number of irq_chip_type instances associated with this
369+
* @name: Name of the irq chip
370+
* @handler: Default flow handler associated with these chips
371+
* @clr: IRQ_* bits to clear in the mapping function
372+
* @set: IRQ_* bits to set in the mapping function
373+
* @gcflags: Generic chip specific setup flags
374+
*/
375+
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
376+
int num_ct, const char *name,
377+
irq_flow_handler_t handler,
378+
unsigned int clr, unsigned int set,
379+
enum irq_gc_flags gcflags)
380+
{
381+
struct irq_domain_chip_generic_info info = {
382+
.irqs_per_chip = irqs_per_chip,
383+
.num_ct = num_ct,
384+
.name = name,
385+
.handler = handler,
386+
.irq_flags_to_clear = clr,
387+
.irq_flags_to_set = set,
388+
.gc_flags = gcflags,
389+
};
390+
391+
return irq_domain_alloc_generic_chips(d, &info);
392+
}
348393
EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips);
349394

350395
static struct irq_chip_generic *

0 commit comments

Comments
 (0)