devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux
@ 2025-12-29 14:27 Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict Josua Mayer
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Some Renesas SoC based boards mux SD and eMMC on a single sdio
controller, exposing user control by dip switch and software control by
gpio.

Purpose is to simplify development and provisioning by selecting boot
media at power-on, and again before starting linux.

Add binding and driver support for linking a (gpio) mux to renesas sdio
controller.

Introduce generic helper functions for getting managed and selected
mux-state objects, and switch i2c-omap and phy-can-transceiver drivers.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
Changes in v4:
- added MULTIPLEXER Kconfig help text.
- removed "select MULTIPLEXER" from renesas sdhi Kconfig, as it is
  not required for all devices using this driver.
- added stubs for all symbols exported by mux core.
  (Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>)
- refactored mux core logic to silence ENOENT errors only on optional
  code paths, keeping error printing unchanged otherwise.
  (Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>)
- picked up various reviewed- and acked-by tags
- Link to v3: https://lore.kernel.org/r/20251210-rz-sdio-mux-v3-0-ca628db56d60@solid-run.com

Changes in v3:
- updated omap-i2c and phy-can-transceiver to use new helpers.
- created generic helper functions for getting managed optional mux-state.
  (Reported-by: Rob Herring <robh@kernel.org>)
- picked up binding ack by Rob Herring.
- replaced use of "SDIO" with "SD/SDIO/eMMC" in binding document and
  commit descriptions.
  (Reported-by: Ulf Hansson <ulf.hansson@linaro.org>)
- Link to v2: https://lore.kernel.org/r/20251201-rz-sdio-mux-v2-0-bcb581b88dd7@solid-run.com

Changes in v2:
- dropped mux-controller node from dt binding example
  (Reported-by: Conor Dooley <conor@kernel.org>
   Reported-by: Krzysztof Kozlowski <krzk@kernel.org>)
- Link to v1: https://lore.kernel.org/r/20251128-rz-sdio-mux-v1-0-1ede318d160f@solid-run.com

---
Josua Mayer (7):
      phy: can-transceiver: rename temporary helper function to avoid conflict
      mux: Add helper functions for getting optional and selected mux-state
      mux: add help text for MULTIPLEXER config option
      phy: can-transceiver: drop temporary helper getting optional mux-state
      i2c: omap: switch to new generic helper for getting selected mux-state
      dt-bindings: mmc: renesas,sdhi: Add mux-states property
      mmc: host: renesas_sdhi_core: support selecting an optional mux

 .../devicetree/bindings/mmc/renesas,sdhi.yaml      |   6 +
 drivers/i2c/busses/i2c-omap.c                      |  19 +--
 drivers/mmc/host/renesas_sdhi.h                    |   1 +
 drivers/mmc/host/renesas_sdhi_core.c               |  16 ++-
 drivers/mux/Kconfig                                |   8 ++
 drivers/mux/core.c                                 | 153 ++++++++++++++++++---
 drivers/phy/phy-can-transceiver.c                  |  10 --
 include/linux/mux/consumer.h                       | 111 ++++++++++++++-
 8 files changed, 272 insertions(+), 52 deletions(-)
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20251128-rz-sdio-mux-acc5137f1618

Best regards,
-- 
Josua Mayer <josua@solid-run.com>



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

* [PATCH v4 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state Josua Mayer
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Rename the temporary devm_mux_state_get_optional function to avoid
conflict with upcoming implementation in multiplexer subsystem.

Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/phy/phy-can-transceiver.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 330356706ad7b..81591d2471282 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -128,7 +128,7 @@ MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
 
 /* Temporary wrapper until the multiplexer subsystem supports optional muxes */
 static inline struct mux_state *
-devm_mux_state_get_optional(struct device *dev, const char *mux_name)
+temp_devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 {
 	if (!of_property_present(dev->of_node, "mux-states"))
 		return NULL;
@@ -183,7 +183,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	priv->num_ch = num_ch;
 	platform_set_drvdata(pdev, priv);
 
-	mux_state = devm_mux_state_get_optional(dev, NULL);
+	mux_state = temp_devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 

-- 
2.51.0



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

* [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  2025-12-31 19:18   ` kernel test robot
  2025-12-29 14:27 ` [PATCH v4 3/7] mux: add help text for MULTIPLEXER config option Josua Mayer
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

In-tree phy-can-transceiver driver has already implemented a local
version of devm_mux_state_get_optional.

The omap-i2c driver gets and selects an optional mux in its probe
function without using any helper.

Add new helper functions covering both aforementioned use-cases:

- mux_control_get_optional:
  Get a mux-control if specified in dt, return NULL otherwise.
- devm_mux_state_get_optional:
  Get a mux-state if specified in dt, return NULL otherwise.
- devm_mux_state_get_selected:
  Get and select a mux-state specified in dt, return error otherwise.
- devm_mux_state_get_optional_selected:
  Get and select a mux-state if specified in dt, return error or NULL.

Existing mux_get helper function is changed to take an extra argument
indicating whether the mux is optional.
In this case no error is printed, and NULL returned in case of ENOENT.

Calling code is adapted to handle NULL return case, and to pass optional
argument as required.

Internal helpers are added so that optional and mandatory variants of
exported symbols can share code and pass through the optional argument
to core mux_get function:

- __devm_mux_state_get
- __devm_mux_state_get_selected

Commit e153fdea9db04 ("phy: can-transceiver: Re-instate "mux-states"
property presence check") noted that "mux_get() always prints an error
message in case of an error, including when the property is not present,
confusing the user."

The first error message covers the case that a mux name is not matched
in dt. The second error message is based on of_parse_phandle_with_args
return value.

In optional case no error is printed and NULL is returned.
This ensures that the new helper functions will not confuse the user
either.

With the addition of optional helper functions it became clear that
drivers should compile and link even if CONFIG_MULTIPLEXER was not enabled.
Add stubs for all symbols exported by mux core.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mux/core.c           | 153 +++++++++++++++++++++++++++++++++++++------
 include/linux/mux/consumer.h | 111 +++++++++++++++++++++++++++++--
 2 files changed, 240 insertions(+), 24 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index a3840fe0995fe..2aa2a29b21913 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -522,11 +522,12 @@ 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.
+ * @optional: Whether to return NULL and silence errors when mux doesn't exist.
  *
  * 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, bool optional)
 {
 	struct device_node *np = dev->of_node;
 	struct of_phandle_args args;
@@ -542,7 +543,9 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
 		else
 			index = of_property_match_string(np, "mux-control-names",
 							 mux_name);
-		if (index < 0) {
+		if (index < 0 && optional) {
+			return NULL;
+		} else if (index < 0) {
 			dev_err(dev, "mux controller '%s' not found\n",
 				mux_name);
 			return ERR_PTR(index);
@@ -558,8 +561,12 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
 						 "mux-controls", "#mux-control-cells",
 						 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);
+			np, state ? "state" : "control",
+			mux_name ?: "", index);
 		return ERR_PTR(ret);
 	}
 
@@ -617,10 +624,23 @@ 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, false);
 }
 EXPORT_SYMBOL_GPL(mux_control_get);
 
+/**
+ * mux_control_get_optional() - Get the optional mux-control for a device.
+ * @dev: The device that needs a mux-control.
+ * @mux_name: The name identifying the mux-control.
+ *
+ * Return: A pointer to the mux-control, an ERR_PTR with a negative errno.
+ */
+struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name)
+{
+	return mux_get(dev, mux_name, NULL, true);
+}
+EXPORT_SYMBOL_GPL(mux_control_get_optional);
+
 /**
  * mux_control_put() - Put away the mux-control for good.
  * @mux: The mux-control to put away.
@@ -657,8 +677,8 @@ struct mux_control *devm_mux_control_get(struct device *dev,
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	mux = mux_control_get(dev, mux_name);
-	if (IS_ERR(mux)) {
+	mux = mux_get(dev, mux_name, NULL, false);
+	if (IS_ERR_OR_NULL(mux)) {
 		devres_free(ptr);
 		return mux;
 	}
@@ -677,7 +697,7 @@ EXPORT_SYMBOL_GPL(devm_mux_control_get);
  *
  * 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, bool optional)
 {
 	struct mux_state *mstate;
 
@@ -685,12 +705,10 @@ 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);
-	if (IS_ERR(mstate->mux)) {
-		int err = PTR_ERR(mstate->mux);
-
+	mstate->mux = mux_get(dev, mux_name, &mstate->state, optional);
+	if (IS_ERR_OR_NULL(mstate->mux)) {
 		kfree(mstate);
-		return ERR_PTR(err);
+		return ERR_CAST(mstate->mux);
 	}
 
 	return mstate;
@@ -716,15 +734,16 @@ 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.
- * @dev: The device that needs a mux-control.
- * @mux_name: The name identifying the mux-control.
+ * __devm_mux_state_get() - Get the optional mux-state for a device,
+ *			    with resource management.
+ * @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.
  *
  * 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)
+static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mux_name,
+					      bool optional)
 {
 	struct mux_state **ptr, *mstate;
 
@@ -732,8 +751,8 @@ struct mux_state *devm_mux_state_get(struct device *dev,
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	mstate = mux_state_get(dev, mux_name);
-	if (IS_ERR(mstate)) {
+	mstate = mux_state_get(dev, mux_name, optional);
+	if (IS_ERR_OR_NULL(mstate)) {
 		devres_free(ptr);
 		return mstate;
 	}
@@ -743,8 +762,102 @@ struct mux_state *devm_mux_state_get(struct device *dev,
 
 	return mstate;
 }
+
+/**
+ * devm_mux_state_get() - 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.
+ *
+ * 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)
+{
+	return __devm_mux_state_get(dev, mux_name, false);
+}
 EXPORT_SYMBOL_GPL(devm_mux_state_get);
 
+/**
+ * devm_mux_state_get_optional() - Get the optional mux-state for a device,
+ *				   with resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ */
+struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name)
+{
+	return __devm_mux_state_get(dev, mux_name, true);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_optional);
+
+/**
+ * __devm_mux_state_get_selected() - Get the optional mux-state for a device,
+ *				     with resource management.
+ * @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.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The returned mux-state (if valid) is already selected.
+ */
+static struct mux_state *__devm_mux_state_get_selected(struct device *dev, const char *mux_name,
+						       bool optional)
+{
+	struct mux_state *mux_state;
+	int ret;
+
+	mux_state = __devm_mux_state_get(dev, mux_name, optional);
+	if (IS_ERR_OR_NULL(mux_state))
+		return mux_state;
+
+	ret = mux_state_select(mux_state);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to select mux-state %s: %d\n",
+				mux_name ?: "", ret);
+
+		mux_state_put(mux_state);
+		return ERR_PTR(ret);
+	}
+
+	return mux_state;
+}
+
+/**
+ * devm_mux_state_get_selected() - Get the mux-state for a device, with
+ *				   resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The returned mux-state (if valid) is already selected.
+ */
+struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name)
+{
+	return __devm_mux_state_get_selected(dev, mux_name, false);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_selected);
+
+/**
+ * devm_mux_state_get_optional_selected() - Get the optional mux-state for
+ *					    a device, with resource management.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
+ *
+ * The returned mux-state (if valid) is already selected.
+ */
+struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
+						       const char *mux_name)
+{
+	return __devm_mux_state_get_selected(dev, mux_name, true);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_optional_selected);
+
 /*
  * Using subsys_initcall instead of module_init here to try to ensure - for
  * the non-modular case - that the subsystem is initialized when mux consumers
diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
index 2e25c838f8312..8096ae34eb3a3 100644
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@ -16,6 +16,8 @@ struct device;
 struct mux_control;
 struct mux_state;
 
+#ifdef CONFIG_MULTIPLEXER
+
 unsigned int mux_control_states(struct mux_control *mux);
 int __must_check mux_control_select_delay(struct mux_control *mux,
 					  unsigned int state,
@@ -54,11 +56,112 @@ int mux_control_deselect(struct mux_control *mux);
 int mux_state_deselect(struct mux_state *mstate);
 
 struct mux_control *mux_control_get(struct device *dev, const char *mux_name);
+struct mux_control *mux_control_get_optional(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(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_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);
+
+#else
+
+static inline unsigned int mux_control_states(struct mux_control *mux)
+{
+	return 0;
+}
+static inline int __must_check mux_control_select_delay(struct mux_control *mux,
+							unsigned int state, unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+static inline int __must_check mux_state_select_delay(struct mux_state *mstate,
+						      unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+static inline int __must_check mux_control_try_select_delay(struct mux_control *mux,
+							    unsigned int state,
+							    unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+static inline int __must_check mux_state_try_select_delay(struct mux_state *mstate,
+							  unsigned int delay_us)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_control_select(struct mux_control *mux,
+						  unsigned int state)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_state_select(struct mux_state *mstate)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_control_try_select(struct mux_control *mux,
+						      unsigned int state)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __must_check mux_state_try_select(struct mux_state *mstate)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int mux_control_deselect(struct mux_control *mux)
+{
+	return -EOPNOTSUPP;
+}
+static inline int mux_state_deselect(struct mux_state *mstate)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_control *mux_control_get_optional(struct device *dev,
+							   const char *mux_name)
+{
+	return NULL;
+}
+static inline void mux_control_put(struct mux_control *mux)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_state *devm_mux_state_get_optional(struct device *dev,
+							    const char *mux_name)
+{
+	return NULL;
+}
+static inline struct mux_state *devm_mux_state_get_selected(struct device *dev,
+							    const char *mux_name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
+								     const char *mux_name)
+{
+	return NULL;
+}
+
+#endif /* CONFIG_MULTIPLEXER */
 
 #endif /* _LINUX_MUX_CONSUMER_H */

-- 
2.51.0



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

* [PATCH v4 3/7] mux: add help text for MULTIPLEXER config option
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 4/7] phy: can-transceiver: drop temporary helper getting optional mux-state Josua Mayer
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Add help text for CONFIG_MULTIPLEXER to allow enabling this option
through the kernel configuration without explicit "select" driver
dependencies.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mux/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index c68132e38138e..b2e1abc7c9104 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -5,6 +5,14 @@
 
 config MULTIPLEXER
 	tristate
+	help
+	  Generic Multiplexer Support.
+
+	  This framework is designed to abstract multiplexer handling for
+	  devices via various GPIO-, MMIO/Regmap or specific multiplexer
+	  controller chips.
+
+	  If unsure, say no.
 
 menu "Multiplexer drivers"
 	depends on MULTIPLEXER

-- 
2.51.0



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

* [PATCH v4 4/7] phy: can-transceiver: drop temporary helper getting optional mux-state
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
                   ` (2 preceding siblings ...)
  2025-12-29 14:27 ` [PATCH v4 3/7] mux: add help text for MULTIPLEXER config option Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 5/7] i2c: omap: switch to new generic helper for getting selected mux-state Josua Mayer
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Multiplexer subsystem has now added helpers for getting managed optional
mux-state.

Switch to the new devm_mux_state_get_optional helper.

This change is only compile-tested.

Acked-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/phy/phy-can-transceiver.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 81591d2471282..2b52e47f247a2 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -126,16 +126,6 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
 
-/* Temporary wrapper until the multiplexer subsystem supports optional muxes */
-static inline struct mux_state *
-temp_devm_mux_state_get_optional(struct device *dev, const char *mux_name)
-{
-	if (!of_property_present(dev->of_node, "mux-states"))
-		return NULL;
-
-	return devm_mux_state_get(dev, mux_name);
-}
-
 static struct phy *can_transceiver_phy_xlate(struct device *dev,
 					     const struct of_phandle_args *args)
 {
@@ -183,7 +173,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	priv->num_ch = num_ch;
 	platform_set_drvdata(pdev, priv);
 
-	mux_state = temp_devm_mux_state_get_optional(dev, NULL);
+	mux_state = devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 

-- 
2.51.0



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

* [PATCH v4 5/7] i2c: omap: switch to new generic helper for getting selected mux-state
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
                   ` (3 preceding siblings ...)
  2025-12-29 14:27 ` [PATCH v4 4/7] phy: can-transceiver: drop temporary helper getting optional mux-state Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 6/7] dt-bindings: mmc: renesas,sdhi: Add mux-states property Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux Josua Mayer
  6 siblings, 0 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Multiplexer subsystem has added generic helper functions for getting an
already selected mux-state object.

Replace existing logic in probe with the equivalent helper function.

This change is only compile-tested.

Reviewed-by: Andreas Kemnade <andreas@kemnade.info>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/i2c/busses/i2c-omap.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d9f590f0c3843..495d1f0c0c3e3 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1453,21 +1453,10 @@ omap_i2c_probe(struct platform_device *pdev)
 				       (1000 * omap->speed / 8);
 	}
 
-	if (of_property_present(node, "mux-states")) {
-		struct mux_state *mux_state;
-
-		mux_state = devm_mux_state_get(&pdev->dev, NULL);
-		if (IS_ERR(mux_state)) {
-			r = PTR_ERR(mux_state);
-			dev_dbg(&pdev->dev, "failed to get I2C mux: %d\n", r);
-			goto err_put_pm;
-		}
-		omap->mux_state = mux_state;
-		r = mux_state_select(omap->mux_state);
-		if (r) {
-			dev_err(&pdev->dev, "failed to select I2C mux: %d\n", r);
-			goto err_put_pm;
-		}
+	omap->mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
+	if (IS_ERR(omap->mux_state)) {
+		r = PTR_ERR(omap->mux_state);
+		goto err_put_pm;
 	}
 
 	/* reset ASAP, clearing any IRQs */

-- 
2.51.0



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

* [PATCH v4 6/7] dt-bindings: mmc: renesas,sdhi: Add mux-states property
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
                   ` (4 preceding siblings ...)
  2025-12-29 14:27 ` [PATCH v4 5/7] i2c: omap: switch to new generic helper for getting selected mux-state Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  2025-12-29 14:27 ` [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux Josua Mayer
  6 siblings, 0 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Add mux controller support for data or control lines that are muxed
between a host and multiple cards.

There are several devices supporting a choice of eMMC or SD on a single
board by both dip switch and gpio, e.g. Renesas RZ/G2L SMARC SoM and
SolidRun RZ/G2L SoM.

In-tree dts for the Renesas boards currently rely on preprocessor macros
and gpio hogs to describe the respective cards.

By adding mux-states property to sdhi controller description, boards can
correctly describe the mux that already exists in hardware - and drivers
can coordinate between mux selection and probing for cards.

Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
index c754ea71f51f7..64fac0d11329a 100644
--- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
+++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
@@ -106,6 +106,11 @@ properties:
   iommus:
     maxItems: 1
 
+  mux-states:
+    description:
+      mux controller node to route the SD/SDIO/eMMC signals from SoC to cards.
+    maxItems: 1
+
   power-domains:
     maxItems: 1
 
@@ -275,6 +280,7 @@ examples:
         max-frequency = <195000000>;
         power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
         resets = <&cpg 314>;
+        mux-states = <&mux 0>;
     };
 
     sdhi1: mmc@ee120000 {

-- 
2.51.0



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

* [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
  2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
                   ` (5 preceding siblings ...)
  2025-12-29 14:27 ` [PATCH v4 6/7] dt-bindings: mmc: renesas,sdhi: Add mux-states property Josua Mayer
@ 2025-12-29 14:27 ` Josua Mayer
  6 siblings, 0 replies; 9+ messages in thread
From: Josua Mayer @ 2025-12-29 14:27 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Wolfram Sang, Marc Kleine-Budde,
	Vincent Mailhol, Vinod Koul, Kishon Vijay Abraham I, Peter Rosin,
	Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Vignesh R, Janusz Krzysztofik, Andi Shyti,
	Neil Armstrong
  Cc: Mikhail Anikin, Yazan Shhady, Jon Nettleton, linux-mmc,
	devicetree, linux-kernel, linux-renesas-soc, linux-can, linux-phy,
	linux-omap, linux-i2c, Josua Mayer

Some hardware designs route data or control signals through a mux to
support multiple devices on a single sdhi controller.

In particular SolidRun RZ/G2L/G2LC/V2L System on Module use a mux for
switching between soldered eMMC and an optional microSD on a carrier
board, e.g. for development or provisioning.

SD/SDIO/eMMC are not well suited for runtime switching between different
cards, however boot-time selection is possible and useful - in
particular considering dt overlays.

Add support for an optional SD/SDIO/eMMC mux defined in dt, and select
it during probe.

Similar functionality already exists in other places, e.g. i2c-omap.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mmc/host/renesas_sdhi.h      |  1 +
 drivers/mmc/host/renesas_sdhi_core.c | 16 +++++++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index afc36a407c2c1..6f4c389a5bfe2 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -98,6 +98,7 @@ struct renesas_sdhi {
 	struct reset_control *rstc;
 	struct tmio_mmc_host *host;
 	struct regulator_dev *rdev;
+	struct mux_state *mux_state;
 };
 
 #define host_to_priv(host) \
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 2a310a1457855..cec7e5fa5aa96 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -26,6 +26,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
+#include <linux/mux/consumer.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinctrl-state.h>
 #include <linux/platform_data/tmio.h>
@@ -1116,9 +1117,15 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 						"state_uhs");
 	}
 
+	priv->mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
+	if (IS_ERR(priv->mux_state))
+		return PTR_ERR(priv->mux_state);
+
 	host = tmio_mmc_host_alloc(pdev, mmc_data);
-	if (IS_ERR(host))
-		return PTR_ERR(host);
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto edselmux;
+	}
 
 	priv->host = host;
 
@@ -1201,7 +1208,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 
 	ret = renesas_sdhi_clk_enable(host);
 	if (ret)
-		return ret;
+		goto edselmux;
 
 	rcfg.of_node = of_get_available_child_by_name(dev->of_node, "vqmmc-regulator");
 	if (rcfg.of_node) {
@@ -1305,6 +1312,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 
 edisclk:
 	renesas_sdhi_clk_disable(host);
+edselmux:
+	if (priv->mux_state)
+		mux_state_deselect(priv->mux_state);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(renesas_sdhi_probe);

-- 
2.51.0



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

* Re: [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state
  2025-12-29 14:27 ` [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state Josua Mayer
@ 2025-12-31 19:18   ` kernel test robot
  0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2025-12-31 19:18 UTC (permalink / raw)
  To: Josua Mayer, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang,
	Marc Kleine-Budde, Vincent Mailhol, Vinod Koul,
	Kishon Vijay Abraham I, Peter Rosin, Aaro Koskinen,
	Andreas Kemnade, Kevin Hilman, Roger Quadros, Tony Lindgren,
	Vignesh R, Janusz Krzysztofik, Andi Shyti, Neil Armstrong
  Cc: oe-kbuild-all, Mikhail Anikin, Yazan Shhady, Jon Nettleton,
	linux-mmc, devicetree, linux-kernel, linux-renesas-soc, linux-can,
	linux-phy

Hi Josua,

kernel test robot noticed the following build errors:

[auto build test ERROR on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Josua-Mayer/phy-can-transceiver-rename-temporary-helper-function-to-avoid-conflict/20251229-223153
base:   8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link:    https://lore.kernel.org/r/20251229-rz-sdio-mux-v4-2-a023e55758fe%40solid-run.com
patch subject: [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state
config: parisc-randconfig-002-20260101 (https://download.01.org/0day-ci/archive/20260101/202601010305.tpY47HE4-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260101/202601010305.tpY47HE4-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601010305.tpY47HE4-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h: In function 'mux_control_put':
>> include/linux/mux/consumer.h:138:9: warning: 'return' with a value, in function returning void [-Wreturn-type]
     138 |  return -EOPNOTSUPP;
         |         ^
   include/linux/mux/consumer.h:136:20: note: declared here
     136 | static inline void mux_control_put(struct mux_control *mux)
         |                    ^~~~~~~~~~~~~~~
   drivers/mux/core.c: At top level:
>> drivers/mux/core.c:302:14: error: redefinition of 'mux_control_states'
     302 | unsigned int mux_control_states(struct mux_control *mux)
         |              ^~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:70:28: note: previous definition of 'mux_control_states' was here
      70 | static inline unsigned int mux_control_states(struct mux_control *mux)
         |                            ^~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:365:5: error: redefinition of 'mux_control_select_delay'
     365 | int mux_control_select_delay(struct mux_control *mux, unsigned int state,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:74:32: note: previous definition of 'mux_control_select_delay' was here
      74 | static inline int __must_check mux_control_select_delay(struct mux_control *mux,
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:403:5: error: redefinition of 'mux_state_select_delay'
     403 | int mux_state_select_delay(struct mux_state *mstate, unsigned int delay_us)
         |     ^~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:79:32: note: previous definition of 'mux_state_select_delay' was here
      79 | static inline int __must_check mux_state_select_delay(struct mux_state *mstate,
         |                                ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:425:5: error: redefinition of 'mux_control_try_select_delay'
     425 | int mux_control_try_select_delay(struct mux_control *mux, unsigned int state,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:84:32: note: previous definition of 'mux_control_try_select_delay' was here
      84 | static inline int __must_check mux_control_try_select_delay(struct mux_control *mux,
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:459:5: error: redefinition of 'mux_state_try_select_delay'
     459 | int mux_state_try_select_delay(struct mux_state *mstate, unsigned int delay_us)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:90:32: note: previous definition of 'mux_state_try_select_delay' was here
      90 | static inline int __must_check mux_state_try_select_delay(struct mux_state *mstate,
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:477:5: error: redefinition of 'mux_control_deselect'
     477 | int mux_control_deselect(struct mux_control *mux)
         |     ^~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:118:19: note: previous definition of 'mux_control_deselect' was here
     118 | static inline int mux_control_deselect(struct mux_control *mux)
         |                   ^~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:503:5: error: redefinition of 'mux_state_deselect'
     503 | int mux_state_deselect(struct mux_state *mstate)
         |     ^~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:122:19: note: previous definition of 'mux_state_deselect' was here
     122 | static inline int mux_state_deselect(struct mux_state *mstate)
         |                   ^~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:625:21: error: redefinition of 'mux_control_get'
     625 | struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
         |                     ^~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:127:35: note: previous definition of 'mux_control_get' was here
     127 | static inline struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
         |                                   ^~~~~~~~~~~~~~~
>> drivers/mux/core.c:638:21: error: redefinition of 'mux_control_get_optional'
     638 | struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name)
         |                     ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:131:35: note: previous definition of 'mux_control_get_optional' was here
     131 | static inline struct mux_control *mux_control_get_optional(struct device *dev,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:650:6: error: redefinition of 'mux_control_put'
     650 | void mux_control_put(struct mux_control *mux)
         |      ^~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:136:20: note: previous definition of 'mux_control_put' was here
     136 | static inline void mux_control_put(struct mux_control *mux)
         |                    ^~~~~~~~~~~~~~~
>> drivers/mux/core.c:671:21: error: redefinition of 'devm_mux_control_get'
     671 | struct mux_control *devm_mux_control_get(struct device *dev,
         |                     ^~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:141:35: note: previous definition of 'devm_mux_control_get' was here
     141 | static inline struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name)
         |                                   ^~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:774:19: error: redefinition of 'devm_mux_state_get'
     774 | struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
         |                   ^~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:145:33: note: previous definition of 'devm_mux_state_get' was here
     145 | static inline struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
         |                                 ^~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:788:19: error: redefinition of 'devm_mux_state_get_optional'
     788 | struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name)
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:149:33: note: previous definition of 'devm_mux_state_get_optional' was here
     149 | static inline struct mux_state *devm_mux_state_get_optional(struct device *dev,
         |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:838:19: error: redefinition of 'devm_mux_state_get_selected'
     838 | struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name)
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:154:33: note: previous definition of 'devm_mux_state_get_selected' was here
     154 | static inline struct mux_state *devm_mux_state_get_selected(struct device *dev,
         |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mux/core.c:854:19: error: redefinition of 'devm_mux_state_get_optional_selected'
     854 | struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/mux/core.c:19:
   include/linux/mux/consumer.h:159:33: note: previous definition of 'devm_mux_state_get_optional_selected' was here
     159 | static inline struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
         |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   In file included from core.c:19:
   include/linux/mux/consumer.h: In function 'mux_control_put':
>> include/linux/mux/consumer.h:138:9: warning: 'return' with a value, in function returning void [-Wreturn-type]
     138 |  return -EOPNOTSUPP;
         |         ^
   include/linux/mux/consumer.h:136:20: note: declared here
     136 | static inline void mux_control_put(struct mux_control *mux)
         |                    ^~~~~~~~~~~~~~~
   core.c: At top level:
   core.c:302:14: error: redefinition of 'mux_control_states'
     302 | unsigned int mux_control_states(struct mux_control *mux)
         |              ^~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:70:28: note: previous definition of 'mux_control_states' was here
      70 | static inline unsigned int mux_control_states(struct mux_control *mux)
         |                            ^~~~~~~~~~~~~~~~~~
   core.c:365:5: error: redefinition of 'mux_control_select_delay'
     365 | int mux_control_select_delay(struct mux_control *mux, unsigned int state,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:74:32: note: previous definition of 'mux_control_select_delay' was here
      74 | static inline int __must_check mux_control_select_delay(struct mux_control *mux,
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~
   core.c:403:5: error: redefinition of 'mux_state_select_delay'
     403 | int mux_state_select_delay(struct mux_state *mstate, unsigned int delay_us)
         |     ^~~~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:79:32: note: previous definition of 'mux_state_select_delay' was here
      79 | static inline int __must_check mux_state_select_delay(struct mux_state *mstate,
         |                                ^~~~~~~~~~~~~~~~~~~~~~
   core.c:425:5: error: redefinition of 'mux_control_try_select_delay'
     425 | int mux_control_try_select_delay(struct mux_control *mux, unsigned int state,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:84:32: note: previous definition of 'mux_control_try_select_delay' was here
      84 | static inline int __must_check mux_control_try_select_delay(struct mux_control *mux,
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   core.c:459:5: error: redefinition of 'mux_state_try_select_delay'
     459 | int mux_state_try_select_delay(struct mux_state *mstate, unsigned int delay_us)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:90:32: note: previous definition of 'mux_state_try_select_delay' was here
      90 | static inline int __must_check mux_state_try_select_delay(struct mux_state *mstate,
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~
   core.c:477:5: error: redefinition of 'mux_control_deselect'
     477 | int mux_control_deselect(struct mux_control *mux)
         |     ^~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:118:19: note: previous definition of 'mux_control_deselect' was here
     118 | static inline int mux_control_deselect(struct mux_control *mux)
         |                   ^~~~~~~~~~~~~~~~~~~~
   core.c:503:5: error: redefinition of 'mux_state_deselect'
     503 | int mux_state_deselect(struct mux_state *mstate)
         |     ^~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:122:19: note: previous definition of 'mux_state_deselect' was here
     122 | static inline int mux_state_deselect(struct mux_state *mstate)
         |                   ^~~~~~~~~~~~~~~~~~
   core.c:625:21: error: redefinition of 'mux_control_get'
     625 | struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
         |                     ^~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:127:35: note: previous definition of 'mux_control_get' was here
     127 | static inline struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
         |                                   ^~~~~~~~~~~~~~~
   core.c:638:21: error: redefinition of 'mux_control_get_optional'
     638 | struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name)
         |                     ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:131:35: note: previous definition of 'mux_control_get_optional' was here
     131 | static inline struct mux_control *mux_control_get_optional(struct device *dev,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~~
   core.c:650:6: error: redefinition of 'mux_control_put'
     650 | void mux_control_put(struct mux_control *mux)
         |      ^~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:136:20: note: previous definition of 'mux_control_put' was here
     136 | static inline void mux_control_put(struct mux_control *mux)
         |                    ^~~~~~~~~~~~~~~
   core.c:671:21: error: redefinition of 'devm_mux_control_get'
     671 | struct mux_control *devm_mux_control_get(struct device *dev,
         |                     ^~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:141:35: note: previous definition of 'devm_mux_control_get' was here
     141 | static inline struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name)
         |                                   ^~~~~~~~~~~~~~~~~~~~
   core.c:774:19: error: redefinition of 'devm_mux_state_get'
     774 | struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
         |                   ^~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:145:33: note: previous definition of 'devm_mux_state_get' was here
     145 | static inline struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
         |                                 ^~~~~~~~~~~~~~~~~~
   core.c:788:19: error: redefinition of 'devm_mux_state_get_optional'
     788 | struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name)
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from core.c:19:
   include/linux/mux/consumer.h:149:33: note: previous definition of 'devm_mux_state_get_optional' was here
     149 | static inline struct mux_state *devm_mux_state_get_optional(struct device *dev,
         |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   core.c:838:19: error: redefinition of 'devm_mux_state_get_selected'
     838 | struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name)
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/mux_control_states +302 drivers/mux/core.c

a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  295  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  296  /**
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  297   * mux_control_states() - Query the number of multiplexer states.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  298   * @mux: The mux-control to query.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  299   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  300   * Return: The number of multiplexer states.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  301   */
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14 @302  unsigned int mux_control_states(struct mux_control *mux)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  303  {
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  304  	return mux->states;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  305  }
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  306  EXPORT_SYMBOL_GPL(mux_control_states);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  307  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  308  /*
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  309   * The mux->lock must be down when calling this function.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  310   */
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  311  static int __mux_control_select(struct mux_control *mux, int state)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  312  {
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  313  	int ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  314  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  315  	if (WARN_ON(state < 0 || state >= mux->states))
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  316  		return -EINVAL;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  317  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  318  	if (mux->cached_state == state)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  319  		return 0;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  320  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  321  	ret = mux_control_set(mux, state);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  322  	if (ret >= 0)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  323  		return 0;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  324  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  325  	/* The mux update failed, try to revert if appropriate... */
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  326  	if (mux->idle_state != MUX_IDLE_AS_IS)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  327  		mux_control_set(mux, mux->idle_state);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  328  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  329  	return ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  330  }
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  331  
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  332  static void mux_control_delay(struct mux_control *mux, unsigned int delay_us)
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  333  {
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  334  	ktime_t delayend;
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  335  	s64 remaining;
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  336  
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  337  	if (!delay_us)
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  338  		return;
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  339  
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  340  	delayend = ktime_add_us(mux->last_change, delay_us);
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  341  	remaining = ktime_us_delta(delayend, ktime_get());
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  342  	if (remaining > 0)
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  343  		fsleep(remaining);
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  344  }
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  345  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  346  /**
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  347   * mux_control_select_delay() - Select the given multiplexer state.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  348   * @mux: The mux-control to request a change of state from.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  349   * @state: The new requested state.
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  350   * @delay_us: The time to delay (in microseconds) if the mux state is changed.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  351   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  352   * On successfully selecting the mux-control state, it will be locked until
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  353   * there is a call to mux_control_deselect(). If the mux-control is already
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  354   * selected when mux_control_select() is called, the caller will be blocked
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  355   * until mux_control_deselect() or mux_state_deselect() is called (by someone
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  356   * else).
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  357   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  358   * Therefore, make sure to call mux_control_deselect() when the operation is
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  359   * complete and the mux-control is free for others to use, but do not call
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  360   * mux_control_deselect() if mux_control_select() fails.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  361   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  362   * Return: 0 when the mux-control state has the requested state or a negative
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  363   * errno on error.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  364   */
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07 @365  int mux_control_select_delay(struct mux_control *mux, unsigned int state,
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  366  			     unsigned int delay_us)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  367  {
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  368  	int ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  369  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  370  	ret = down_killable(&mux->lock);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  371  	if (ret < 0)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  372  		return ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  373  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  374  	ret = __mux_control_select(mux, state);
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  375  	if (ret >= 0)
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  376  		mux_control_delay(mux, delay_us);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  377  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  378  	if (ret < 0)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  379  		up(&mux->lock);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  380  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  381  	return ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  382  }
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  383  EXPORT_SYMBOL_GPL(mux_control_select_delay);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  384  
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  385  /**
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  386   * mux_state_select_delay() - Select the given multiplexer state.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  387   * @mstate: The mux-state to select.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  388   * @delay_us: The time to delay (in microseconds) if the mux state is changed.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  389   *
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  390   * On successfully selecting the mux-state, its mux-control will be locked
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  391   * until there is a call to mux_state_deselect(). If the mux-control is already
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  392   * selected when mux_state_select() is called, the caller will be blocked
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  393   * until mux_state_deselect() or mux_control_deselect() is called (by someone
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  394   * else).
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  395   *
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  396   * Therefore, make sure to call mux_state_deselect() when the operation is
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  397   * complete and the mux-control is free for others to use, but do not call
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  398   * mux_state_deselect() if mux_state_select() fails.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  399   *
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  400   * Return: 0 when the mux-state has been selected or a negative
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  401   * errno on error.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  402   */
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07 @403  int mux_state_select_delay(struct mux_state *mstate, unsigned int delay_us)
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  404  {
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  405  	return mux_control_select_delay(mstate->mux, mstate->state, delay_us);
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  406  }
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  407  EXPORT_SYMBOL_GPL(mux_state_select_delay);
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  408  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  409  /**
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  410   * mux_control_try_select_delay() - Try to select the given multiplexer state.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  411   * @mux: The mux-control to request a change of state from.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  412   * @state: The new requested state.
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  413   * @delay_us: The time to delay (in microseconds) if the mux state is changed.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  414   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  415   * On successfully selecting the mux-control state, it will be locked until
f22d1117b9c3e2 drivers/mux/core.c     Peter Rosin        2022-01-07  416   * mux_control_deselect() is called.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  417   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  418   * Therefore, make sure to call mux_control_deselect() when the operation is
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  419   * complete and the mux-control is free for others to use, but do not call
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  420   * mux_control_deselect() if mux_control_try_select() fails.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  421   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  422   * Return: 0 when the mux-control state has the requested state or a negative
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  423   * errno on error. Specifically -EBUSY if the mux-control is contended.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  424   */
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07 @425  int mux_control_try_select_delay(struct mux_control *mux, unsigned int state,
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  426  				 unsigned int delay_us)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  427  {
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  428  	int ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  429  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  430  	if (down_trylock(&mux->lock))
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  431  		return -EBUSY;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  432  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  433  	ret = __mux_control_select(mux, state);
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  434  	if (ret >= 0)
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  435  		mux_control_delay(mux, delay_us);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  436  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  437  	if (ret < 0)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  438  		up(&mux->lock);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  439  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  440  	return ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  441  }
17b5b576ff5faf drivers/mux/core.c     Vincent Whitchurch 2021-10-07  442  EXPORT_SYMBOL_GPL(mux_control_try_select_delay);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  443  
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  444  /**
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  445   * mux_state_try_select_delay() - Try to select the given multiplexer state.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  446   * @mstate: The mux-state to select.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  447   * @delay_us: The time to delay (in microseconds) if the mux state is changed.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  448   *
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  449   * On successfully selecting the mux-state, its mux-control will be locked
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  450   * until mux_state_deselect() is called.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  451   *
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  452   * Therefore, make sure to call mux_state_deselect() when the operation is
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  453   * complete and the mux-control is free for others to use, but do not call
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  454   * mux_state_deselect() if mux_state_try_select() fails.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  455   *
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  456   * Return: 0 when the mux-state has been selected or a negative errno on
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  457   * error. Specifically -EBUSY if the mux-control is contended.
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  458   */
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07 @459  int mux_state_try_select_delay(struct mux_state *mstate, unsigned int delay_us)
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  460  {
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  461  	return mux_control_try_select_delay(mstate->mux, mstate->state, delay_us);
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  462  }
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  463  EXPORT_SYMBOL_GPL(mux_state_try_select_delay);
84564481bc4520 drivers/mux/core.c     Aswath Govindraju  2022-01-07  464  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  465  /**
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  466   * mux_control_deselect() - Deselect the previously selected multiplexer state.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  467   * @mux: The mux-control to deselect.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  468   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  469   * It is required that a single call is made to mux_control_deselect() for
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  470   * each and every successful call made to either of mux_control_select() or
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  471   * mux_control_try_select().
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  472   *
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  473   * Return: 0 on success and a negative errno on error. An error can only
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  474   * occur if the mux has an idle state. Note that even if an error occurs, the
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  475   * mux-control is unlocked and is thus free for the next access.
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  476   */
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14 @477  int mux_control_deselect(struct mux_control *mux)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  478  {
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  479  	int ret = 0;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  480  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  481  	if (mux->idle_state != MUX_IDLE_AS_IS &&
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  482  	    mux->idle_state != mux->cached_state)
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  483  		ret = mux_control_set(mux, mux->idle_state);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  484  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  485  	up(&mux->lock);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  486  
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  487  	return ret;
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  488  }
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  489  EXPORT_SYMBOL_GPL(mux_control_deselect);
a3b02a9c6591ce drivers/mux/mux-core.c Peter Rosin        2017-05-14  490  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

end of thread, other threads:[~2025-12-31 19:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-29 14:27 [PATCH v4 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux Josua Mayer
2025-12-29 14:27 ` [PATCH v4 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict Josua Mayer
2025-12-29 14:27 ` [PATCH v4 2/7] mux: Add helper functions for getting optional and selected mux-state Josua Mayer
2025-12-31 19:18   ` kernel test robot
2025-12-29 14:27 ` [PATCH v4 3/7] mux: add help text for MULTIPLEXER config option Josua Mayer
2025-12-29 14:27 ` [PATCH v4 4/7] phy: can-transceiver: drop temporary helper getting optional mux-state Josua Mayer
2025-12-29 14:27 ` [PATCH v4 5/7] i2c: omap: switch to new generic helper for getting selected mux-state Josua Mayer
2025-12-29 14:27 ` [PATCH v4 6/7] dt-bindings: mmc: renesas,sdhi: Add mux-states property Josua Mayer
2025-12-29 14:27 ` [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux Josua Mayer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).