All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Marc Zyngier <maz@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Bartosz Golaszewski <brgl@bgdev.pl>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	"open list:GPIO SUBSYSTEM" <linux-gpio@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linux-Renesas <linux-renesas-soc@vger.kernel.org>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" 
	<devicetree@vger.kernel.org>,
	Phil Edworthy <phil.edworthy@renesas.com>,
	Biju Das <biju.das.jz@bp.renesas.com>
Subject: Re: [PATCH v3 5/5] pinctrl: renesas: pinctrl-rzg2l: Add IRQ domain to handle GPIO interrupt
Date: Fri, 13 May 2022 19:13:29 +0100	[thread overview]
Message-ID: <CA+V-a8uXakF45TLvpsfeAY_EZKDGHr-wfgqLR_LTz1ZAo8FYmg@mail.gmail.com> (raw)
In-Reply-To: <CAMuHMdXHJ385isGd-x8u4sFm1w=rxOC89SUryYbSd34bijkb0g@mail.gmail.com>

Hi Geert

On Fri, May 13, 2022 at 3:29 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Prabhakar,
>
> On Fri, May 13, 2022 at 3:56 PM Lad, Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
> > On Fri, May 13, 2022 at 7:53 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > > On Thu, May 12, 2022 at 7:36 PM Lad, Prabhakar
> > > <prabhakar.csengg@gmail.com> wrote:
> > > > On Thu, May 12, 2022 at 8:39 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > > > > 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.
> > > > > > 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
> > > > > > 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?
> > >
> > > gpiochip_irqchip_remove() does:
> > >
> > >         /* Remove all IRQ mappings and delete the domain */
> > >         if (gc->irq.domain) {
> > >                 unsigned int irq;
> > >
> > >                 for (offset = 0; offset < gc->ngpio; offset++) {
> > >                        if (!gpiochip_irqchip_irq_valid(gc, offset))
> > >                                 continue;
> > >
> > >                         irq = irq_find_mapping(gc->irq.domain, offset);
> > >                         irq_dispose_mapping(irq);
> > >                 }
> > >
> > >                 irq_domain_remove(gc->irq.domain);
> > >
> > >         }
> > >
> > > The main thing is not about avoiding to loop through all GPIO pins,
> > > but to avoid irq_{find,dispose}_mapping() doing the wrong thing.
> > So in our case if we don't implement valid masks, that would mean all
> > the pins are valid. irq_find_mapping() would return 0 if no mapping is
> > found to the corresponding offset and irq_dispose_mapping() would
> > simply return back without doing anything if virq == 0.(In this patch
> > rzg2l_gpio_free() does call irq_{find,dispose}_mapping())
>
> But "offset" is a number from the GPIO offset space (0-122), while

The "offset" reported by kernel is 120-511:

root@smarc-rzg2l:~# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 120-511, parent: platform/11030000.pinctrl, 11030000.pinctrl:
 gpio-120 (P0_0                )
 gpio-121 (P0_1                )
 gpio-122 (P0_2                )
 gpio-123 (P0_3                )
 gpio-124 (P0_4                )
.....
 gpio-507 (P48_3               )
 gpio-508 (P48_4               )
 gpio-509 (P48_5               )
 gpio-510 (P48_6               )
 gpio-511 (P48_7               )

> irq_find_mapping() expects a number from the domain's IRQ space,
> which is only 0-31?
>
Nope, let me demonstrate with an example, I have configured the gpio
pins as GPIO keys in DTS:

+       keyboard {
+               compatible = "gpio-keys";
+               status = "okay";
+
+               key-1 {
+                       gpios = <&pinctrl RZG2L_GPIO(43, 0) GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_1>;
+                       linux,input-type = <EV_KEY>;
+                       wakeup-source;
+                       label = "SW1";
+               };
+
+               key-2 {
+                       gpios = <&pinctrl RZG2L_GPIO(41, 0) GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_2>;
+                       linux,input-type = <EV_KEY>;
+                       wakeup-source;
+                       label = "SW2";
+               };
+
+               key-3 {
+                       gpios = <&pinctrl RZG2L_GPIO(43, 1) GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_3>;
+                       linux,input-type = <EV_KEY>;
+                       wakeup-source;
+                       label = "SW3";
+               };
+       };

root@smarc-rzg2l:~# cat /proc/interrupts | grep SW
root@smarc-rzg2l:~#
root@smarc-rzg2l:~# insmod gpio_keys.ko
[  925.002720] input: keyboard as /devices/platform/keyboard/input/input3
root@smarc-rzg2l:~# cat /proc/interrupts | grep SW
 82:          0          0 11030000.pinctrl 344 Edge      SW1
 83:          0          0 11030000.pinctrl 328 Edge      SW2
 84:          0          0 11030000.pinctrl 345 Edge      SW3
root@smarc-rzg2l:~#

In here 82/83/84 are virq and 344/328/345 are hwirq, which can be
confirmed from sysfs file:

root@smarc-rzg2l:~# cat /sys/kernel/debug/irq/irqs/82
handler:  handle_fasteoi_irq
device:   (null)
status:   0x00000001
istate:   0x00000000
ddepth:   0
wdepth:   0
dstate:   0x13400201
            IRQ_TYPE_EDGE_RISING
            IRQD_ACTIVATED
            IRQD_IRQ_STARTED
            IRQD_SINGLE_TARGET
            IRQD_DEFAULT_TRIGGER_SET
            IRQD_HANDLE_ENFORCE_IRQCTX
node:     0
affinity: 0-1
effectiv:
domain:  :soc:pinctrl@11030000
 hwirq:   0x158
 chip:    11030000.pinctrl
  flags:   0x800
             IRQCHIP_IMMUTABLE
 parent:
    domain:  :soc:interrupt-controller@110a0000
     hwirq:   0x9
     chip:    rzg2l-irqc
      flags:   0x15
                 IRQCHIP_SET_TYPE_MASKED
                 IRQCHIP_MASK_ON_SUSPEND
                 IRQCHIP_SKIP_SET_WAKE
     parent:
        domain:  :soc:interrupt-controller@11900000-1
         hwirq:   0x1dc
         chip:    GICv3
          flags:   0x15
                     IRQCHIP_SET_TYPE_MASKED
                     IRQCHIP_MASK_ON_SUSPEND
                     IRQCHIP_SKIP_SET_WAKE
root@smarc-rzg2l:~#
root@smarc-rzg2l:~#
root@smarc-rzg2l:~# cat /sys/kernel/debug/irq/irqs/83
handler:  handle_fasteoi_irq
device:   (null)
status:   0x00000001
istate:   0x00000000
ddepth:   0
wdepth:   0
dstate:   0x13400201
            IRQ_TYPE_EDGE_RISING
            IRQD_ACTIVATED
            IRQD_IRQ_STARTED
            IRQD_SINGLE_TARGET
            IRQD_DEFAULT_TRIGGER_SET
            IRQD_HANDLE_ENFORCE_IRQCTX
node:     0
affinity: 0-1
effectiv:
domain:  :soc:pinctrl@11030000
 hwirq:   0x148
 chip:    11030000.pinctrl
  flags:   0x800
             IRQCHIP_IMMUTABLE
 parent:
    domain:  :soc:interrupt-controller@110a0000
     hwirq:   0xa
     chip:    rzg2l-irqc
      flags:   0x15
                 IRQCHIP_SET_TYPE_MASKED
                 IRQCHIP_MASK_ON_SUSPEND
                 IRQCHIP_SKIP_SET_WAKE
     parent:
        domain:  :soc:interrupt-controller@11900000-1
         hwirq:   0x1dd
         chip:    GICv3
          flags:   0x15
                     IRQCHIP_SET_TYPE_MASKED
                     IRQCHIP_MASK_ON_SUSPEND
                     IRQCHIP_SKIP_SET_WAKE
root@smarc-rzg2l:~#
root@smarc-rzg2l:~# cat /sys/kernel/debug/irq/irqs/84
handler:  handle_fasteoi_irq
device:   (null)
status:   0x00000001
istate:   0x00000000
ddepth:   0
wdepth:   0
dstate:   0x13400201
            IRQ_TYPE_EDGE_RISING
            IRQD_ACTIVATED
            IRQD_IRQ_STARTED
            IRQD_SINGLE_TARGET
            IRQD_DEFAULT_TRIGGER_SET
            IRQD_HANDLE_ENFORCE_IRQCTX
node:     0
affinity: 0-1
effectiv:
domain:  :soc:pinctrl@11030000
 hwirq:   0x159
 chip:    11030000.pinctrl
  flags:   0x800
             IRQCHIP_IMMUTABLE
 parent:
    domain:  :soc:interrupt-controller@110a0000
     hwirq:   0xb
     chip:    rzg2l-irqc
      flags:   0x15
                 IRQCHIP_SET_TYPE_MASKED
                 IRQCHIP_MASK_ON_SUSPEND
                 IRQCHIP_SKIP_SET_WAKE
     parent:
        domain:  :soc:interrupt-controller@11900000-1
         hwirq:   0x1de
         chip:    GICv3
          flags:   0x15
                     IRQCHIP_SET_TYPE_MASKED
                     IRQCHIP_MASK_ON_SUSPEND
                     IRQCHIP_SKIP_SET_WAKE
root@smarc-rzg2l:~#
root@smarc-rzg2l:~#
root@smarc-rzg2l:~#

root@smarc-rzg2l:~# rmmod gpio_keys.ko
[ 1143.037314] rzg2l_gpio_free offset:345 virq:84
[ 1143.042488] rzg2l_gpio_free offset:328 virq:83
[ 1143.048700] rzg2l_gpio_free offset:344 virq:82
root@smarc-rzg2l:~#
root@smarc-rzg2l:~#

I have added print in gpio_free callback where
irq_{find,dispose}_mapping()) prints the correct value above.


> > > The loop is over all GPIO offsets, while not all of them are mapped
> > > to valid interrupts. Does the above work correctly?
> > >
> > I haven't tested unloading the pinctrl driver which should call
> > gpiochip_irqchip_remove() (we don't have remove call back for pinctrl
> > driver)
> >
> > > > > 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.
> > >
> > > Upon closer look, I think the mask is a red herring, and we don't
> > > need it.
> > Agreed.
> >
> > > But we do need to handle the (possible) mismatch between GPIO
> > > offset (index) and IRQ offset in the above code.
> > >
> > Agreed, do you see any possibility of the mismatch I have missed?
>
> gpiochip_to_irq():
>
>         if (irq_domain_is_hierarchy(domain)) {
>                 struct irq_fwspec spec;
>
>                 spec.fwnode = domain->fwnode;
>                 spec.param_count = 2;
>                 spec.param[0] = gc->irq.child_offset_to_irq(gc, offset);
>                 spec.param[1] = IRQ_TYPE_NONE;
>
>                 return irq_create_fwspec_mapping(&spec);
>         }
>
> Same here: in the absence of a child_offset_to_irq() callback,
> the default gpiochip_child_offset_to_irq_noop() will be used,
> assuming an identity mapping between GPIO numbers and IRQ
> numbers.
>
Agreed, gpiochip_child_offset_to_irq_noop will return the "offset",
but irq_create_fwspec_mapping() in gpiochip_to_irq() will return the
virq number which will not be equal to the offset.

I added the below change in gpio_keys.c where it calls gpiod_to_irq()
-> to_irq()  and the below is the log:
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -589,6 +589,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
                                        button->gpio, error);
                                return error;
                        }
+                       dev_err(dev,"%s gpiod_to_irq() = (irq) %d\n",
__func__, irq);
+
                        bdata->irq = irq;
                }

root@smarc-rzg2l:~# insmod gpio_keys.ko
[   54.288678] gpio-keys keyboard: gpio_keys_setup_key gpiod_to_irq() = (irq) 82
[   54.297230] gpio-keys keyboard: gpio_keys_setup_key gpiod_to_irq() = (irq) 83
[   54.311256] gpio-keys keyboard: gpio_keys_setup_key gpiod_to_irq() = (irq) 84
[   54.332560] input: keyboard as /devices/platform/keyboard/input/input0
root@smarc-rzg2l:~#

> So perhaps
>   1. you need to provide a child_offset_to_irq() callback,
>   2. gpiochip_irqchip_remove() needs to apply the child_offset_to_irq()
>     mapping too?
>   3. you do need the mask, or let child_offset_to_irq() an error code,
>      to avoid irq_{find,dispose}_mapping() handling non-existent irqs?
>
From the above logs, I don't think this is needed. Please correct me
if I am wrong.


> Or am I missing something?
>
> I guess this is easy to verify by adding some debug prints to the code.
>
Let me know if you want me to add debug prints at specific places.

Cheers,
Prabhakar

  reply	other threads:[~2022-05-13 18:14 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-11 18:32 [PATCH v3 0/5] Renesas RZ/G2L IRQC support Lad Prabhakar
2022-05-11 18:32 ` [PATCH v3 1/5] dt-bindings: interrupt-controller: Add Renesas RZ/G2L Interrupt Controller Lad Prabhakar
2022-05-12  6:14   ` Biju Das
2022-05-12  6:43   ` Geert Uytterhoeven
2022-05-12 17:58     ` Lad, Prabhakar
2022-05-11 18:32 ` [PATCH v3 2/5] irqchip: Add RZ/G2L IA55 Interrupt Controller driver Lad Prabhakar
2022-05-11 19:25   ` Biju Das
2022-05-12 18:01     ` Lad, Prabhakar
2022-05-12  7:05   ` Geert Uytterhoeven
2022-05-12  7:23   ` Marc Zyngier
2022-05-12  7:26     ` Geert Uytterhoeven
2022-05-12 18:08     ` Lad, Prabhakar
2022-05-11 18:32 ` [PATCH v3 3/5] gpio: gpiolib: Allow free() callback to be overridden Lad Prabhakar
2022-05-12  7:06   ` Geert Uytterhoeven
2022-05-12 11:19   ` Marc Zyngier
2022-05-12 12:48     ` Lad, Prabhakar
2022-05-12 13:24       ` Marc Zyngier
2022-05-12 13:50         ` Lad, Prabhakar
2022-05-12 16:26           ` Marc Zyngier
2022-05-12 17:55             ` Lad, Prabhakar
2022-05-12 22:24               ` Marc Zyngier
2022-05-11 18:32 ` [PATCH v3 4/5] gpio: gpiolib: Add ngirq member to struct gpio_irq_chip Lad Prabhakar
2022-05-12  7:29   ` Geert Uytterhoeven
2022-05-18 18:30     ` Lad, Prabhakar
2022-05-13 20:47   ` Linus Walleij
2022-05-18 18:36     ` Lad, Prabhakar
2022-05-19 13:21       ` Linus Walleij
2022-05-11 18:32 ` [PATCH v3 5/5] pinctrl: renesas: pinctrl-rzg2l: Add IRQ domain to handle GPIO interrupt Lad Prabhakar
2022-05-12  5:35   ` Biju Das
2022-05-12 17:43     ` Lad, Prabhakar
2022-05-12 17:59       ` Biju Das
2022-05-13  6:12         ` Biju Das
2022-05-13 13:42           ` Lad, Prabhakar
2022-05-12  7:39   ` Geert Uytterhoeven
2022-05-12 17:36     ` Lad, Prabhakar
2022-05-13  6:53       ` Geert Uytterhoeven
2022-05-13 13:55         ` Lad, Prabhakar
2022-05-13 14:29           ` Geert Uytterhoeven
2022-05-13 18:13             ` Lad, Prabhakar [this message]
2022-05-15  5:13               ` Biju Das
     [not found]                 ` <87pmkfm0v3.wl-maz@kernel.org>
2022-05-16  7:20                   ` Biju Das
     [not found]                     ` <87pmkd6gda.wl-maz@kernel.org>
2022-05-16  8:33                       ` Biju Das
     [not found]                         ` <87o7zx6ckp.wl-maz@kernel.org>
2022-05-16  9:56                           ` Biju Das
2022-05-16  7:13               ` Geert Uytterhoeven
2022-05-18 19:04                 ` Lad, Prabhakar
2022-05-12 11:15   ` Marc Zyngier
2022-05-12 17:46     ` Lad, Prabhakar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CA+V-a8uXakF45TLvpsfeAY_EZKDGHr-wfgqLR_LTz1ZAo8FYmg@mail.gmail.com \
    --to=prabhakar.csengg@gmail.com \
    --cc=biju.das.jz@bp.renesas.com \
    --cc=brgl@bgdev.pl \
    --cc=devicetree@vger.kernel.org \
    --cc=geert@linux-m68k.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=phil.edworthy@renesas.com \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=robh+dt@kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.