From: "Alvin Šipraga" <alvin.sipraga@analog.com>
To: development@redaril.me
Cc: Peter Rosin <peda@lysator.liu.se>,
Linus Walleij <linusw@kernel.org>,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
xu.yang_2@nxp.com
Subject: Re: [PATCH v3 1/3] mux: convert to use fwnode interface
Date: Wed, 30 Sep 2026 11:39:02 +0200 [thread overview]
Message-ID: <arzYpNsduacQzAV8@analog.com> (raw)
In-Reply-To: <20260929-mux_fwnode-v3-1-9b3b9ae1334e@redaril.me>
On Tue, Sep 29, 2026 at 10:51:46PM +0200, Fabio Forni via B4 Relay wrote:
> From: Fabio Forni <development@redaril.me>
>
> As firmware node is a more common abstract, this will convert the whole
> thing to fwnode interface.
>
> Co-developed-by: Xu Yang <xu.yang_2@nxp.com>
> Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> Signed-off-by: Fabio Forni <development@redaril.me>
Reviewed-by: Alvin Šipraga <alvin.sipraga@analog.com>
> ---
> drivers/mux/core.c | 96 ++++++++++++++++++-----------------
> drivers/pinctrl/pinctrl-generic-mux.c | 4 +-
> include/linux/mux/consumer.h | 6 ++-
> 3 files changed, 57 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/mux/core.c b/drivers/mux/core.c
> index 5083e3d19606..56096a9139bd 100644
> --- a/drivers/mux/core.c
> +++ b/drivers/mux/core.c
> @@ -18,7 +18,7 @@
> #include <linux/module.h>
> #include <linux/mux/consumer.h>
> #include <linux/mux/driver.h>
> -#include <linux/of.h>
> +#include <linux/property.h>
> #include <linux/slab.h>
>
> /*
> @@ -118,6 +118,7 @@ struct mux_chip *mux_chip_alloc(struct device *dev,
> mux_chip->dev.type = &mux_type;
> mux_chip->dev.parent = dev;
> mux_chip->dev.of_node = dev->of_node;
> + mux_chip->dev.fwnode = dev->fwnode;
> dev_set_drvdata(&mux_chip->dev, mux_chip);
>
> mux_chip->id = ida_alloc(&mux_ida, GFP_KERNEL);
> @@ -517,11 +518,11 @@ int mux_state_deselect(struct mux_state *mstate)
> EXPORT_SYMBOL_GPL(mux_state_deselect);
>
> /* Note this function returns a reference to the mux_chip dev. */
> -static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np)
> +static struct mux_chip *mux_chip_find_by_fwnode(struct fwnode_handle *fwnode)
> {
> struct device *dev;
>
> - dev = class_find_device_by_of_node(&mux_class, np);
> + dev = class_find_device_by_fwnode(&mux_class, fwnode);
>
> return dev ? to_mux_chip(dev) : NULL;
> }
> @@ -533,17 +534,17 @@ static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np)
> * @state: Pointer to where the requested state is returned, or NULL when
> * the required multiplexer states are handled by other means.
> * @optional: Whether to return NULL and silence errors when mux doesn't exist.
> - * @node: the device nodes, use dev->of_node if it is NULL.
> + * @node: the device nodes, use dev's fwnode if it is NULL.
> *
> * Return: Pointer to the mux-control on success, an ERR_PTR with a negative
> * errno on error, or NULL if optional is true and mux doesn't exist.
> */
> static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> unsigned int *state, bool optional,
> - struct device_node *node)
> + struct fwnode_handle *node)
> {
> - struct device_node *np = node ? node : dev->of_node;
> - struct of_phandle_args args;
> + struct fwnode_handle *fwnode = node ? node : dev_fwnode(dev);
> + struct fwnode_reference_args args;
> struct mux_chip *mux_chip;
> unsigned int controller;
> int index = 0;
> @@ -551,11 +552,13 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
>
> if (mux_name) {
> if (state)
> - index = of_property_match_string(np, "mux-state-names",
> - mux_name);
> + index = fwnode_property_match_string(fwnode,
> + "mux-state-names",
> + mux_name);
> else
> - index = of_property_match_string(np, "mux-control-names",
> - mux_name);
> + index = fwnode_property_match_string(fwnode,
> + "mux-control-names",
> + mux_name);
> if (index < 0 && optional) {
> return NULL;
> } else if (index < 0) {
> @@ -566,39 +569,40 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> }
>
> if (state)
> - ret = of_parse_phandle_with_args(np,
> - "mux-states", "#mux-state-cells",
> - index, &args);
> + ret = fwnode_property_get_reference_args(fwnode, "mux-states",
> + "#mux-state-cells", 0,
> + index, &args);
> else
> - ret = of_parse_phandle_with_args(np,
> - "mux-controls", "#mux-control-cells",
> - index, &args);
> + ret = fwnode_property_get_reference_args(fwnode,
> + "mux-controls", "#mux-control-cells",
> + 0, index, &args);
> +
> if (ret) {
> if (optional && ret == -ENOENT)
> return NULL;
>
> - dev_err(dev, "%pOF: failed to get mux-%s %s(%i)\n",
> - np, state ? "state" : "control",
> - mux_name ?: "", index);
> + dev_err(dev, "%pfw: failed to get mux-%s %s(%i)\n",
> + fwnode, state ? "state" : "control", mux_name ?: "",
> + index);
> return ERR_PTR(ret);
> }
>
> - mux_chip = of_find_mux_chip_by_node(args.np);
> - of_node_put(args.np);
> + mux_chip = mux_chip_find_by_fwnode(args.fwnode);
> + fwnode_handle_put(args.fwnode);
> if (!mux_chip)
> return ERR_PTR(-EPROBE_DEFER);
>
> controller = 0;
> if (state) {
> - if (args.args_count > 2 || args.args_count == 0 ||
> - (args.args_count < 2 && mux_chip->controllers > 1)) {
> - dev_err(dev, "%pOF: wrong #mux-state-cells for %pOF\n",
> - np, args.np);
> + if (args.nargs > 2 || args.nargs == 0 ||
> + (args.nargs < 2 && mux_chip->controllers > 1)) {
> + dev_err(dev, "%pfw: wrong #mux-state-cells for %pfw\n",
> + fwnode, args.fwnode);
> put_device(&mux_chip->dev);
> return ERR_PTR(-EINVAL);
> }
>
> - if (args.args_count == 2) {
> + if (args.nargs == 2) {
> controller = args.args[0];
> *state = args.args[1];
> } else {
> @@ -606,21 +610,21 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> }
>
> } else {
> - if (args.args_count > 1 ||
> - (!args.args_count && mux_chip->controllers > 1)) {
> - dev_err(dev, "%pOF: wrong #mux-control-cells for %pOF\n",
> - np, args.np);
> + if (args.nargs > 1 ||
> + (!args.nargs && mux_chip->controllers > 1)) {
> + dev_err(dev, "%pfw: wrong #mux-control-cells for %pfw\n",
> + fwnode, args.fwnode);
> put_device(&mux_chip->dev);
> return ERR_PTR(-EINVAL);
> }
>
> - if (args.args_count)
> + if (args.nargs)
> controller = args.args[0];
> }
>
> if (controller >= mux_chip->controllers) {
> - dev_err(dev, "%pOF: bad mux controller %u specified in %pOF\n",
> - np, controller, args.np);
> + dev_err(dev, "%pfw: bad mux controller %u specified in %pfw\n",
> + fwnode, controller, args.fwnode);
> put_device(&mux_chip->dev);
> return ERR_PTR(-EINVAL);
> }
> @@ -714,14 +718,14 @@ EXPORT_SYMBOL_GPL(devm_mux_control_get);
> * @dev: The device that needs a mux-state.
> * @mux_name: The name identifying the mux-state.
> * @optional: Whether to return NULL and silence errors when mux doesn't exist.
> - * @np: the device nodes, use dev->of_node if it is NULL.
> + * @node: the device nodes, use dev's fwnode if it is NULL.
> *
> * Return: Pointer to the mux-state on success, an ERR_PTR with a negative
> * errno on error, or NULL if optional is true and mux doesn't exist.
> */
> static struct mux_state *
> mux_state_get(struct device *dev, const char *mux_name, bool optional,
> - struct device_node *np)
> + struct fwnode_handle *node)
> {
> struct mux_state *mstate;
>
> @@ -729,7 +733,7 @@ mux_state_get(struct device *dev, const char *mux_name, bool optional,
> if (!mstate)
> return ERR_PTR(-ENOMEM);
>
> - mstate->mux = mux_get(dev, mux_name, &mstate->state, optional, np);
> + mstate->mux = mux_get(dev, mux_name, &mstate->state, optional, node);
> if (IS_ERR(mstate->mux)) {
> int err = PTR_ERR(mstate->mux);
>
> @@ -771,7 +775,7 @@ static void devm_mux_state_release(struct device *dev, void *res)
> * @dev: The device that needs a mux-state.
> * @mux_name: The name identifying the mux-state.
> * @optional: Whether to return NULL and silence errors when mux doesn't exist.
> - * @np: The device nodes, use dev->of_node if it is NULL.
> + * @node: The device nodes, use dev's fwnode if it is NULL.
> * @init: Optional function pointer for mux-state object initialisation.
> * @exit: Optional function pointer for mux-state object cleanup on release.
> *
> @@ -779,7 +783,7 @@ static void devm_mux_state_release(struct device *dev, void *res)
> * errno on error, or NULL if optional is true and mux doesn't exist.
> */
> static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mux_name,
> - bool optional, struct device_node *np,
> + bool optional, struct fwnode_handle *node,
> int (*init)(struct mux_state *mstate),
> int (*exit)(struct mux_state *mstate))
> {
> @@ -787,7 +791,7 @@ static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mu
> struct mux_state *mstate;
> int ret;
>
> - mstate = mux_state_get(dev, mux_name, optional, np);
> + mstate = mux_state_get(dev, mux_name, optional, node);
> if (IS_ERR(mstate))
> return ERR_CAST(mstate);
> else if (optional && !mstate)
> @@ -821,23 +825,23 @@ static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mu
> }
>
> /**
> - * devm_mux_state_get_from_np() - Get the mux-state for a device, with resource
> + * devm_mux_state_get_from_fwnode() - Get the mux-state for a device, with resource
> * management.
> * @dev: The device that needs a mux-control.
> * @mux_name: The name identifying the mux-control.
> - * @np: the device nodes, use dev->of_node if it is NULL.
> + * @node: the device nodes, use dev's fwnode if it is NULL.
> *
> * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
> *
> * The mux-state will automatically be freed on release.
> */
> struct mux_state *
> -devm_mux_state_get_from_np(struct device *dev, const char *mux_name,
> - struct device_node *np)
> +devm_mux_state_get_from_fwnode(struct device *dev, const char *mux_name,
> + struct fwnode_handle *node)
> {
> - return __devm_mux_state_get(dev, mux_name, false, np, NULL, NULL);
> + return __devm_mux_state_get(dev, mux_name, false, node, NULL, NULL);
> }
> -EXPORT_SYMBOL_GPL(devm_mux_state_get_from_np);
> +EXPORT_SYMBOL_GPL(devm_mux_state_get_from_fwnode);
>
> /**
> * devm_mux_state_get_optional() - Get the optional mux-state for a device,
> diff --git a/drivers/pinctrl/pinctrl-generic-mux.c b/drivers/pinctrl/pinctrl-generic-mux.c
> index 202b72351efb..6d5b6100c5ca 100644
> --- a/drivers/pinctrl/pinctrl-generic-mux.c
> +++ b/drivers/pinctrl/pinctrl-generic-mux.c
> @@ -50,7 +50,9 @@ mux_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,
> if (!group_names)
> return -ENOMEM;
>
> - function->mux_state = devm_mux_state_get_from_np(pctldev->dev, NULL, np_config);
> + function->mux_state = devm_mux_state_get_from_fwnode(pctldev->dev,
> + NULL,
> + of_fwnode_handle(np_config));
> if (IS_ERR(function->mux_state))
> return PTR_ERR(function->mux_state);
>
> diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
> index 449e38e6e2c5..7d121217ca96 100644
> --- a/include/linux/mux/consumer.h
> +++ b/include/linux/mux/consumer.h
> @@ -11,6 +11,7 @@
> #define _LINUX_MUX_CONSUMER_H
>
> #include <linux/compiler.h>
> +#include <linux/device.h>
>
> struct device;
> struct mux_control;
> @@ -62,7 +63,8 @@ void mux_control_put(struct mux_control *mux);
> struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name);
>
> struct mux_state *
> -devm_mux_state_get_from_np(struct device *dev, const char *mux_name, struct device_node *np);
> +devm_mux_state_get_from_fwnode(struct device *dev, const char *mux_name,
> + struct fwnode_handle *node);
>
> struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name);
> struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name);
> @@ -165,6 +167,6 @@ static inline struct mux_state *devm_mux_state_get_optional_selected(struct devi
> #endif /* CONFIG_MULTIPLEXER */
>
> #define devm_mux_state_get(dev, mux_name) \
> - devm_mux_state_get_from_np(dev, mux_name, NULL)
> + devm_mux_state_get_from_fwnode(dev, mux_name, NULL)
>
> #endif /* _LINUX_MUX_CONSUMER_H */
>
> --
> 2.55.0
>
>
next prev parent reply other threads:[~2026-09-30 9:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 20:51 [PATCH v3 0/3] Migrate the multiplexer subsystem to fwnode Fabio Forni via B4 Relay
2026-09-29 20:51 ` Fabio Forni
2026-09-29 20:51 ` [PATCH v3 1/3] mux: convert to use fwnode interface Fabio Forni via B4 Relay
2026-09-29 20:51 ` Fabio Forni
2026-09-30 9:39 ` Alvin Šipraga [this message]
2026-09-29 20:51 ` [PATCH v3 2/3] mux: Document mux_chip_find_by_fwnode() Fabio Forni via B4 Relay
2026-09-29 20:51 ` Fabio Forni
2026-09-30 9:39 ` Alvin Šipraga
2026-09-29 20:51 ` [PATCH v3 3/3] mux: Avoid use-after-free of args.fwnode in mux_get() Fabio Forni via B4 Relay
2026-09-29 20:51 ` Fabio Forni
2026-09-30 9:45 ` Alvin Šipraga
2026-09-30 17:44 ` Fabio
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=arzYpNsduacQzAV8@analog.com \
--to=alvin.sipraga@analog.com \
--cc=development@redaril.me \
--cc=linusw@kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peda@lysator.liu.se \
--cc=xu.yang_2@nxp.com \
/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.