[PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux

Josua Mayer posted 7 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
Posted by Josua Mayer 1 month, 1 week ago
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
Re: [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
Posted by Wolfram Sang 3 weeks, 5 days ago
Hi Josua,

thanks for your work and kudos for striving for a generic solution. It
seems worthwhile to me to add the helpers. I have questions, though:

> +	priv->mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);

The minor nit (which may be bike-shedding): Maybe the function name
could be '*_select' instead of '*_selected'. To make more explicit that
this function is actively changing the selection and not passively
retrieving the current state?

The bigger thing is that with devm_* I had the expectation that
deselection is also handled automatically...

> +edselmux:
> +	if (priv->mux_state)
> +		mux_state_deselect(priv->mux_state);

... so I was a bit surprised to see this manual cleanup. Has it been
discussed if that deselection can also be in the helpers?

Happy hacking,

   Wolfram
Re: [PATCH v4 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
Posted by Josua Mayer 3 weeks, 1 day ago
Hi Wolfram,

On 14/01/2026 13:49, Wolfram Sang wrote:
> Hi Josua,
>
> thanks for your work and kudos for striving for a generic solution. It
> seems worthwhile to me to add the helpers. I have questions, though:
>
>> +	priv->mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
> The minor nit (which may be bike-shedding): Maybe the function name
> could be '*_select' instead of '*_selected'. To make more explicit that
> this function is actively changing the selection and not passively
> retrieving the current state?
I have no strong opinion on select vs. selected.
I merely followed the devm_clk_get_enabled/selected.
>
> The bigger thing is that with devm_* I had the expectation that
> deselection is also handled automatically...
>
>> +edselmux:
>> +	if (priv->mux_state)
>> +		mux_state_deselect(priv->mux_state);
> ... so I was a bit surprised to see this manual cleanup. Has it been
> discussed if that deselection can also be in the helpers?
I have not considered adding this, and was careful
not to imply it in the function descriptions.

At the time I felt adding helpers was growing in complexity too fast,
and I am not very familair with devres.

I agree that the general expectation is devm functions are fully managed,
in this case including deselect.

>
> Happy hacking,
>
>     Wolfram
>
>
sincerely
Josua Mayer