public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
From: Frank Li <Frank.Li@nxp.com>
To: "Peter Rosin" <peda@axentia.se>,
	"Linus Walleij" <linusw@kernel.org>,
	"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>
Cc: 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>,  Frank Li <Frank.Li@nxp.com>
Subject: [PATCH v6 1/7] mux: add devm_mux_state_get_from_np() to get mux from child node
Date: Mon, 04 May 2026 19:54:35 -0400	[thread overview]
Message-ID: <20260504-pinctrl-mux-v6-1-8ea858ba3a5b@nxp.com> (raw)
In-Reply-To: <20260504-pinctrl-mux-v6-0-8ea858ba3a5b@nxp.com>

Add new API devm_mux_state_get_from_np() to retrieve a mux control from
a specified child device node.

Make devm_mux_state_get() call devm_mux_state_get_from_np() with a NULL
node parameter, which defaults to using the device's own of_node.

Support the following DT schema:

pinctrl@0 {
    uart-func {
            mux-state = <&mux_chip 0>;
    };

    spi-func {
            mux-state = <&mux_chip 1>;
    };
};

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v6
- rebase to v7.1
- change commit message to use 'devm_mux_state_get_from_np()", remove
devm_mux_control_get() change because it is not used yet.

change from v1 to v5
- none
---
 drivers/mux/core.c           | 42 ++++++++++++++++++++++++++----------------
 include/linux/mux/consumer.h |  8 +++++++-
 2 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index 23538de2c91b41ad998471d5af429cf3c6211e4e..2f01acfccf47b1a55037a29101951f4b1760d890 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -533,14 +533,16 @@ 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.
  *
  * 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)
+				   unsigned int *state, bool optional,
+				   struct device_node *node)
 {
-	struct device_node *np = dev->of_node;
+	struct device_node *np = node ? node : dev->of_node;
 	struct of_phandle_args args;
 	struct mux_chip *mux_chip;
 	unsigned int controller;
@@ -635,7 +637,7 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
  */
 struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
 {
-	struct mux_control *mux = mux_get(dev, mux_name, NULL, false);
+	struct mux_control *mux = mux_get(dev, mux_name, NULL, false, NULL);
 
 	if (!mux)
 		return ERR_PTR(-ENOENT);
@@ -654,7 +656,7 @@ EXPORT_SYMBOL_GPL(mux_control_get);
  */
 struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name)
 {
-	return mux_get(dev, mux_name, NULL, true);
+	return mux_get(dev, mux_name, NULL, true, NULL);
 }
 EXPORT_SYMBOL_GPL(mux_control_get_optional);
 
@@ -712,11 +714,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.
  *
  * 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)
+static struct mux_state *
+mux_state_get(struct device *dev, const char *mux_name, bool optional,
+	      struct device_node *np)
 {
 	struct mux_state *mstate;
 
@@ -724,7 +729,7 @@ static struct mux_state *mux_state_get(struct device *dev, const char *mux_name,
 	if (!mstate)
 		return ERR_PTR(-ENOMEM);
 
-	mstate->mux = mux_get(dev, mux_name, &mstate->state, optional);
+	mstate->mux = mux_get(dev, mux_name, &mstate->state, optional, np);
 	if (IS_ERR(mstate->mux)) {
 		int err = PTR_ERR(mstate->mux);
 
@@ -773,7 +778,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,
+					      bool optional, struct device_node *np,
 					      int (*init)(struct mux_state *mstate),
 					      int (*exit)(struct mux_state *mstate))
 {
@@ -781,7 +786,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);
+	mstate = mux_state_get(dev, mux_name, optional, np);
 	if (IS_ERR(mstate))
 		return ERR_CAST(mstate);
 	else if (optional && !mstate)
@@ -815,20 +820,23 @@ static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mu
 }
 
 /**
- * devm_mux_state_get() - Get the mux-state for a device, with resource
- *			  management.
+ * devm_mux_state_get_from_np() - 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.
  *
  * 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(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)
 {
-	return __devm_mux_state_get(dev, mux_name, false, NULL, NULL);
+	return __devm_mux_state_get(dev, mux_name, false, np, NULL, NULL);
 }
-EXPORT_SYMBOL_GPL(devm_mux_state_get);
+EXPORT_SYMBOL_GPL(devm_mux_state_get_from_np);
 
 /**
  * devm_mux_state_get_optional() - Get the optional mux-state for a device,
@@ -843,7 +851,7 @@ EXPORT_SYMBOL_GPL(devm_mux_state_get);
  */
 struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 {
-	return __devm_mux_state_get(dev, mux_name, true, NULL, NULL);
+	return __devm_mux_state_get(dev, mux_name, true, NULL, NULL, NULL);
 }
 EXPORT_SYMBOL_GPL(devm_mux_state_get_optional);
 
@@ -861,7 +869,8 @@ EXPORT_SYMBOL_GPL(devm_mux_state_get_optional);
  */
 struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name)
 {
-	return __devm_mux_state_get(dev, mux_name, false, mux_state_select, mux_state_deselect);
+	return __devm_mux_state_get(dev, mux_name, false, NULL,
+				    mux_state_select, mux_state_deselect);
 }
 EXPORT_SYMBOL_GPL(devm_mux_state_get_selected);
 
@@ -881,7 +890,8 @@ EXPORT_SYMBOL_GPL(devm_mux_state_get_selected);
 struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
 						       const char *mux_name)
 {
-	return __devm_mux_state_get(dev, mux_name, true, mux_state_select, mux_state_deselect);
+	return __devm_mux_state_get(dev, mux_name, true, NULL,
+				    mux_state_select, mux_state_deselect);
 }
 EXPORT_SYMBOL_GPL(devm_mux_state_get_optional_selected);
 
diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
index a961861a503b33a3ea18aee6a2eb044866aa8801..449e38e6e2c515b3dd2b51a8b8cf0295a2520804 100644
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@ -60,7 +60,10 @@ struct mux_control *mux_control_get_optional(struct device *dev, const char *mux
 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(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);
+
 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);
 struct mux_state *devm_mux_state_get_optional_selected(struct device *dev, const char *mux_name);
@@ -161,4 +164,7 @@ 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)
+
 #endif /* _LINUX_MUX_CONSUMER_H */

-- 
2.43.0


  reply	other threads:[~2026-05-04 23:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-04 23:54 [PATCH v6 0/7] pinctrl: Add generic pinctrl for board-level mux chips Frank Li
2026-05-04 23:54 ` Frank Li [this message]
2026-05-04 23:54 ` [PATCH v6 2/7] dt-bindings: " Frank Li
2026-05-04 23:54 ` [PATCH v6 3/7] pinctrl: extract pinctrl_generic_to_map() from pinctrl_generic_pins_function_dt_node_to_map() Frank Li
2026-05-04 23:54 ` [PATCH v6 4/7] pinctrl: add optional .release_mux() callback Frank Li
2026-05-04 23:54 ` [PATCH v6 5/7] pinctrl: add generic board-level pinctrl driver using mux framework Frank Li
2026-05-04 23:54 ` [PATCH v6 6/7] arm64: dts: imx8mp-evk: add board-level mux for CAN2 and MICFIL Frank Li
2026-05-04 23:54 ` [PATCH v6 7/7] arm64: dts: imx8mp-evk: add flexcan2 overlay file Frank Li
2026-05-05 12:50 ` [PATCH v6 0/7] pinctrl: Add generic pinctrl for board-level mux chips Linus Walleij

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=20260504-pinctrl-mux-v6-1-8ea858ba3a5b@nxp.com \
    --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