[PATCH v4 1/7] mux: add devm_mux_control_get_from_np() to get mux from child node

Frank Li
2026-03-25T23:04:34Z

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

Make devm_mux_control_get() call devm_mux_control_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 v1 to v4
- none
---
drivers/mux/core.c | 40 ++++++++++++++++++++++++----------------
include/linux/mux/consumer.h | 16 ++++++++++++----
2 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index a3840fe0995fe0125432d34edd8ab0f2cd1a6e9a..bdd959389b4ee1b0b8a7367fadf2c148c8f2f0b1 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -522,13 +522,15 @@ static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np)
* @mux_name: The name identifying the mux-control.
* @state: Pointer to where the requested state is returned, or NULL when
* the required multiplexer states are handled by other means.
+ * @node: the device nodes, use dev->of_node if it is NULL.
*
* Return: A pointer to the mux-control, or an ERR_PTR with a negative errno.
*/
static struct mux_control *mux_get(struct device *dev, const char *mux_name,
- unsigned int *state)
+ unsigned int *state,
+ 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;
@@ -617,7 +619,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)
{
- return mux_get(dev, mux_name, NULL);
+ return mux_get(dev, mux_name, NULL, NULL);
}
EXPORT_SYMBOL_GPL(mux_control_get);

@@ -641,15 +643,17 @@ static void devm_mux_control_release(struct device *dev, void *res)
}

/**
- * devm_mux_control_get() - Get the mux-control for a device, with resource
- * management.
+ * devm_mux_control_get_from_np() - Get the mux-control 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-control, or an ERR_PTR with a negative errno.
*/
-struct mux_control *devm_mux_control_get(struct device *dev,
- const char *mux_name)
+struct mux_control *
+devm_mux_control_get_from_np(struct device *dev, const char *mux_name,
+ struct device_node *np)
{
struct mux_control **ptr, *mux;

@@ -668,16 +672,18 @@ struct mux_control *devm_mux_control_get(struct device *dev,

return mux;
}
-EXPORT_SYMBOL_GPL(devm_mux_control_get);
+EXPORT_SYMBOL_GPL(devm_mux_control_get_from_np);

/*
* mux_state_get() - Get the mux-state for a device.
* @dev: The device that needs a mux-state.
* @mux_name: The name identifying the mux-state.
+ * @np: the device nodes, use dev->of_node if it is NULL.
*
* Return: A pointer to the mux-state, or an ERR_PTR with a negative errno.
*/
-static struct mux_state *mux_state_get(struct device *dev, const char *mux_name)
+static struct mux_state *
+mux_state_get(struct device *dev, const char *mux_name, struct device_node *np)
{
struct mux_state *mstate;

@@ -685,7 +691,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);
+ mstate->mux = mux_get(dev, mux_name, &mstate->state, np);
if (IS_ERR(mstate->mux)) {
int err = PTR_ERR(mstate->mux);

@@ -716,15 +722,17 @@ static void devm_mux_state_release(struct device *dev, void *res)
}

/**
- * 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.
*/
-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 **ptr, *mstate;

@@ -732,7 +740,7 @@ struct mux_state *devm_mux_state_get(struct device *dev,
if (!ptr)
return ERR_PTR(-ENOMEM);

- mstate = mux_state_get(dev, mux_name);
+ mstate = mux_state_get(dev, mux_name, np);
if (IS_ERR(mstate)) {
devres_free(ptr);
return mstate;
@@ -743,7 +751,7 @@ struct mux_state *devm_mux_state_get(struct device *dev,

return mstate;
}
-EXPORT_SYMBOL_GPL(devm_mux_state_get);
+EXPORT_SYMBOL_GPL(devm_mux_state_get_from_np);

/*
* Using subsys_initcall instead of module_init here to try to ensure - for
diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
index 2e25c838f8312532040441ee618424b76378aad7..6300e091035323dd6158d52a55a109d43ef120aa 100644
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@ -56,9 +56,17 @@ int mux_state_deselect(struct mux_state *mstate);
struct mux_control *mux_control_get(struct device *dev, const char *mux_name);
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_control *
+devm_mux_control_get_from_np(struct device *dev, const char *mux_name,
+ struct device_node *np);
+
+#define devm_mux_control_get(dev, mux_name) \
+ devm_mux_control_get_from_np(dev, mux_name, NULL)
+
+struct mux_state *
+devm_mux_state_get_from_np(struct device *dev, const char *mux_name,
+ struct device_node *np);
+#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