Unverified Commit 12479382 authored by Michael Walle's avatar Michael Walle Committed by Mark Brown
Browse files

regmap-irq: make it possible to add irq_chip do a specific device node



Add a new function regmap_add_irq_chip_np() with its corresponding
devm_regmap_add_irq_chip_np() variant. Sometimes one want to register
the IRQ domain on a different device node that the one of the regmap
node. For example when using a MFD where there are different interrupt
controllers and particularly for the generic regmap gpio_chip/irq_chip
driver. In this case it is not desireable to have the IRQ domain on
the parent node.

Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20200402203656.27047-5-michael@walle.cc


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8f3d9f35
Loading
Loading
Loading
Loading
+68 −16
Original line number Diff line number Diff line
@@ -541,8 +541,9 @@ static const struct irq_domain_ops regmap_domain_ops = {
};

/**
 * regmap_add_irq_chip() - Use standard regmap IRQ controller handling
 * regmap_add_irq_chip_np() - Use standard regmap IRQ controller handling
 *
 * @np: The device_node where the IRQ domain should be added to.
 * @map: The regmap for the device.
 * @irq: The IRQ the device uses to signal interrupts.
 * @irq_flags: The IRQF_ flags to use for the primary interrupt.
@@ -556,8 +557,9 @@ static const struct irq_domain_ops regmap_domain_ops = {
 * register cache.  The chip driver is responsible for restoring the
 * register values used by the IRQ controller over suspend and resume.
 */
int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
			int irq_base, const struct regmap_irq_chip *chip,
int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq,
			   int irq_flags, int irq_base,
			   const struct regmap_irq_chip *chip,
			   struct regmap_irq_chip_data **data)
{
	struct regmap_irq_chip_data *d;
@@ -769,12 +771,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
	}

	if (irq_base)
		d->domain = irq_domain_add_legacy(map->dev->of_node,
						  chip->num_irqs, irq_base, 0,
						  &regmap_domain_ops, d);
		d->domain = irq_domain_add_legacy(np, chip->num_irqs, irq_base,
						  0, &regmap_domain_ops, d);
	else
		d->domain = irq_domain_add_linear(map->dev->of_node,
						  chip->num_irqs,
		d->domain = irq_domain_add_linear(np, chip->num_irqs,
						  &regmap_domain_ops, d);
	if (!d->domain) {
		dev_err(map->dev, "Failed to create IRQ domain\n");
@@ -808,6 +808,30 @@ err_alloc:
	kfree(d);
	return ret;
}
EXPORT_SYMBOL_GPL(regmap_add_irq_chip_np);

/**
 * regmap_add_irq_chip() - Use standard regmap IRQ controller handling
 *
 * @map: The regmap for the device.
 * @irq: The IRQ the device uses to signal interrupts.
 * @irq_flags: The IRQF_ flags to use for the primary interrupt.
 * @irq_base: Allocate at specific IRQ number if irq_base > 0.
 * @chip: Configuration for the interrupt controller.
 * @data: Runtime data structure for the controller, allocated on success.
 *
 * Returns 0 on success or an errno on failure.
 *
 * This is the same as regmap_add_irq_chip_np, except that the device
 * node of the regmap is used.
 */
int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
			int irq_base, const struct regmap_irq_chip *chip,
			struct regmap_irq_chip_data **data)
{
	return regmap_add_irq_chip_np(map->dev->of_node, map, irq, irq_flags,
				      irq_base, chip, data);
}
EXPORT_SYMBOL_GPL(regmap_add_irq_chip);

/**
@@ -875,9 +899,10 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
}

/**
 * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
 * devm_regmap_add_irq_chip_np() - Resource manager regmap_add_irq_chip_np()
 *
 * @dev: The device pointer on which irq_chip belongs to.
 * @np: The device_node where the IRQ domain should be added to.
 * @map: The regmap for the device.
 * @irq: The IRQ the device uses to signal interrupts
 * @irq_flags: The IRQF_ flags to use for the primary interrupt.
@@ -890,8 +915,9 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
 * The &regmap_irq_chip_data will be automatically released when the device is
 * unbound.
 */
int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
			     int irq_flags, int irq_base,
int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np,
				struct regmap *map, int irq, int irq_flags,
				int irq_base,
				const struct regmap_irq_chip *chip,
				struct regmap_irq_chip_data **data)
{
@@ -903,7 +929,7 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
	if (!ptr)
		return -ENOMEM;

	ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base,
	ret = regmap_add_irq_chip_np(np, map, irq, irq_flags, irq_base,
				     chip, &d);
	if (ret < 0) {
		devres_free(ptr);
@@ -915,6 +941,32 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
	*data = d;
	return 0;
}
EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip_np);

/**
 * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
 *
 * @dev: The device pointer on which irq_chip belongs to.
 * @map: The regmap for the device.
 * @irq: The IRQ the device uses to signal interrupts
 * @irq_flags: The IRQF_ flags to use for the primary interrupt.
 * @irq_base: Allocate at specific IRQ number if irq_base > 0.
 * @chip: Configuration for the interrupt controller.
 * @data: Runtime data structure for the controller, allocated on success
 *
 * Returns 0 on success or an errno on failure.
 *
 * The &regmap_irq_chip_data will be automatically released when the device is
 * unbound.
 */
int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
			     int irq_flags, int irq_base,
			     const struct regmap_irq_chip *chip,
			     struct regmap_irq_chip_data **data)
{
	return devm_regmap_add_irq_chip_np(dev, map->dev->of_node, map, irq,
					   irq_flags, irq_base, chip, data);
}
EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip);

/**
+10 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
struct module;
struct clk;
struct device;
struct device_node;
struct i2c_client;
struct i3c_device;
struct irq_domain;
@@ -1310,12 +1311,21 @@ struct regmap_irq_chip_data;
int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
			int irq_base, const struct regmap_irq_chip *chip,
			struct regmap_irq_chip_data **data);
int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq,
			   int irq_flags, int irq_base,
			   const struct regmap_irq_chip *chip,
			   struct regmap_irq_chip_data **data);
void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data);

int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
			     int irq_flags, int irq_base,
			     const struct regmap_irq_chip *chip,
			     struct regmap_irq_chip_data **data);
int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np,
				struct regmap *map, int irq, int irq_flags,
				int irq_base,
				const struct regmap_irq_chip *chip,
				struct regmap_irq_chip_data **data);
void devm_regmap_del_irq_chip(struct device *dev, int irq,
			      struct regmap_irq_chip_data *data);