Re: [PATCH v3 5/5] pinctrl: renesas: pinctrl-rzg2l: Add IRQ domain to handle GPIO interrupt

Lad, Prabhakar
2022-05-12T17:36:52Z

Hi Geert,

Thank you for the review.

On Thu, May 12, 2022 at 8:39 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Prabhakar,
>
> On Wed, May 11, 2022 at 8:32 PM Lad Prabhakar
> <prabhakar.mahadev-lad.rj@bp.renesas.com> wrote:
> > Add IRQ domian to RZ/G2L pinctrl driver to handle GPIO interrupt.
>
> domain
>
ouch.

> > GPIO0-GPIO122 pins can be used as IRQ lines but only 32 pins can be
> > used as IRQ lines at given time. Selection of pins as IRQ lines
>
> at a given time
>
will fix that.

> > is handled by IA55 (which is the IRQC block) which sits in between the
> > GPIO and GIC.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
>
> Thanks for your patch!
>
> > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
>
> > static int rzg2l_gpio_register(struct rzg2l_pinctrl *pctrl)
> > {
> > struct device_node *np = pctrl->dev->of_node;
> > struct gpio_chip *chip = &pctrl->gpio_chip;
> > const char *name = dev_name(pctrl->dev);
> > + struct irq_domain *parent_domain;
> > struct of_phandle_args of_args;
> > + struct device_node *parent_np;
> > + struct gpio_irq_chip *girq;
> > int ret;
> >
> > + parent_np = of_irq_find_parent(np);
> > + if (!parent_np)
> > + return -ENXIO;
> > +
> > + parent_domain = irq_find_host(parent_np);
> > + of_node_put(parent_np);
> > + if (!parent_domain)
> > + return -EPROBE_DEFER;
> > +
> > ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &of_args);
> > if (ret) {
> > dev_err(pctrl->dev, "Unable to parse gpio-ranges\n");
> > @@ -1138,6 +1330,15 @@ static int rzg2l_gpio_register(struct rzg2l_pinctrl *pctrl)
> > chip->base = -1;
> > chip->ngpio = of_args.args[2];
> >
> > + girq = &chip->irq;
> > + girq->chip = &rzg2l_gpio_irqchip;
> > + girq->fwnode = of_node_to_fwnode(np);
> > + girq->parent_domain = parent_domain;
> > + girq->child_to_parent_hwirq = rzg2l_gpio_child_to_parent_hwirq;
> > + girq->populate_parent_alloc_arg = rzg2l_gpio_populate_parent_fwspec;
> > + girq->child_irq_domain_ops.free = rzg2l_gpio_irq_domain_free;
> > + girq->ngirq = RZG2L_TINT_MAX_INTERRUPT;
> > +
>
> I think you need to provide a .init_valid_mask() callback, as
> gpiochip_irqchip_remove() relies on that for destroying interrupts.
Are you suggesting the callback to avoid looping through all the GPIO pins?

> However, the mask will need to be dynamic, as GPIO interrupts can be
> mapped and unmapped to one of the 32 available interrupts dynamically,
> right?
Yep that's correct.

> I'm not sure if that can be done easily: if gpiochip_irqchip_irq_valid()
> is ever called too early, before the mapping is done, it would fail.
>
The mask initialization is a one time process and that is during
adding the GPIO chip. At this stage we won't be knowing what will be
the valid GPIO pins used as interrupts. Maybe the core needs to
implement a callback which lands in the GPIO controller driver to tell
if the gpio irq line is valid. This way we can handle dynamic
interrupts.

Cheers,
Prabhakar

> > pctrl->gpio_range.id = 0;
> > pctrl->gpio_range.pin_base = 0;
> > pctrl->gpio_range.base = 0;
>
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds