[PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device

Mathieu Dubois-Briand posted 11 patches 9 months ago
There is a newer version of this series
[PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Mathieu Dubois-Briand 9 months ago
GPIO controller often have support for IRQ: allow to easily allocate
both gpio-regmap and regmap-irq in one operation.

Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
---
 drivers/gpio/gpio-regmap.c  | 23 +++++++++++++++++++++--
 include/linux/gpio/regmap.h | 15 +++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
index 05f8781b5204..61d5f48b445d 100644
--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -203,6 +203,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;
@@ -280,8 +281,26 @@ 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);
+	irq_domain = config->irq_domain;
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+	if (config->regmap_irq_chip) {
+		struct regmap_irq_chip_data *irq_chip_data;
+
+		ret = devm_regmap_add_irq_chip_fwnode(config->parent, dev_fwnode(config->parent),
+						      config->regmap, config->regmap_irq_irqno,
+						      config->regmap_irq_flags, 0,
+						      config->regmap_irq_chip, &irq_chip_data);
+		if (ret)
+			goto err_free_gpio;
+
+		irq_domain = regmap_irq_get_domain(irq_chip_data);
+		if (config->regmap_irq_chip_data)
+			*config->regmap_irq_chip_data = irq_chip_data;
+	}
+#endif
+
+	if (irq_domain) {
+		ret = gpiochip_irqchip_add_domain(chip, irq_domain);
 		if (ret)
 			goto err_remove_gpiochip;
 	}
diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
index a9f7b7faf57b..55df2527b982 100644
--- a/include/linux/gpio/regmap.h
+++ b/include/linux/gpio/regmap.h
@@ -40,6 +40,14 @@ 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_chip_data: (Optional) Pointer on an regmap_irq_chip_data
+ *                      structure pointer. If set, it will be populated with a
+ *                      pointer on allocated regmap_irq data.
+ * @regmap_irq_irqno	(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 +86,13 @@ struct gpio_regmap_config {
 	int ngpio_per_reg;
 	struct irq_domain *irq_domain;
 
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+	struct regmap_irq_chip *regmap_irq_chip;
+	struct regmap_irq_chip_data **regmap_irq_chip_data;
+	int regmap_irq_irqno;
+	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);

-- 
2.39.5
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Michael Walle 9 months ago
Hi,

> GPIO controller often have support for IRQ: allow to easily allocate
> both gpio-regmap and regmap-irq in one operation.
>
> Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
> ---
>  drivers/gpio/gpio-regmap.c  | 23 +++++++++++++++++++++--
>  include/linux/gpio/regmap.h | 15 +++++++++++++++
>  2 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
> index 05f8781b5204..61d5f48b445d 100644
> --- a/drivers/gpio/gpio-regmap.c
> +++ b/drivers/gpio/gpio-regmap.c
> @@ -203,6 +203,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;
> @@ -280,8 +281,26 @@ 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);
> +	irq_domain = config->irq_domain;
> +#ifdef CONFIG_GPIOLIB_IRQCHIP

Why do we need this ifdef?

> +	if (config->regmap_irq_chip) {
> +		struct regmap_irq_chip_data *irq_chip_data;
> +
> +		ret = devm_regmap_add_irq_chip_fwnode(config->parent, dev_fwnode(config->parent),
> +						      config->regmap, config->regmap_irq_irqno,
> +						      config->regmap_irq_flags, 0,
> +						      config->regmap_irq_chip, &irq_chip_data);
> +		if (ret)
> +			goto err_free_gpio;
> +
> +		irq_domain = regmap_irq_get_domain(irq_chip_data);
> +		if (config->regmap_irq_chip_data)
> +			*config->regmap_irq_chip_data = irq_chip_data;

I'm not a fan of misusing the config to return any data. Can we have
a normal gpio_regmap_get_...()? Usually, the config is on the stack
of the caller, what if you need to get irq_chip_data afterwards?
Then your caller has to save it somewhere.

Also, what is the advantage of this? Your caller doesn't have to
call devm_regmap_add_irq_chip_fwnode(), but on the flip side you
have to cram all its parameters in the gpio_regmap config. I'd like
to keep that small and simple (but still extensible!). IMHO just
setting the irq_domain is enough to achieve that.

-michael

> +	}
> +#endif
> +
> +	if (irq_domain) {
> +		ret = gpiochip_irqchip_add_domain(chip, irq_domain);
>  		if (ret)
>  			goto err_remove_gpiochip;
>  	}
> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
> index a9f7b7faf57b..55df2527b982 100644
> --- a/include/linux/gpio/regmap.h
> +++ b/include/linux/gpio/regmap.h
> @@ -40,6 +40,14 @@ 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_chip_data: (Optional) Pointer on an regmap_irq_chip_data
> + *                      structure pointer. If set, it will be populated with a
> + *                      pointer on allocated regmap_irq data.
> + * @regmap_irq_irqno	(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 +86,13 @@ struct gpio_regmap_config {
>  	int ngpio_per_reg;
>  	struct irq_domain *irq_domain;
>  
> +#ifdef CONFIG_GPIOLIB_IRQCHIP
> +	struct regmap_irq_chip *regmap_irq_chip;
> +	struct regmap_irq_chip_data **regmap_irq_chip_data;
> +	int regmap_irq_irqno;
> +	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);
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Mathieu Dubois-Briand 9 months ago
On Wed Mar 19, 2025 at 8:15 AM CET, Michael Walle wrote:
> Hi,
>
> > GPIO controller often have support for IRQ: allow to easily allocate
> > both gpio-regmap and regmap-irq in one operation.
> >
> > Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
> > ---
> >  drivers/gpio/gpio-regmap.c  | 23 +++++++++++++++++++++--
> >  include/linux/gpio/regmap.h | 15 +++++++++++++++
> >  2 files changed, 36 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
> > index 05f8781b5204..61d5f48b445d 100644
> > --- a/drivers/gpio/gpio-regmap.c
> > +++ b/drivers/gpio/gpio-regmap.c
> > @@ -203,6 +203,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;
> > @@ -280,8 +281,26 @@ 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);
> > +	irq_domain = config->irq_domain;
> > +#ifdef CONFIG_GPIOLIB_IRQCHIP
>
> Why do we need this ifdef?
>

Hum yes, on second thought we probably need to depend on
CONFIG_REGMAP_IRQ here.

> > +	if (config->regmap_irq_chip) {
> > +		struct regmap_irq_chip_data *irq_chip_data;
> > +
> > +		ret = devm_regmap_add_irq_chip_fwnode(config->parent, dev_fwnode(config->parent),
> > +						      config->regmap, config->regmap_irq_irqno,
> > +						      config->regmap_irq_flags, 0,
> > +						      config->regmap_irq_chip, &irq_chip_data);
> > +		if (ret)
> > +			goto err_free_gpio;
> > +
> > +		irq_domain = regmap_irq_get_domain(irq_chip_data);
> > +		if (config->regmap_irq_chip_data)
> > +			*config->regmap_irq_chip_data = irq_chip_data;
>
> I'm not a fan of misusing the config to return any data. Can we have
> a normal gpio_regmap_get_...()? Usually, the config is on the stack
> of the caller, what if you need to get irq_chip_data afterwards?
> Then your caller has to save it somewhere.
>

Yes, makes sense. As suggested by Andy Shevchenko, I will remove this
parameter as there is no user today: a way to retrieve it can be added
later if needed.

> Also, what is the advantage of this? Your caller doesn't have to
> call devm_regmap_add_irq_chip_fwnode(), but on the flip side you
> have to cram all its parameters in the gpio_regmap config. I'd like
> to keep that small and simple (but still extensible!). IMHO just
> setting the irq_domain is enough to achieve that.

This was a request from Andy on my previous series.

>
> -michael
>

Thanks for your review.
Mathieu

-- 
Mathieu Dubois-Briand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Michael Walle 8 months, 3 weeks ago
Hi,

> > > +#ifdef CONFIG_GPIOLIB_IRQCHIP
> >
> > Why do we need this ifdef?
> >
>
> Hum yes, on second thought we probably need to depend on
> CONFIG_REGMAP_IRQ here.

But then, you'd also require the regmap_irq support for chips that
don't support IRQs at all. devm_regmap_add_irq_fwnode() seems to be
missing a stub version.

-michael
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Mathieu Dubois-Briand 8 months, 3 weeks ago
On Tue Mar 25, 2025 at 8:50 AM CET, Michael Walle wrote:
> > > > +#ifdef CONFIG_GPIOLIB_IRQCHIP
> > >
> > > Why do we need this ifdef?
> > >
> >
> > Hum yes, on second thought we probably need to depend on
> > CONFIG_REGMAP_IRQ here.
>
> But then, you'd also require the regmap_irq support for chips that
> don't support IRQs at all. devm_regmap_add_irq_fwnode() seems to be
> missing a stub version.
>

Sorry, maybe my previous message was not clear, when I said "depend",
what I meant is having an "#ifdef CONFIG_REGMAP_IRQ" here in place of
"#ifdef CONFIG_GPIOLIB_IRQCHIP"

If CONFIG_REGMAP_IRQ is enabled, drivers/base/regmap/regmap-irq.c is
built, so we do have both devm_regmap_add_irq_chip_fwnode() and
regmap_irq_get_domain(). So this code block should compile and link
correctly.

I did some build tests with and without CONFIG_GPIOLIB_IRQCHIP and I
believe this is fine.

Or am I missing something?


-- 
Mathieu Dubois-Briand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Michael Walle 8 months, 3 weeks ago
On Wed Mar 26, 2025 at 12:00 PM CET, Mathieu Dubois-Briand wrote:
> On Tue Mar 25, 2025 at 8:50 AM CET, Michael Walle wrote:
> > > > > +#ifdef CONFIG_GPIOLIB_IRQCHIP
> > > >
> > > > Why do we need this ifdef?
> > > >
> > >
> > > Hum yes, on second thought we probably need to depend on
> > > CONFIG_REGMAP_IRQ here.
> >
> > But then, you'd also require the regmap_irq support for chips that
> > don't support IRQs at all. devm_regmap_add_irq_fwnode() seems to be
> > missing a stub version.
> >
>
> Sorry, maybe my previous message was not clear, when I said "depend",
> what I meant is having an "#ifdef CONFIG_REGMAP_IRQ" here in place of
> "#ifdef CONFIG_GPIOLIB_IRQCHIP"
>
> If CONFIG_REGMAP_IRQ is enabled, drivers/base/regmap/regmap-irq.c is
> built, so we do have both devm_regmap_add_irq_chip_fwnode() and
> regmap_irq_get_domain(). So this code block should compile and link
> correctly.

Yes.

> I did some build tests with and without CONFIG_GPIOLIB_IRQCHIP and I
> believe this is fine.
>
> Or am I missing something?

I'd like to avoid the ifdef macros if possible. Thus you'd need
stubs for devm_regmap_add_irq_chip_fwnode() and
regmap_irq_get_domain() if CONFIG_REGMAP_IRQ is not defined.

Not sure if broonie agrees though (?).

-michael
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Andy Shevchenko 9 months ago
On Thu, Mar 20, 2025 at 09:35:15AM +0100, Mathieu Dubois-Briand wrote:
> On Wed Mar 19, 2025 at 8:15 AM CET, Michael Walle wrote:

...

> > Also, what is the advantage of this? Your caller doesn't have to
> > call devm_regmap_add_irq_chip_fwnode(), but on the flip side you
> > have to cram all its parameters in the gpio_regmap config. I'd like
> > to keep that small and simple (but still extensible!). IMHO just
> > setting the irq_domain is enough to achieve that.
> 
> This was a request from Andy on my previous series.

The benefit is deduplication of a lot of code. You may consider it the same as
GPIO library does with IRQ chip. This is just the same on a different level.

Besides the driver in this series, I would think of other GPIO drivers that
are not (yet) converted to regmap (partially because of this is being absent)
or existing drivers, if any, that may utilise it.

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Michael Walle 8 months, 3 weeks ago
Hi,

> > > Also, what is the advantage of this? Your caller doesn't have to
> > > call devm_regmap_add_irq_chip_fwnode(), but on the flip side you
> > > have to cram all its parameters in the gpio_regmap config. I'd like
> > > to keep that small and simple (but still extensible!). IMHO just
> > > setting the irq_domain is enough to achieve that.
> > 
> > This was a request from Andy on my previous series.
>
> The benefit is deduplication of a lot of code. You may consider it the same as
> GPIO library does with IRQ chip. This is just the same on a different level.

I'd say "a lot of code" is slightly exaggerated :-) I was hesitant
because it sounded like a one-off for the regmap_irq support. There
could theoretically be other irq_domain providers (I think).

I just had a quick look at all the gpio_regmap drivers and they all
use regmap_irq. So maybe it's fair to say that one could be directly
supported within gpio_regmap.

> Besides the driver in this series, I would think of other GPIO drivers that
> are not (yet) converted to regmap (partially because of this is being absent)
> or existing drivers, if any, that may utilise it.

Yes probably all of the existing ones :)

-michael
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Andy Shevchenko 9 months ago
On Tue, Mar 18, 2025 at 05:26:22PM +0100, Mathieu Dubois-Briand wrote:
> GPIO controller often have support for IRQ: allow to easily allocate
> both gpio-regmap and regmap-irq in one operation.

...

> -	if (config->irq_domain) {
> -		ret = gpiochip_irqchip_add_domain(chip, config->irq_domain);

> +	irq_domain = config->irq_domain;

Better to move it into #else, so we avoid double assignment (see below).

> +#ifdef CONFIG_GPIOLIB_IRQCHIP
> +	if (config->regmap_irq_chip) {
> +		struct regmap_irq_chip_data *irq_chip_data;
> +
> +		ret = devm_regmap_add_irq_chip_fwnode(config->parent, dev_fwnode(config->parent),
> +						      config->regmap, config->regmap_irq_irqno,
> +						      config->regmap_irq_flags, 0,
> +						      config->regmap_irq_chip, &irq_chip_data);
> +		if (ret)
> +			goto err_free_gpio;
> +
> +		irq_domain = regmap_irq_get_domain(irq_chip_data);
> +		if (config->regmap_irq_chip_data)
> +			*config->regmap_irq_chip_data = irq_chip_data;

Hmm... I was under impression that we don't need this to be returned.
Do we have any user of it right now? If not, no need to export until
it is needed.

> +	}

	} else

> +#endif

	irq_domain = config->irq_domain;

> +
> +	if (irq_domain) {
> +		ret = gpiochip_irqchip_add_domain(chip, irq_domain);
>  		if (ret)
>  			goto err_remove_gpiochip;
>  	}

...

> +#ifdef CONFIG_GPIOLIB_IRQCHIP
> +	struct regmap_irq_chip *regmap_irq_chip;
> +	struct regmap_irq_chip_data **regmap_irq_chip_data;

But why double pointer?

> +	int regmap_irq_irqno;
> +	unsigned long regmap_irq_flags;
> +#endif

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Mathieu Dubois-Briand 9 months ago
On Tue Mar 18, 2025 at 5:52 PM CET, Andy Shevchenko wrote:
> On Tue, Mar 18, 2025 at 05:26:22PM +0100, Mathieu Dubois-Briand wrote:
> > GPIO controller often have support for IRQ: allow to easily allocate
> > both gpio-regmap and regmap-irq in one operation.
>
> ...
>
> > -	if (config->irq_domain) {
> > -		ret = gpiochip_irqchip_add_domain(chip, config->irq_domain);
>
> > +	irq_domain = config->irq_domain;
>
> Better to move it into #else, so we avoid double assignment (see below).
>

OK

> > +#ifdef CONFIG_GPIOLIB_IRQCHIP
> > +	if (config->regmap_irq_chip) {
> > +		struct regmap_irq_chip_data *irq_chip_data;
> > +
> > +		ret = devm_regmap_add_irq_chip_fwnode(config->parent, dev_fwnode(config->parent),
> > +						      config->regmap, config->regmap_irq_irqno,
> > +						      config->regmap_irq_flags, 0,
> > +						      config->regmap_irq_chip, &irq_chip_data);
> > +		if (ret)
> > +			goto err_free_gpio;
> > +
> > +		irq_domain = regmap_irq_get_domain(irq_chip_data);
> > +		if (config->regmap_irq_chip_data)
> > +			*config->regmap_irq_chip_data = irq_chip_data;
>
> Hmm... I was under impression that we don't need this to be returned.
> Do we have any user of it right now? If not, no need to export until
> it is needed.
>

Right, I will remove it.

> > +	}
>
> 	} else
>
> > +#endif
>
> 	irq_domain = config->irq_domain;
>
> > +
> > +	if (irq_domain) {
> > +		ret = gpiochip_irqchip_add_domain(chip, irq_domain);
> >  		if (ret)
> >  			goto err_remove_gpiochip;
> >  	}
>
> ...
>
> > +#ifdef CONFIG_GPIOLIB_IRQCHIP
> > +	struct regmap_irq_chip *regmap_irq_chip;
> > +	struct regmap_irq_chip_data **regmap_irq_chip_data;
>
> But why double pointer?
>

I believe this has to be a double pointer, as it is going to be assigned
a pointer value: data buffer is allocated inside of
devm_regmap_add_irq_chip_fwnode().

But as you said, it's better to remove it and add it later if there is
an use case.

> > +	int regmap_irq_irqno;
> > +	unsigned long regmap_irq_flags;
> > +#endif

Thanks for your review.


-- 
Mathieu Dubois-Briand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH v5 06/11] gpio: regmap: Allow to allocate regmap-irq device
Posted by Andy Shevchenko 9 months ago
On Thu, Mar 20, 2025 at 08:55:57AM +0100, Mathieu Dubois-Briand wrote:
> On Tue Mar 18, 2025 at 5:52 PM CET, Andy Shevchenko wrote:
> > On Tue, Mar 18, 2025 at 05:26:22PM +0100, Mathieu Dubois-Briand wrote:

...

> > > +#ifdef CONFIG_GPIOLIB_IRQCHIP
> > > +	struct regmap_irq_chip *regmap_irq_chip;
> > > +	struct regmap_irq_chip_data **regmap_irq_chip_data;
> >
> > But why double pointer?
> 
> I believe this has to be a double pointer, as it is going to be assigned
> a pointer value: data buffer is allocated inside of
> devm_regmap_add_irq_chip_fwnode().

Yes, but it doesn't need to be a double one in the data structrure, right?

> But as you said, it's better to remove it and add it later if there is
> an use case.

This would be even better for now, thanks!

-- 
With Best Regards,
Andy Shevchenko