linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Linus Walleij <linus.walleij@linaro.org>
To: Dan Carpenter <dan.carpenter@linaro.org>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>,
	Michal Simek <michal.simek@amd.com>,
	 Sudeep Holla <sudeep.holla@arm.com>,
	Cristian Marussi <cristian.marussi@arm.com>,
	 Bartosz Golaszewski <brgl@bgdev.pl>,
	linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	 arm-scmi@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH RFC v2 6/7] pinctrl-scmi: Add GPIO support
Date: Thu, 14 Aug 2025 10:39:23 +0200	[thread overview]
Message-ID: <CACRpkdZOnjW-mjQbTOUybNod8PyT+p66v8h2c4ejAfV7wo-8Tg@mail.gmail.com> (raw)
In-Reply-To: <bd79aa90-73f7-4d7b-a340-539b52a73bcf@sabinyo.mountain>

On Sun, Jul 20, 2025 at 9:39 PM Dan Carpenter <dan.carpenter@linaro.org> wrote:

> This adds GPIO support to the SCMI pin controller driver.  It's an RFC
> patch because I'm not really sure how these are used and so I don't
> know how they should be configured via devicetree.  I've labeled the
> places where I think devicetree configuration would go with a FIXME.
>
> This driver was based on work from Takahiro AKASHI.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>

(...)

> @@ -955,19 +954,16 @@ int pinctrl_gpio_get_config(struct gpio_chip *gc, unsigned int offset, unsigned
>         if (ret)
>                 return ret;
>
> -       ops = pctldev->desc->confops;
> -       if (!ops || !ops->pin_config_get)
> -               return -EINVAL;
> -
>         mutex_lock(&pctldev->mutex);
>         pin = gpio_to_pin(range, gc, offset);
> -       ret = ops->pin_config_get(pctldev, pin, config);
> +       ret = pin_config_get_for_pin(pctldev, pin, config);
>         mutex_unlock(&pctldev->mutex);
>
>         if (ret)
>                 return ret;
>
>         *config = pinconf_to_config_argument(*config);
> +
>         return 0;
>  }

Looks reasonable.

> @@ -42,6 +46,7 @@ struct scmi_pinctrl {
>         unsigned int nr_functions;
>         struct pinctrl_pin_desc *pins;
>         unsigned int nr_pins;
> +       struct gpio_chip *gc;

This being a pointer is slightly confusing. And looking below I see why:

> +       gpio = fwnode_get_named_child_node(dev->fwnode, "gpio");
> +       if (!gpio)
> +               return 0;
> +
> +       pmx->gc = devm_kcalloc(dev, pmx->nr_functions, sizeof(*pmx->gc), GFP_KERNEL);
> +       if (!pmx->gc)
> +               return -ENOMEM;

So this needs a comment to what is actually going on here.

To me it looks like the code is instantiating a struct gpio_chip for
each function on the pin mux.

That feels wrong: instead we should probably instantiate *one* gpio_chip for
the whole pinmux and then create individual gpio lines for each
pin that can work as a GPIO.

> +       for (i = 0; i < pmx->nr_functions; i++) {
> +               const char *fn_name;
> +
> +               ret = pinctrl_ops->is_gpio(pmx->ph, i, FUNCTION_TYPE);
> +               if (ret < 0)
> +                       return ret;

So we are only looking for functions that are of GPIO type.

> +               if (ret == false)
> +                       continue;
> +
> +               ret = pinctrl_ops->name_get(pmx->ph, i, FUNCTION_TYPE, &fn_name);
> +               if (ret)
> +                       return ret;
> +
> +               pmx->gc[i].label = devm_kasprintf(dev, GFP_KERNEL, "%s", fn_name);
> +               if (!pmx->gc[i].label)
> +                       return -ENOMEM;
> +
> +               pmx->gc[i].owner = THIS_MODULE;
> +               pmx->gc[i].get = pinctrl_gpio_get;
> +               pmx->gc[i].set = pinctrl_gpio_set;
> +               pmx->gc[i].get_direction = pinctrl_gpio_get_direction;
> +               pmx->gc[i].direction_input = pinctrl_gpio_direction_input;
> +               pmx->gc[i].direction_output = pinctrl_gpio_direction_output_wrapper;
> +               pmx->gc[i].add_pin_ranges = gpio_add_pin_ranges;
> +
> +               // FIXME: verify that this is correct
> +               pmx->gc[i].can_sleep = true;
> +
> +               ret = get_nr_pins_in_function(pmx, i);
> +               if (ret < 0)
> +                       return ret;
> +               pmx->gc[i].ngpio = ret;

Please put a print here and see how many pins there are usually in the
function here. In my mind it should always be 1 and if it is not 1 then
something is wrong.

We cannot instantiate n gpio_chips for a pin controller where n is the
number of functions for GPIO, intead we need to instantiate one gpio_chip
for the whole pin controller with ngpio set to the number of pins
that exist on the pin controller and mask of any lines that cannot be
used as GPIO from the chip using the gc->init_valid_mask() callback.

I think you want to look at Bartosz series that introduce a GPIO
function category and use this as a basis for your work, because
I plan to merge this for v6.18:
https://lore.kernel.org/linux-gpio/20250812-pinctrl-gpio-pinfuncs-v4-0-bb3906c55e64@linaro.org/T/#t

If you can first patch the SCMI pin control driver to use
pinmux_generic_add_pinfunction() based on Bartosz patch set
and get to this:

+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,

Then it is also easier to figure out if a line is GPIO or not (the
core will help you).

I hope the conversion to Bartosz generics could be
straightforward... It looks straightforward but there may
be devil in the details :)

After this you can use pinmux_generic_function_is_gpio()
to check if a certain function is used for GPIO or not, I think
in the SCMI case this is done with a simple strcmp().

Then you can use this to instantiate a gpio_chip for SCMI
that will dynamically allow pins to be remuxed into GPIO and
made available on the chip as we go.

I'm sure Bartosz can help out a bit with some details!

Yours,
Linus Walleij


  reply	other threads:[~2025-08-14  8:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-20 19:38 [PATCH RFC v2 0/7] pinctrl-scmi: Add GPIO support Dan Carpenter
2025-07-20 19:38 ` [PATCH RFC v2 1/7] firmware: arm_scmi: move boiler plate code into the get info functions Dan Carpenter
2025-08-21  8:09   ` Cristian Marussi
2025-07-20 19:38 ` [PATCH RFC v2 2/7] firmware: arm_scmi: add is_gpio() function Dan Carpenter
2025-08-21  8:19   ` Cristian Marussi
2025-07-20 19:38 ` [PATCH RFC v2 4/7] pinctrl-scmi: add PIN_CONFIG_INPUT_VALUE Dan Carpenter
2025-08-21  8:38   ` Cristian Marussi
2025-09-05  8:27   ` Linus Walleij
2025-09-05  8:31     ` Linus Walleij
2025-09-05  9:24       ` Linus Walleij
2025-07-20 19:39 ` [PATCH RFC v2 6/7] pinctrl-scmi: Add GPIO support Dan Carpenter
2025-08-14  8:39   ` Linus Walleij [this message]
2025-07-20 19:39 ` [PATCH RFC v2 5/7] pinctrl: Delete PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS support Dan Carpenter
2025-08-21  8:48   ` Cristian Marussi
2025-07-20 19:39 ` [PATCH RFC v2 7/7] pinctrl-scmi: remove unused struct member Dan Carpenter
2025-08-21  8:50   ` Cristian Marussi
2025-08-18  9:03 ` [PATCH RFC v2 0/7] pinctrl-scmi: Add GPIO support Linus Walleij
2025-09-04  8:49   ` Dan Carpenter

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=CACRpkdZOnjW-mjQbTOUybNod8PyT+p66v8h2c4ejAfV7wo-8Tg@mail.gmail.com \
    --to=linus.walleij@linaro.org \
    --cc=arm-scmi@vger.kernel.org \
    --cc=brgl@bgdev.pl \
    --cc=cristian.marussi@arm.com \
    --cc=dan.carpenter@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michal.simek@amd.com \
    --cc=sudeep.holla@arm.com \
    --cc=takahiro.akashi@linaro.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).