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

Linus Walleij linusw at kernel.org
Mon Aug 3 01:10:56 PDT 2026


On Thu, Jul 30, 2026 at 12:58 PM Changhuang Liang
<changhuang.liang at starfivetech.com> wrote:

> > If a pin controller back-end is used, the GPIO controller or hardware
> > description needs to provide "GPIO ranges" mapping the GPIO line offsets 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 direction is set
> via the `struct pinmux_ops .gpio_set_direction` callback, which is executed after
> `mutex_lock(&pctldev->mutex);`. I need to configure some pinconf settings while
> setting the GPIO direction inside `.gpio_set_direction`, for example:
>
>     config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 0);
>     ret = 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 offset)
{
        return pinctrl_gpio_direction_input(chip, offset);
}

static int my_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
                                       int value)
{
        int ret;

        ret = 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 = {
        .direction_input = my_gpio_direction_input,
        .direction_output = my_gpio_direction_output,
        .set_config = 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



More information about the linux-riscv mailing list