Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Frank Li <Frank.li@nxp.com>
To: Linus Walleij <linusw@kernel.org>
Cc: "Peter Rosin" <peda@axentia.se>, "Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Rafał Miłecki" <rafal@milecki.pl>,
	"Sascha Hauer" <s.hauer@pengutronix.de>,
	"Pengutronix Kernel Team" <kernel@pengutronix.de>,
	"Fabio Estevam" <festevam@gmail.com>,
	linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org,
	"Haibo Chen" <haibo.chen@nxp.com>
Subject: Re: [PATCH v2 4/6] pinctrl: add generic board-level pinctrl driver using mux framework
Date: Fri, 27 Feb 2026 10:22:45 -0500	[thread overview]
Message-ID: <aaG2xQDnMVGGAOJE@lizhi-Precision-Tower-5810> (raw)
In-Reply-To: <CAD++jLkT83xz+PSzZZv_Mv+Mqx_+W30d_xk68EDG-sdmFF3x3A@mail.gmail.com>

On Fri, Feb 27, 2026 at 10:20:14AM +0100, Linus Walleij wrote:
> Hi Frank,
>
> thanks for your patch!
>
> On Thu, Feb 26, 2026 at 12:55 AM Frank Li <Frank.Li@nxp.com> wrote:
>
> > Many boards use on-board mux chips (often controlled by GPIOs from an I2C
> > expander) to switch shared signals between peripherals.
> >
> > Add a generic pinctrl driver built on top of the mux framework to
> > centralize mux handling and avoid probe ordering issues. Keep board-level
> > routing out of individual drivers and supports boot-time only mux
> > selection.
> >
> > Ensure correct probe ordering, especially when the GPIO expander is probed
> > later.
> >
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> (...)
>
> > +static int
> > +mux_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,
> > +                         struct device_node *np_config,
> > +                         struct pinctrl_map **map, unsigned int *num_maps)
> > +{
> > +       struct mux_pinctrl *mpctl = pinctrl_dev_get_drvdata(pctldev);
> > +       struct mux_pin_function *function;
> > +       struct device *dev = mpctl->dev;
> > +       const char **pgnames;
> > +       int selector;
> > +       int group;
> > +       int ret;
> > +
> > +       *map = devm_kcalloc(dev, 1, sizeof(**map), GFP_KERNEL);
> > +       if (!*map)
> > +               return -ENOMEM;
> > +
> > +       *num_maps = 0;
> > +
> > +       function = devm_kzalloc(dev, sizeof(*function), GFP_KERNEL);
> > +       if (!function) {
> > +               ret = -ENOMEM;
> > +               goto err_func;
> > +       }
> > +
> > +       pgnames = devm_kzalloc(dev, sizeof(*pgnames), GFP_KERNEL);
> > +       if (!pgnames) {
> > +               ret = -ENOMEM;
> > +               goto err_pgnames;
> > +       }
> > +
> > +       pgnames[0] = np_config->name;
> > +
> > +       guard(mutex)(&mpctl->lock);
> > +
> > +       selector = pinmux_generic_add_function(mpctl->pctl, np_config->name,
> > +                                              pgnames, 1, function);
> > +       if (selector < 0) {
> > +               ret = selector;
> > +               goto err_add_func;
> > +       }
> > +
> > +       group = pinctrl_generic_add_group(mpctl->pctl, np_config->name, NULL, 0, mpctl);
> > +       if (group < 0) {
> > +               ret = group;
> > +               goto err_add_group;
> > +       }
> > +
> > +       function->mux_state = devm_mux_state_get_from_np(pctldev->dev, NULL, np_config);
> > +       if (IS_ERR(function->mux_state)) {
> > +               ret = PTR_ERR(function->mux_state);
> > +               goto err_mux_state_get;
> > +       }
> > +
> > +       (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
> > +       (*map)->data.mux.group = np_config->name;
> > +       (*map)->data.mux.function = np_config->name;
> > +
> > +       *num_maps = 1;
> > +
> > +       return 0;
> > +
> > +err_mux_state_get:
> > +       pinctrl_generic_remove_group(mpctl->pctl, group);
> > +err_add_group:
> > +       pinmux_generic_remove_function(mpctl->pctl, selector);
> > +err_add_func:
> > +       devm_kfree(dev, pgnames);
> > +err_pgnames:
> > +       devm_kfree(dev, function);
> > +err_func:
> > +       devm_kfree(dev, *map);
> > +
> > +       return ret;
> > +}
>
> This is so close to the pinctrl-internal helpers that you better work with
> those instead.
>
> Can't you just use pinctrl_generic_pins_function_dt_node_to_map()?
> It was added in the last merge window in
> commit 43722575e5cdcc6c457bfe81fae9c3ad343ea031
> "pinctrl: add generic functions + pins mapper"
>
> There are problems with the above, for example this is only called
> on the probe() path so you would not need any devm_*free calls,
> as you can see in the generic helpers.
>
> I think you need to look into using or extending the existing helpers for this,
>
> > +static void
> > +mux_pinmux_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map,
> > +                      unsigned int num_maps)
> > +{
> > +       struct mux_pinctrl *mpctl = pinctrl_dev_get_drvdata(pctldev);
> > +
> > +       devm_kfree(mpctl->dev, map);
> > +}
>
> Just use pinctrl_utils_free_map().
>
> > +static void mux_pinmux_release_mux(struct pinctrl_dev *pctldev,
> > +                                  unsigned int func_selector,
> > +                                  unsigned int group_selector)
> > +{
> > +       struct mux_pinctrl *mpctl = pinctrl_dev_get_drvdata(pctldev);
> > +       const struct function_desc *function;
> > +       struct mux_pin_function *func;
> > +
> > +       guard(mutex)(&mpctl->lock);
> > +
> > +       function = pinmux_generic_get_function(pctldev, func_selector);
> > +       func = function->data;
> > +
> > +       mux_state_deselect(func->mux_state);
> > +
> > +       mpctl->cur_select = -1;
> > +}
>
> As mentioned I have my doubts about this, explain why this hardware
> is so different that this is needed.
>

As board mux (uart and flexcan) exist, for example, only one of UART and
FlexCAN work.

when modprobe uart.ko,  mux_state_select called.

So flexcan driver can't get such mux as expected.

when remmod uart.ko, we need release mux_state, so flexcan driver can
get such resource.

Genernally, DT may only enouble one of UART or flexcan.

but insmod uart.ko
    rmmod uart.ko

    insmod uart.ko (here also need release previous's state at prevous rmmod).

Frank

> Other than that I like the concept!
>
> Yours,
> Linus Walleij


  reply	other threads:[~2026-02-27 15:37 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-25 23:55 [PATCH v2 0/6] pinctrl: Add generic pinctrl for board-level mux chips Frank Li
2026-02-25 23:55 ` [PATCH v2 1/6] mux: add devm_mux_control_get_from_np() to get mux from child node Frank Li
2026-02-25 23:55 ` [PATCH v2 2/6] dt-bindings: pinctrl: Add generic pinctrl for board-level mux chips Frank Li
2026-02-27  9:02   ` Linus Walleij
2026-03-06  0:57   ` Rob Herring (Arm)
2026-02-25 23:55 ` [PATCH v2 3/6] pinctrl: add optional .release_mux() callback Frank Li
2026-02-27  9:07   ` Linus Walleij
2026-02-27 15:32     ` Frank Li
2026-03-02 10:12       ` Linus Walleij
2026-02-25 23:55 ` [PATCH v2 4/6] pinctrl: add generic board-level pinctrl driver using mux framework Frank Li
2026-02-27  9:09   ` Daniel Baluta
2026-02-27  9:20   ` Linus Walleij
2026-02-27 15:22     ` Frank Li [this message]
2026-03-02 10:11       ` Linus Walleij
2026-03-05 17:37         ` Frank Li
2026-03-08 23:49           ` Linus Walleij
2026-02-25 23:55 ` [PATCH v2 5/6] arm64: dts: imx8mp-evk: add board-level mux for CAN2 and MICFIL Frank Li
2026-02-25 23:55 ` [PATCH v2 6/6] arm64: dts: imx8mp-evk: add flexcan2 overlay file Frank Li

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=aaG2xQDnMVGGAOJE@lizhi-Precision-Tower-5810 \
    --to=frank.li@nxp.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=festevam@gmail.com \
    --cc=haibo.chen@nxp.com \
    --cc=imx@lists.linux.dev \
    --cc=kernel@pengutronix.de \
    --cc=krzk+dt@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peda@axentia.se \
    --cc=rafal@milecki.pl \
    --cc=robh@kernel.org \
    --cc=s.hauer@pengutronix.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox