summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2024-08-13 17:47:04 +0100
committerMark Brown <broonie@kernel.org>2024-08-13 17:47:04 +0100
commitc69bb91c47e840c96ec4e72e7ebd982dd518441e (patch)
tree1db3c23698bdccaf26ab6ee0ccf0d8396152b4e6 /drivers/base
parent7c626ce4bae1ac14f60076d00eafe71af30450ba (diff)
parentdde286ee57704226b500cb9eb59547fec07aad3d (diff)
downloadlwn-c69bb91c47e840c96ec4e72e7ebd982dd518441e.tar.gz
lwn-c69bb91c47e840c96ec4e72e7ebd982dd518441e.zip
regmap IRQ support for devices with multiple IRQs
Merge series from Matti Vaittinen <mazziesaccount@gmail.com>: Devices can provide multiple interrupt lines. One reason for this is that a device has multiple subfunctions, each providing its own interrupt line. Another reason is that a device can be designed to be used (also) on a system where some of the interrupts can be routed to another processor. A line often further acts as a demultiplex for specific interrupts and has it's respective set of interrupt (status, mask, ack, ...) registers. Regmap supports the handling of these registers and demultiplexing interrupts, but interrupt domain code ends up assigning the same name for the per interrupt line domains This series adds possibility for giving a name suffix for an interrupt Previous discussion can be found from: https://lore.kernel.org/all/87plst28yk.ffs@tglx/ https://lore.kernel.org/all/15685ef6-92a5-41df-9148-1a67ceaec47b@gmail.com/ The domain suffix support added in this series will be used by the ROHM BD96801 ERRB IRQ support code. The BD96801 ERRB support will need the initial BD96801 driver code, which is not yet in irq/core or regmap trees. Thus the user for this new support is not included in the series, but will be sent once the name suffix support gets merged.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap-irq.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index d3ec1345b5b5..a750e48a26b8 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -608,6 +608,30 @@ int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
}
EXPORT_SYMBOL_GPL(regmap_irq_set_type_config_simple);
+static int regmap_irq_create_domain(struct fwnode_handle *fwnode, int irq_base,
+ const struct regmap_irq_chip *chip,
+ struct regmap_irq_chip_data *d)
+{
+ struct irq_domain_info info = {
+ .fwnode = fwnode,
+ .size = chip->num_irqs,
+ .hwirq_max = chip->num_irqs,
+ .virq_base = irq_base,
+ .ops = &regmap_domain_ops,
+ .host_data = d,
+ .name_suffix = chip->domain_suffix,
+ };
+
+ d->domain = irq_domain_instantiate(&info);
+ if (IS_ERR(d->domain)) {
+ dev_err(d->map->dev, "Failed to create IRQ domain\n");
+ return PTR_ERR(d->domain);
+ }
+
+ return 0;
+}
+
+
/**
* regmap_add_irq_chip_fwnode() - Use standard regmap IRQ controller handling
*
@@ -856,18 +880,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
}
}
- if (irq_base)
- d->domain = irq_domain_create_legacy(fwnode, chip->num_irqs,
- irq_base, 0,
- &regmap_domain_ops, d);
- else
- d->domain = irq_domain_create_linear(fwnode, chip->num_irqs,
- &regmap_domain_ops, d);
- if (!d->domain) {
- dev_err(map->dev, "Failed to create IRQ domain\n");
- ret = -ENOMEM;
+ ret = regmap_irq_create_domain(fwnode, irq_base, chip, d);
+ if (ret)
goto err_alloc;
- }
ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
irq_flags | IRQF_ONESHOT,