Re: [PATCH v3 04/21] pinctrl: starfive: Add StarFive JHB100 sys0 controller driver

Linus Walleij <[email protected]> Mon, 3 Aug 2026 10:10:56 +0200
Newsgroups org.kernel.vger.linux-gpio,org.infradead.lists.linux-riscv,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel
Message-ID <CAD++jLn_vdk2VxupDRErNfqFNZbf7pimCrfnziRPTmDPm7toVw@mail.gmail.com>
On Thu, Jul 30, 2026 at 12:58=E2=80=AFPM Changhuang Liang
<[email protected]> wrote:

> > If a pin controller back-end is used, the GPIO controller or hardware
> > description needs to provide "GPIO ranges" mapping the GPIO line offset=
s to
> > pin numbers on the pin controller so they can properly cross-reference =
each
> > other."
>
> I tried this change, but it doesn't work. In my new version, the GPIO dir=
ection is set
> via the `struct pinmux_ops .gpio_set_direction` callback, which is execut=
ed after
> `mutex_lock(&pctldev->mutex);`. I need to configure some pinconf settings=
 while
> setting the GPIO direction inside `.gpio_set_direction`, for example:
>
>     config =3D pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 0);
>     ret =3D pinctrl_gpio_set_config(gc, gpio, config);
>
> However, `pinctrl_gpio_set_config` will again acquire the lock with
> `mutex_lock(&pctldev->mutex);`.
>
> So this approach may no longer work?

I can't see all your code so I don't know exactly why this happens, but
nominally you implement the GPIO helpers:

struct pinmux_ops {
(...)
        int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
                                    struct pinctrl_gpio_range *range,
                                    unsigned int offset);
        void (*gpio_disable_free) (struct pinctrl_dev *pctldev,
                                   struct pinctrl_gpio_range *range,
                                   unsigned int offset);
        int (*gpio_set_direction) (struct pinctrl_dev *pctldev,
                                   struct pinctrl_gpio_range *range,
                                   unsigned int offset,
                                   bool input);

Then on the GPIO side:

static int my_gpio_direction_input(struct gpio_chip *chip, unsigned int off=
set)
{
        return pinctrl_gpio_direction_input(chip, offset);
}

static int my_gpio_direction_output(struct gpio_chip *chip, unsigned int of=
fset,
                                       int value)
{
        int ret;

        ret =3D my_gpio_set(chip, offset, value);
        if (ret)
                return ret;

        return pinctrl_gpio_direction_output(chip, offset);
}

static const struct gpio_chip my_gpio_chip =3D {
        .direction_input =3D my_gpio_direction_input,
        .direction_output =3D my_gpio_direction_output,
        .set_config =3D gpiochip_generic_config,
};

And these will call into the pin controller backend for you, so you do not
need to set this yourself?

Yours,
Linus Walleij