mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] mux: convert to use fwnode interface
@ 2026-09-15 19:35 Fabio Forni via B4 Relay
  2026-09-15 23:26 ` Linus Walleij
  2026-09-16  0:20 ` Alvin Šipraga
  0 siblings, 2 replies; 3+ messages in thread
From: Fabio Forni via B4 Relay @ 2026-09-15 19:35 UTC (permalink / raw)
  To: Peter Rosin, Linus Walleij
  Cc: linux-kernel, linux-gpio, xu.yang_2, Fabio Forni

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>
---
This patch migrates the multiplexer subsystem from using the of_*          
family of functions and structs, to the more generic fwnode framework.     
                                                                           
It is a rebase of a single commit[1] contained in a old patch series[2]
submitted by Xu Yang. The original commit plus follow-up comments were
tested on kernel v6.12 on an arm64-based board, but this current rebase
isn't tested yet.                                                  
                                                                           
Link: https://lore.kernel.org/all/20220823195429.1243516-3-xu.yang_2@nxp.com [1]
Link: https://lore.kernel.org/all/20220823195429.1243516-1-xu.yang_2@nxp.com [2]
---
 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..2de0d1fd43d0 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_swnode() - 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_swnode(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_swnode);
 
 /**
  * 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..bb6681753727 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_swnode(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..ceb6858cdce8 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_swnode(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_swnode(dev, mux_name, NULL)
 
 #endif /* _LINUX_MUX_CONSUMER_H */

---
base-commit: f6e7b42bf05b2427fb8a7a1d1c387a86638bb413
change-id: 20260915-mux_fwnode-a16593c39ffd

Best regards,
-- 
Fabio Forni <development@redaril.me>



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mux: convert to use fwnode interface
  2026-09-15 19:35 [PATCH] mux: convert to use fwnode interface Fabio Forni via B4 Relay
@ 2026-09-15 23:26 ` Linus Walleij
  2026-09-16  0:20 ` Alvin Šipraga
  1 sibling, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2026-09-15 23:26 UTC (permalink / raw)
  To: development; +Cc: Peter Rosin, linux-kernel, linux-gpio, xu.yang_2

On Tue, Sep 15, 2026 at 9:35 PM Fabio Forni via B4 Relay
<devnull+development.redaril.me@kernel.org> 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>

Acked-by: Linus Walleij <linusw@kernel.org>

The mux maintainer can merge this once it looks fine to him.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mux: convert to use fwnode interface
  2026-09-15 19:35 [PATCH] mux: convert to use fwnode interface Fabio Forni via B4 Relay
  2026-09-15 23:26 ` Linus Walleij
@ 2026-09-16  0:20 ` Alvin Šipraga
  1 sibling, 0 replies; 3+ messages in thread
From: Alvin Šipraga @ 2026-09-16  0:20 UTC (permalink / raw)
  To: development
  Cc: Peter Rosin, Linus Walleij, linux-kernel, linux-gpio, xu.yang_2

On Tue, Sep 15, 2026 at 09:35:21PM +0200, Fabio Forni via B4 Relay wrote:
> @@ -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_swnode() - 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_swnode(struct device *dev, const char *mux_name,
> +			       struct fwnode_handle *node)

Shouldn't it be get_from_fwnode (not swnode)?

Kind regards,
Alvin

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-16  0:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-15 19:35 [PATCH] mux: convert to use fwnode interface Fabio Forni via B4 Relay
2026-09-15 23:26 ` Linus Walleij
2026-09-16  0:20 ` Alvin Šipraga

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®