Commit 553b75d4 authored by Mathieu Dubois-Briand's avatar Mathieu Dubois-Briand Committed by Lee Jones
Browse files

gpio: regmap: Allow to allocate regmap-irq device



GPIO controller often have support for IRQ: allow to easily allocate
both gpio-regmap and regmap-irq in one operation.

Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: default avatarMathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Link: https://lore.kernel.org/r/20250824-mdb-max7360-support-v14-5-435cfda2b1ea@bootlin.com


Signed-off-by: default avatarLee Jones <lee@kernel.org>
parent d93a75d9
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@ struct gpio_regmap {
	unsigned int reg_dir_in_base;
	unsigned int reg_dir_out_base;

#ifdef CONFIG_REGMAP_IRQ
	int regmap_irq_line;
	struct regmap_irq_chip_data *irq_chip_data;
#endif

	int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
			      unsigned int offset, unsigned int *reg,
			      unsigned int *mask);
@@ -215,6 +220,7 @@ EXPORT_SYMBOL_GPL(gpio_regmap_get_drvdata);
 */
struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config)
{
	struct irq_domain *irq_domain;
	struct gpio_regmap *gpio;
	struct gpio_chip *chip;
	int ret;
@@ -295,8 +301,22 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
	if (ret < 0)
		goto err_free_gpio;

	if (config->irq_domain) {
		ret = gpiochip_irqchip_add_domain(chip, config->irq_domain);
#ifdef CONFIG_REGMAP_IRQ
	if (config->regmap_irq_chip) {
		gpio->regmap_irq_line = config->regmap_irq_line;
		ret = regmap_add_irq_chip_fwnode(dev_fwnode(config->parent), config->regmap,
						 config->regmap_irq_line, config->regmap_irq_flags,
						 0, config->regmap_irq_chip, &gpio->irq_chip_data);
		if (ret)
			goto err_free_gpio;

		irq_domain = regmap_irq_get_domain(gpio->irq_chip_data);
	} else
#endif
	irq_domain = config->irq_domain;

	if (irq_domain) {
		ret = gpiochip_irqchip_add_domain(chip, irq_domain);
		if (ret)
			goto err_remove_gpiochip;
	}
@@ -317,6 +337,11 @@ EXPORT_SYMBOL_GPL(gpio_regmap_register);
 */
void gpio_regmap_unregister(struct gpio_regmap *gpio)
{
#ifdef CONFIG_REGMAP_IRQ
	if (gpio->irq_chip_data)
		regmap_del_irq_chip(gpio->regmap_irq_line, gpio->irq_chip_data);
#endif

	gpiochip_remove(&gpio->gpio_chip);
	kfree(gpio);
}
+11 −0
Original line number Diff line number Diff line
@@ -40,6 +40,11 @@ struct regmap;
 * @drvdata:		(Optional) Pointer to driver specific data which is
 *			not used by gpio-remap but is provided "as is" to the
 *			driver callback(s).
 * @regmap_irq_chip:	(Optional) Pointer on an regmap_irq_chip structure. If
 *			set, a regmap-irq device will be created and the IRQ
 *			domain will be set accordingly.
 * @regmap_irq_line	(Optional) The IRQ the device uses to signal interrupts.
 * @regmap_irq_flags	(Optional) The IRQF_ flags to use for the interrupt.
 *
 * The ->reg_mask_xlate translates a given base address and GPIO offset to
 * register and mask pair. The base address is one of the given register
@@ -78,6 +83,12 @@ struct gpio_regmap_config {
	int ngpio_per_reg;
	struct irq_domain *irq_domain;

#ifdef CONFIG_REGMAP_IRQ
	struct regmap_irq_chip *regmap_irq_chip;
	int regmap_irq_line;
	unsigned long regmap_irq_flags;
#endif

	int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
			      unsigned int offset, unsigned int *reg,
			      unsigned int *mask);