Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v9 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
From: kernel test robot @ 2026-02-09  2:12 UTC (permalink / raw)
  To: Josua Mayer, Marc Kleine-Budde, Vincent Mailhol, Vinod Koul,
	Neil Armstrong, Peter Rosin, Aaro Koskinen, Andreas Kemnade,
	Kevin Hilman, Roger Quadros, Tony Lindgren, Janusz Krzysztofik,
	Vignesh R, Andi Shyti, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
	Magnus Damm, Wolfram Sang
  Cc: oe-kbuild-all, Yazan Shhady, Jon Nettleton, Mikhail Anikin,
	linux-can, linux-phy, linux-kernel, linux-omap, linux-i2c,
	linux-mmc, devicetree
In-Reply-To: <20260208-rz-sdio-mux-v9-7-9a3be13c1280@solid-run.com>

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/20260208-234345
base:   8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link:    https://lore.kernel.org/r/20260208-rz-sdio-mux-v9-7-9a3be13c1280%40solid-run.com
patch subject: [PATCH v9 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
config: s390-randconfig-r054-20260209 (https://download.01.org/0day-ci/archive/20260209/202602091037.wNIGJdbh-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260209/202602091037.wNIGJdbh-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/202602091037.wNIGJdbh-lkp@intel.com/

All errors (new ones prefixed by >>):

   s390-linux-ld: drivers/mmc/host/renesas_sdhi_core.o: in function `renesas_sdhi_probe':
>> renesas_sdhi_core.c:(.text+0x1996): undefined reference to `devm_mux_state_get_optional_selected'

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

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH v9 7/7] mmc: host: renesas_sdhi_core: support selecting an optional mux
From: Josua Mayer @ 2026-02-08 15:39 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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.

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mmc/host/renesas_sdhi_core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 2a310a145785..f9ec78d699f4 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>
@@ -1062,6 +1063,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 	struct regulator_dev *rdev;
 	struct renesas_sdhi_dma *dma_priv;
 	struct device *dev = &pdev->dev;
+	struct mux_state *mux_state;
 	struct tmio_mmc_host *host;
 	struct renesas_sdhi *priv;
 	int num_irqs, irq, ret, i;
@@ -1116,6 +1118,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 						"state_uhs");
 	}
 
+	mux_state = devm_mux_state_get_optional_selected(&pdev->dev, NULL);
+	if (IS_ERR(mux_state))
+		return PTR_ERR(mux_state);
+
 	host = tmio_mmc_host_alloc(pdev, mmc_data);
 	if (IS_ERR(host))
 		return PTR_ERR(host);

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v9 6/7] dt-bindings: mmc: renesas,sdhi: Add mux-states property
From: Josua Mayer @ 2026-02-08 15:39 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
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 c754ea71f51f..64fac0d11329 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.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v9 5/7] i2c: omap: switch to new generic helper for getting selected mux-state
From: Josua Mayer @ 2026-02-08 15:39 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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.

There is a functional difference in that the mux is now automatically
deselected on release, replacing the explicit mux_state_deselect call.

This change is only compile-tested.

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Andreas Kemnade <andreas@kemnade.info>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/i2c/busses/i2c-omap.c | 24 +++++-------------------
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d9f590f0c384..f02d294db42a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1453,27 +1453,16 @@ 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 */
 	r = omap_i2c_init(omap);
 	if (r)
-		goto err_mux_state_deselect;
+		goto err_put_pm;
 
 	if (omap->rev < OMAP_I2C_OMAP1_REV_2)
 		r = devm_request_irq(&pdev->dev, omap->irq, omap_i2c_omap1_isr,
@@ -1515,9 +1504,6 @@ omap_i2c_probe(struct platform_device *pdev)
 
 err_unuse_clocks:
 	omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
-err_mux_state_deselect:
-	if (omap->mux_state)
-		mux_state_deselect(omap->mux_state);
 err_put_pm:
 	pm_runtime_put_sync(omap->dev);
 err_disable_pm:

-- 
2.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v9 4/7] phy: can-transceiver: drop temporary helper getting optional mux-state
From: Josua Mayer @ 2026-02-08 15:38 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
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 81591d247128..2b52e47f247a 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.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v9 2/7] mux: Add helper functions for getting optional and selected mux-state
From: Josua Mayer @ 2026-02-08 15:38 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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.

To support automatic deselect for _selected helper, a new structure is
created storing an exit pointer similar to clock core which is called on
release.

To facilitate code sharing between optional/mandatory/selected helpers,
a new internal helper function is added to handle quiet (optional) and
verbose (mandatory) errors, as well as storing the correct callback for
devm release: __devm_mux_state_get

Due to this structure devm_mux_state_get_*_selected can no longer print
a useful error message when select fails. Instead callers should print
errors where needed.

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.

Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 drivers/mux/core.c           | 206 ++++++++++++++++++++++++++++++++++++-------
 include/linux/mux/consumer.h | 108 ++++++++++++++++++++++-
 2 files changed, 279 insertions(+), 35 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index a3840fe0995f..b3ed3a094a09 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -46,6 +46,16 @@ static const struct class mux_class = {
 	.name = "mux",
 };
 
+/**
+ * struct devm_mux_state_state -	Tracks managed resources for mux-state objects.
+ * @mstate:				Pointer to a mux state.
+ * @exit:				An optional callback to execute before free.
+ */
+struct devm_mux_state_state {
+	struct mux_state *mstate;
+	int (*exit)(struct mux_state *mstate);
+};
+
 static DEFINE_IDA(mux_ida);
 
 static int __init mux_init(void)
@@ -516,17 +526,19 @@ static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np)
 	return dev ? to_mux_chip(dev) : NULL;
 }
 
-/*
+/**
  * mux_get() - Get the mux-control for a device.
  * @dev: The device that needs a mux-control.
  * @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.
+ * 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)
+				   unsigned int *state, bool optional)
 {
 	struct device_node *np = dev->of_node;
 	struct of_phandle_args args;
@@ -542,7 +554,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 +572,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 +635,29 @@ 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);
+	struct mux_control *mux = mux_get(dev, mux_name, NULL, false);
+
+	if (!mux)
+		return ERR_PTR(-ENOENT);
+
+	return mux;
 }
 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: Pointer to the mux-state on success, an ERR_PTR with a negative errno on error,
+ * or NULL if mux doesn't exist.
+ */
+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,10 +694,13 @@ struct mux_control *devm_mux_control_get(struct device *dev,
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	mux = mux_control_get(dev, mux_name);
+	mux = mux_get(dev, mux_name, NULL, false);
 	if (IS_ERR(mux)) {
 		devres_free(ptr);
 		return mux;
+	} else if (!mux) {
+		devres_free(ptr);
+		return ERR_PTR(-ENOENT);
 	}
 
 	*ptr = mux;
@@ -670,14 +710,16 @@ struct mux_control *devm_mux_control_get(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_mux_control_get);
 
-/*
+/**
  * 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.
+ * @optional: Whether to return NULL and silence errors when mux doesn't exist.
  *
- * Return: A pointer to the mux-state, or an ERR_PTR with a negative errno.
+ * 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)
+static struct mux_state *mux_state_get(struct device *dev, const char *mux_name, bool optional)
 {
 	struct mux_state *mstate;
 
@@ -685,12 +727,16 @@ 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, optional);
 	if (IS_ERR(mstate->mux)) {
-		int err = PTR_ERR(mstate->mux);
-
 		kfree(mstate);
-		return ERR_PTR(err);
+		return ERR_CAST(mstate->mux);
+	} else if (optional && !mstate->mux) {
+		kfree(mstate);
+		return NULL;
+	} else if (!mstate->mux) {
+		kfree(mstate);
+		return ERR_PTR(-ENOENT);
 	}
 
 	return mstate;
@@ -710,9 +756,66 @@ static void mux_state_put(struct mux_state *mstate)
 
 static void devm_mux_state_release(struct device *dev, void *res)
 {
-	struct mux_state *mstate = *(struct mux_state **)res;
+	struct devm_mux_state_state *devm_state = res;
 
+	if (devm_state->exit)
+		devm_state->exit(devm_state->mstate);
+
+	mux_state_put(devm_state->mstate);
+}
+
+/**
+ * __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.
+ * @init: Optional function pointer for mux-state object initialisation.
+ * @exit: Optional function pointer for mux-state object cleanup on release.
+ *
+ * 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 *__devm_mux_state_get(struct device *dev, const char *mux_name,
+					      bool optional,
+					      int (*init)(struct mux_state *mstate),
+					      int (*exit)(struct mux_state *mstate))
+{
+	struct devm_mux_state_state *devm_state;
+	struct mux_state *mstate;
+	int ret;
+
+	mstate = mux_state_get(dev, mux_name, optional);
+	if (IS_ERR(mstate))
+		return ERR_CAST(mstate);
+	else if (optional && !mstate)
+		return NULL;
+	else if (!mstate)
+		return ERR_PTR(-ENOENT);
+
+	devm_state = devres_alloc(devm_mux_state_release, sizeof(*devm_state), GFP_KERNEL);
+	if (!devm_state) {
+		ret = -ENOMEM;
+		goto err_devres_alloc;
+	}
+
+	if (init) {
+		ret = init(mstate);
+		if (ret)
+			goto err_mux_state_init;
+	}
+
+	devm_state->mstate = mstate;
+	devm_state->exit = exit;
+	devres_add(dev, devm_state);
+
+	return mstate;
+
+err_mux_state_init:
+	devres_free(devm_state);
+err_devres_alloc:
 	mux_state_put(mstate);
+	return ERR_PTR(ret);
 }
 
 /**
@@ -722,28 +825,69 @@ static void devm_mux_state_release(struct device *dev, void *res)
  * @mux_name: The name identifying the mux-control.
  *
  * 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(struct device *dev, const char *mux_name)
 {
-	struct mux_state **ptr, *mstate;
-
-	ptr = devres_alloc(devm_mux_state_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return ERR_PTR(-ENOMEM);
+	return __devm_mux_state_get(dev, mux_name, false, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get);
 
-	mstate = mux_state_get(dev, mux_name);
-	if (IS_ERR(mstate)) {
-		devres_free(ptr);
-		return mstate;
-	}
+/**
+ * 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 on success, an ERR_PTR with a negative errno on error,
+ * or NULL if mux doesn't exist.
+ *
+ * The mux-state will automatically be freed on release.
+ */
+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);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_optional);
 
-	*ptr = mstate;
-	devres_add(dev, ptr);
+/**
+ * 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.
+ *
+ * The mux-state will automatically be deselected and freed on release.
+ */
+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);
+}
+EXPORT_SYMBOL_GPL(devm_mux_state_get_selected);
 
-	return mstate;
+/**
+ * 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 on success, an ERR_PTR with a negative errno on error,
+ * or NULL if mux doesn't exist.
+ *
+ * The returned mux-state (if valid) is already selected.
+ *
+ * The mux-state will automatically be deselected and freed on release.
+ */
+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);
 }
-EXPORT_SYMBOL_GPL(devm_mux_state_get);
+EXPORT_SYMBOL_GPL(devm_mux_state_get_optional_selected);
 
 /*
  * 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 2e25c838f831..a961861a503b 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;
 
+#if IS_ENABLED(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,109 @@ 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) {}
+
+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.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v9 3/7] mux: add help text for MULTIPLEXER config option
From: Josua Mayer @ 2026-02-08 15:38 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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

Select it by default when COMPILE_TEST is set for better coverage.

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

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index c68132e38138..4f7c6bb86fc6 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -4,7 +4,14 @@
 #
 
 config MULTIPLEXER
-	tristate
+	tristate "Generic Multiplexer Support"
+	default m if COMPILE_TEST
+	help
+	  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.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* [PATCH v9 0/7] mmc: host: renesas_sdhi_core: support configuring an optional sdio mux
From: Josua Mayer @ 2026-02-08 15:38 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, 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 v9:
- compile-tested on x86 with MULTIPLEXER=m/y/unset.
- fixed Kconfig changes so that CONFIG_MULTIPLEXER can be selected.
  through menuconfig / .config as intended.
- updated trailers
- document null return value for mux_control_get_optional.
- fix build error for CONFIG_MULTIPLEXER=m, found with x86_64
  allmodconfig: replaced ifdef ... with if IS_ENABLED(...).
  (Reported-by: Mark Brown <broonie@kernel.org>)
- Link to v8: https://lore.kernel.org/r/20260203-rz-sdio-mux-v8-0-024ea405863e@solid-run.com

Changes in v8:
- Add defensive null checks for all non-optional calls to internal
  mux_get function.
- Document NULL return value on applicable functions.
- Avoid IS_ERR_OR_NULL and ERR_PTR(0) to disarm smatch errors.
- Link to v7: https://lore.kernel.org/r/20260128-rz-sdio-mux-v7-0-92ebb6da0df8@solid-run.com

Changes in v7:
- picked up reviewed-tags
- fix Kconfig change to add the missing prompt for CONFIG_MULTIPLEXER,
  and enable it by default when COMPILE_TEST is set.
  (Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>)
- fix another kernel build robot warning: undocumented C struct member
- Link to v6: https://lore.kernel.org/r/20260121-rz-sdio-mux-v6-0-38aa39527928@solid-run.com

Changes in v6:
- replaced /* with /** for devm_mux_state_state function description.
- collected review tags.
- fixed checkpatch warnings (space-before-tab, void-return).
  (Reported-by: Geert Uytterhoeven)
- fixed use-after-free in mux core mux_get function.
  (Reported-by: Geert Uytterhoeven)
- fix mux helper error path uninitialised return code variable.
  (Reported-by: kernel test robot <lkp@intel.com>)
- Link to v5: https://lore.kernel.org/r/20260118-rz-sdio-mux-v5-0-3c37e8872683@solid-run.com

Changes in v5:
- implemented automatic mux deselect for devm_*_selected.
  (Reported-by: Wolfram Sang <wsa+renesas@sang-engineering.com>)
- because of semantic changes I dropped reviewed and acks from omap-i2c
  patch (Andreas Kemnade / Wolfram Sang).
- fix invalid return value in void function for mux helper stubs
  (Reported-by: kernel test robot <lkp@intel.com>)
- Link to v4: https://lore.kernel.org/r/20251229-rz-sdio-mux-v4-0-a023e55758fe@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                      |  24 +--
 drivers/mmc/host/renesas_sdhi_core.c               |   6 +
 drivers/mux/Kconfig                                |   9 +-
 drivers/mux/core.c                                 | 206 +++++++++++++++++----
 drivers/phy/phy-can-transceiver.c                  |  10 -
 include/linux/mux/consumer.h                       | 108 ++++++++++-
 7 files changed, 304 insertions(+), 65 deletions(-)
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20251128-rz-sdio-mux-acc5137f1618

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



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH v9 1/7] phy: can-transceiver: rename temporary helper function to avoid conflict
From: Josua Mayer @ 2026-02-08 15:38 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin, linux-can, linux-phy,
	linux-kernel, linux-omap, linux-i2c, linux-mmc, devicetree,
	linux-renesas-soc, Josua Mayer
In-Reply-To: <20260208-rz-sdio-mux-v9-0-9a3be13c1280@solid-run.com>

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>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
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 330356706ad7..81591d247128 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.43.0



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: [PATCH v8 3/7] mux: add help text for MULTIPLEXER config option
From: Josua Mayer @ 2026-02-08 15:16 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
	Peter Rosin, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
	Roger Quadros, Tony Lindgren, Janusz Krzysztofik, Vignesh R,
	Andi Shyti, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Geert Uytterhoeven, Magnus Damm, Wolfram Sang
  Cc: Yazan Shhady, Jon Nettleton, Mikhail Anikin,
	linux-can@vger.kernel.org, linux-phy@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-i2c@vger.kernel.org, linux-mmc@vger.kernel.org,
	devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org
In-Reply-To: <20260203-rz-sdio-mux-v8-3-024ea405863e@solid-run.com>

On 03/02/2026 15:01, Josua Mayer wrote:
> Add prompt and help text for CONFIG_MULTIPLEXER to allow enabling this
> option thorugh the kernel configuration without explicit "select" driver
> dependencies.
>
> Select it by default when COMPILE_TEST is set for better coverage.
>
> Signed-off-by: Josua Mayer <josua@solid-run.com>
> ---
>   drivers/mux/Kconfig | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
> index c68132e38138..e31c46820bdf 100644
> --- a/drivers/mux/Kconfig
> +++ b/drivers/mux/Kconfig
> @@ -4,7 +4,13 @@
>   #
>   
>   config MULTIPLEXER
> -	tristate
> +	tristate "Generic Multiplexer Support" if COMPILE_TEST

This didn't do what I thought it would.
It was my intention to allow enabling this through menuconfig / .config.

With the syntax above menuconfig shows:

│ Symbol: MULTIPLEXER [=n]
│ Type  : tristate
│ Defined at drivers/mux/Kconfig:6
│   Prompt: Generic Multiplexer Support
│   Visible if: COMPILE_TEST [=n]

This means it cannot be selected.

Instead I (think I) should use
default m if COMPILE_TEST

Since my patch-set broke x86_64 allmodconfig and failed merge into 
linux-next,
this presents an opportunity to change the above as well with v9.

> +	help
> +	  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
>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: Lynx 10G SerDes Driver on my kernel
From: Vladimir Oltean @ 2026-02-08 13:42 UTC (permalink / raw)
  To: Tanjeff Moos; +Cc: Sean Anderson, linux-phy@lists.infradead.org
In-Reply-To: <1e508f4e-d9a7-4e06-8308-e2d67099e927@westermo.com>

On Thu, Feb 05, 2026 at 05:47:12PM +0100, Tanjeff Moos wrote:
> Question: How is the lane supposed to be enabled?

By a phy_init() and phy_power_on() sequence.

In current mainline this is done by the fman_memac driver:
https://elixir.bootlin.com/linux/v6.18.6/source/drivers/net/ethernet/freescale/fman/fman_memac.c#L526-L545

In LF I've moved the phy_init()
https://github.com/nxp-qoriq/linux/blob/lf-6.12.y/drivers/net/pcs/pcs-lynx.c#L563
and phy_power_on()
https://github.com/nxp-qoriq/linux/blob/lf-6.12.y/drivers/net/pcs/pcs-lynx.c#L435
to the Lynx PCS driver to simplify MAC drivers a little bit, since they
all have to go through the same steps (the Lynx PCS is present in dpaa1,
dpaa2, enetc, felix switch).

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [PATCH phy-next] phy: apple: apple: Check the actual ioremap return value
From: Janne Grunau @ 2026-02-07 16:40 UTC (permalink / raw)
  To: Sven Peter, Neal Gompa, Vinod Koul, Neil Armstrong, Philipp Zabel
  Cc: asahi, linux-phy, linux-kernel, Dan Carpenter, Janne Grunau

The address where the devm_ioremap_resource() return value is stored is
always a valid pointer. Check the actual return value instead as that
that might be an error value.

Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/asahi/aYXvX1bYOXtYCgfC@stanley.mountain/
Fixes: 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY")
Signed-off-by: Janne Grunau <j@jannau.net>
---
 drivers/phy/apple/atc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c
index dc867f368b68748ea953e594ad998d7f965d8d1d..c144e273a555a741b49adfccbe046df83d193e03 100644
--- a/drivers/phy/apple/atc.c
+++ b/drivers/phy/apple/atc.c
@@ -2206,7 +2206,7 @@ static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcph
 	for (int i = 0; i < ARRAY_SIZE(resources); i++) {
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name);
 		*resources[i].addr = devm_ioremap_resource(&pdev->dev, res);
-		if (IS_ERR(resources[i].addr))
+		if (IS_ERR(*resources[i].addr))
 			return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr),
 					     "Unable to map %s regs", resources[i].name);
 

---
base-commit: dbeea86fecef7cf2b93aded4525d74f6277376ef
change-id: 20260207-phy-apple-resource-err-ptr-5923d1130465

Best regards,
-- 
Janne Grunau <j@jannau.net>


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: [PATCH 1/2] dt-bindings: phy: spacemit: add regulator support to K1 USB2 PHY
From: Krzysztof Kozlowski @ 2026-02-07 13:44 UTC (permalink / raw)
  To: Ze Huang, Chukun Pan
  Cc: Yixun Lan, Vinod Koul, Rob Herring, Mark Brown, Conor Dooley,
	Liam Girdwood, Krzysztof Kozlowski, Neil Armstrong, linux-riscv,
	linux-phy, linux-kernel, devicetree, spacemit
In-Reply-To: <DG8QBWSJ79MP.2MVIHFRBX3WXX@linux.dev>

On 07/02/2026 13:30, Ze Huang wrote:
> On Sat Feb 7, 2026 at 6:48 PM CST, Krzysztof Kozlowski wrote:
>> On Fri, Feb 06, 2026 at 06:00:08PM +0800, Chukun Pan wrote:
>>> Add an optional phy-supply property to describe the regulator
>>> supplying for USB VBUS.
>>
>> Why wasn't it there before? USB did not have VBUS?
> 
> Previously, the VBUS regulator was defined as regulator-always-on in
> the device tree as a workaround.

Bindings are supposed to be complete regardless what driver does (or
does not).

You must list all supplies with proper names.

If this regulator was missing, then what else?

> 
>>
>> Explanation is so incomplete I suspect you are patching broken things,
>> so as well this could be completely different hardware (e.g. there is no
>> regulator for this block but e.g. connector).
>>
> 
> usb ports under usb hub node can describe the topology well, but
> still regulator always-on is necessary as no driver toggles it.
> 
>     usb3 {
>      dr_mode = "host";
>      #address-cells = <1>;
>      #size-cells = <0>;
>      status = "okay";
> 
>      hub_2_0: hub@1 {
>       compatible = "usb2109,2817";
>       reg = <0x1>;
>       #address-cells = <1>;
>       #size-cells = <0>;
>       vdd-supply = <&usb3_vhub>;
>       peer-hub = <&hub_3_0>;
>       reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>;
> 
>       port@1 {
>        reg = <1>;
>        vbus-supply = <&usb3_vbus>;
>       };
> 
>       port@2 {
>        reg = <2>;
>        vbus-supply = <&usb3_vbus>;
>       };
> 
>       ...
> 
>       hub_3_0: hub@2 {
>         ...
>       };
>     };
> 
> Here is the diagram for the USB2, USB3 controller on K1 Jupiter board [1] (page 21)
> 
>     +-----------------------+
>     |        K1 SoC         |
>     |                       |
>     |  +-----------------+  |   (USB 3.0)
>     |  | USB3 Controller |--|---------------------------------->+--------------------------+
>     |  +-----------------+  |                                   |        VL817 Hub         |
>     |                       |                                   |                          |---> [USB3 Ports]
>     |      HUB_PWREN        |                                   | +----------------------+ |     ^
>     |       (GPIO)  --------|---------------------------------->| | Enable Chip Power    | |     |
>     |                       |                                   | +----------------------+ |     |
>     |                       |                                   +--------------------------+     |
>     |      USB3_PWREN       |                                                                    |
>     |       (GPIO)   -------|----------------------------------------------------------> [VBUS of USB3 Ports]
>     |                       |
>     |                       |
>     |~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     |                       |
>     |  +-----------------+  |   (USB 2.0)
>     |  | USB2 Controller |--|---------------------------------->+--------------------------+
>     |  +-----------------+  |                                   |      FE1_1S Hub          |---> [USB2 Ports]
>     |                       |                                   +--------------------------+     ^
>     |   USB_HOST_PWREN_H    |                                                                    |
>     |       (GPIO)      ----|-----------------------------------------------------------> [VBUS of USB2 Ports]
>     |                       |
>     |                       |
>     +-----------------------+


I do not see here a "phy" regulator supply. Are you sure this is how
your pin or supply is called?

> 
> [1] https://github.com/milkv-jupiter/jupiter-files/blob/main/hardware/v1_0/jupiter-sch-v1_0.pdf

This page shows the connector, so not the phy.

> 
>>
>>>
>>> Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
>>> ---
>>>  Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml | 4 ++++
>>>  1 file changed, 4 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>>> index 43eaca90d88c..74a1cd5bcdbe 100644
>>> --- a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>>> @@ -19,6 +19,10 @@ properties:
>>>    clocks:
>>>      maxItems: 1
>>>  
>>> +  phy-supply:
>>> +    description:
>>> +      Phandle to a regulator that provides power to VBUS.
>>
> 
> "vbus-supply" should be more accurate.
> 
>> Drop redundant part. This cannot be anything else than phandle and
>> regulator.
>>
>> "VBUS power supply" for example.
>>
> 
>> But anyway, I don't have certainty that
>> this is correct hardware representation. It's your task to provide that.
>>
>> Best regards,
>> Krzysztof
> 
> I initially considered handling VBUS via the onboard_usb_dev driver, as
> we discussed previously for the BananaPi-F3 board (which uses a VL817
> Hub) [2]. I was waiting for Marco Felsch's patch series "onboard-dev USB
> hub host managed vbus" to land [3].
> 
> [2] https://lore.kernel.org/linux-riscv/aWJAT3n_KcND8bOz@monica.localdomain/
> [3] https://lore.kernel.org/all/20250911-v6-16-topic-usb-onboard-dev-v4-0-1af288125d74@pengutronix.de/
> 
> I am not certain if managing VBUS in the PHY driver (e.g.,
> phy-stm32-usbphyc.c and phy-rockchip-usb.c) is the standard method.
> I would not insist on the "onboard_usb_dev managed vbus" if this patch
> (PHY managed) is considered proper way.

I am not talking about driver here at all.

Please start describing in the bindings your complete hardware, not your
drivers.

That's a no for this patch, because phy does not have such supply.

Best regards,
Krzysztof

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH v3 0/6] drm/sun4i: Support LVDS on D1s/T113 combo D-PHY
From: Parthiban @ 2026-02-07 13:34 UTC (permalink / raw)
  To: Kuba Szczodrzyński, Maxime Ripard, Samuel Holland,
	Chen-Yu Tsai, Jernej Skrabec, Maarten Lankhorst,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: parthiban, David Airlie, Simona Vetter, linux-arm-kernel,
	linux-sunxi, linux-kernel, linux-riscv, linux-phy, devicetree,
	dri-devel, paulk
In-Reply-To: <20251116134609.447043-1-kuba@szczodrzynski.pl>

On 11/16/25 2:46 PM, Kuba Szczodrzyński wrote:
> Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo
> MIPI DSI D-PHY" which is required when using single-link LVDS0. The same
> PD0..PD9 pins are used for either DSI or LVDS.
> 
> Other than having to use the combo D-PHY, LVDS output is configured in
> the same way as on older chips.
> 
> This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It
> is then configured by the LCD TCON, which allows connecting a
> single-link LVDS display panel.

Also one additional note is, current LVDS implementation in tcon doesn't
handle LVDS mode in "0x0084 LCD LVDS Configure". We have only bitwidth
handled. When using smaller LVDS panels vesa & jeida needs to be handled
separately. Not sure if the mode support bit is same across all the SoC's TCON,
but here is the diff which I have used to make it work for vesa-24 by tweaking
the a133 lvds hook.

commit 1f2d8983f78a11adab759160957a9cf6dc4296aa
Author: Parthiban Nallathambi <parthiban@linumiz.com>
Date:   Tue Feb 3 21:55:48 2026 +0530

    drm/sunxi: a133 add support for LVDS mode handling
    
    A133 supports both NS and JEIDA mode. Add support depends on the
    mode selected from the devicetree data mapping.
    
    Signed-off-by: Parthiban Nallathambi <parthiban@linumiz.com>

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 3bacc897217f..98a2fb7ed015 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -175,8 +175,34 @@ static void sun6i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
 static void sun20i_tcon_setup_lvds_dphy(struct sun4i_tcon *tcon,
                                        const struct drm_encoder *encoder)
 {
+       struct drm_connector *connector;
+       struct drm_display_info *info;
        union phy_configure_opts opts = { };
 
+       connector = sun4i_tcon_get_connector(encoder);
+       if (!connector)
+               return;
+
+       info = &connector->display_info;
+       if (info->num_bus_formats != 1)
+               return;
+
+       switch (info->bus_formats[0]) {
+       case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+       case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+       case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA:
+               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
+                                  SUN4I_TCON0_LVDS_IF_MODE,
+                                  SUN4I_TCON0_LVDS_IF_MODE);
+               break;
+       case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+       case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG:
+               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
+                                  SUN4I_TCON0_LVDS_IF_MODE,
+                                  0);
+               break;
+       }
+
        if (!tcon->quirks->has_combo_dphy || !tcon->dphy)
                return;
 
@@ -550,7 +576,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
        else
                reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS;
 
-       regmap_write(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, reg);
+       regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
+                          SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0 | SUN4I_TCON0_LVDS_IF_BITWIDTH_MASK,
+                          reg);
 
        /* Setup the polarity of the various signals */
        if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 7e6a5f500d37..fa45b070def2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -101,11 +101,12 @@
 
 #define SUN4I_TCON0_LVDS_IF_REG                        0x84
 #define SUN4I_TCON0_LVDS_IF_EN                         BIT(31)
+#define SUN4I_TCON0_LVDS_IF_MODE                       BIT(27)
 #define SUN4I_TCON0_LVDS_IF_BITWIDTH_MASK              BIT(26)
 #define SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS            (1 << 26)
 #define SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS            (0 << 26)
 #define SUN4I_TCON0_LVDS_IF_CLK_SEL_MASK               BIT(20)
-#define SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0              (1 << 20)
+#define SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0              BIT(20)
 #define SUN4I_TCON0_LVDS_IF_CLK_POL_MASK               BIT(4)
 #define SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL             (1 << 4)
 #define SUN4I_TCON0_LVDS_IF_CLK_POL_INV                        (0 << 4)

Shall this be same for all the TCON?

--
Thanks,
Parthiban
https://linumiz.com
https://www.linkedin.com/company/linumiz

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related

* Re: [PATCH 1/2] dt-bindings: phy: spacemit: add regulator support to K1 USB2 PHY
From: Ze Huang @ 2026-02-07 12:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Chukun Pan
  Cc: Yixun Lan, Vinod Koul, Ze Huang, Rob Herring, Mark Brown,
	Conor Dooley, Liam Girdwood, Krzysztof Kozlowski, Neil Armstrong,
	linux-riscv, linux-phy, linux-kernel, devicetree, spacemit
In-Reply-To: <20260207-dancing-finch-of-chemistry-f98cf2@quoll>

On Sat Feb 7, 2026 at 6:48 PM CST, Krzysztof Kozlowski wrote:
> On Fri, Feb 06, 2026 at 06:00:08PM +0800, Chukun Pan wrote:
>> Add an optional phy-supply property to describe the regulator
>> supplying for USB VBUS.
>
> Why wasn't it there before? USB did not have VBUS?

Previously, the VBUS regulator was defined as regulator-always-on in
the device tree as a workaround.

>
> Explanation is so incomplete I suspect you are patching broken things,
> so as well this could be completely different hardware (e.g. there is no
> regulator for this block but e.g. connector).
>

usb ports under usb hub node can describe the topology well, but
still regulator always-on is necessary as no driver toggles it.

    usb3 {
     dr_mode = "host";
     #address-cells = <1>;
     #size-cells = <0>;
     status = "okay";

     hub_2_0: hub@1 {
      compatible = "usb2109,2817";
      reg = <0x1>;
      #address-cells = <1>;
      #size-cells = <0>;
      vdd-supply = <&usb3_vhub>;
      peer-hub = <&hub_3_0>;
      reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>;

      port@1 {
       reg = <1>;
       vbus-supply = <&usb3_vbus>;
      };

      port@2 {
       reg = <2>;
       vbus-supply = <&usb3_vbus>;
      };

      ...

      hub_3_0: hub@2 {
        ...
      };
    };

Here is the diagram for the USB2, USB3 controller on K1 Jupiter board [1] (page 21)

    +-----------------------+
    |        K1 SoC         |
    |                       |
    |  +-----------------+  |   (USB 3.0)
    |  | USB3 Controller |--|---------------------------------->+--------------------------+
    |  +-----------------+  |                                   |        VL817 Hub         |
    |                       |                                   |                          |---> [USB3 Ports]
    |      HUB_PWREN        |                                   | +----------------------+ |     ^
    |       (GPIO)  --------|---------------------------------->| | Enable Chip Power    | |     |
    |                       |                                   | +----------------------+ |     |
    |                       |                                   +--------------------------+     |
    |      USB3_PWREN       |                                                                    |
    |       (GPIO)   -------|----------------------------------------------------------> [VBUS of USB3 Ports]
    |                       |
    |                       |
    |~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |                       |
    |  +-----------------+  |   (USB 2.0)
    |  | USB2 Controller |--|---------------------------------->+--------------------------+
    |  +-----------------+  |                                   |      FE1_1S Hub          |---> [USB2 Ports]
    |                       |                                   +--------------------------+     ^
    |   USB_HOST_PWREN_H    |                                                                    |
    |       (GPIO)      ----|-----------------------------------------------------------> [VBUS of USB2 Ports]
    |                       |
    |                       |
    +-----------------------+

[1] https://github.com/milkv-jupiter/jupiter-files/blob/main/hardware/v1_0/jupiter-sch-v1_0.pdf

>
>> 
>> Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
>> ---
>>  Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml | 4 ++++
>>  1 file changed, 4 insertions(+)
>> 
>> diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>> index 43eaca90d88c..74a1cd5bcdbe 100644
>> --- a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>> @@ -19,6 +19,10 @@ properties:
>>    clocks:
>>      maxItems: 1
>>  
>> +  phy-supply:
>> +    description:
>> +      Phandle to a regulator that provides power to VBUS.
>

"vbus-supply" should be more accurate.

> Drop redundant part. This cannot be anything else than phandle and
> regulator.
>
> "VBUS power supply" for example.
>

> But anyway, I don't have certainty that
> this is correct hardware representation. It's your task to provide that.
>
> Best regards,
> Krzysztof

I initially considered handling VBUS via the onboard_usb_dev driver, as
we discussed previously for the BananaPi-F3 board (which uses a VL817
Hub) [2]. I was waiting for Marco Felsch's patch series "onboard-dev USB
hub host managed vbus" to land [3].

[2] https://lore.kernel.org/linux-riscv/aWJAT3n_KcND8bOz@monica.localdomain/
[3] https://lore.kernel.org/all/20250911-v6-16-topic-usb-onboard-dev-v4-0-1af288125d74@pengutronix.de/

I am not certain if managing VBUS in the PHY driver (e.g.,
phy-stm32-usbphyc.c and phy-rockchip-usb.c) is the standard method.
I would not insist on the "onboard_usb_dev managed vbus" if this patch
(PHY managed) is considered proper way.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: phy: spacemit: add regulator support to K1 USB2 PHY
From: Yixun Lan @ 2026-02-07 11:55 UTC (permalink / raw)
  To: Chukun Pan
  Cc: Yixun Lan, Vinod Koul, Ze Huang, Rob Herring, Mark Brown,
	Conor Dooley, Liam Girdwood, Krzysztof Kozlowski, Neil Armstrong,
	linux-riscv, linux-phy, linux-kernel, devicetree, spacemit
In-Reply-To: <20260206100009.873182-1-amadeus@jmu.edu.cn>

Hi Chukun,

On 18:00 Fri 06 Feb     , Chukun Pan wrote:
> Add an optional phy-supply property to describe the regulator
> supplying for USB VBUS.
> 
No, the phy itself doesn't require regulator supply

We previously had a discussion about this, and I personally agree it 
should be handled at USB port level, see Ze's comment

https://lore.kernel.org/all/aWJAT3n_KcND8bOz@monica.localdomain/

> Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
> ---
>  Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
> index 43eaca90d88c..74a1cd5bcdbe 100644
> --- a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
> @@ -19,6 +19,10 @@ properties:
>    clocks:
>      maxItems: 1
>  
> +  phy-supply:
> +    description:
> +      Phandle to a regulator that provides power to VBUS.
> +
>    "#phy-cells":
>      const: 0
>  
> -- 
> 2.34.1
> 

-- 
Yixun Lan (dlan)

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: phy: spacemit: add regulator support to K1 USB2 PHY
From: Krzysztof Kozlowski @ 2026-02-07 10:49 UTC (permalink / raw)
  To: Chukun Pan
  Cc: Yixun Lan, Vinod Koul, Ze Huang, Rob Herring, Mark Brown,
	Conor Dooley, Liam Girdwood, Krzysztof Kozlowski, Neil Armstrong,
	linux-riscv, linux-phy, linux-kernel, devicetree, spacemit
In-Reply-To: <20260207-dancing-finch-of-chemistry-f98cf2@quoll>

On 07/02/2026 11:48, Krzysztof Kozlowski wrote:
> On Fri, Feb 06, 2026 at 06:00:08PM +0800, Chukun Pan wrote:
>> Add an optional phy-supply property to describe the regulator
>> supplying for USB VBUS.
> 
> Why wasn't it there before? USB did not have VBUS?
> 
> Explanation is so incomplete I suspect you are patching broken things,
> so as well this could be completely different hardware (e.g. there is no
> regulator for this block but e.g. connector).
> 
> 
>>
>> Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
>> ---
>>  Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>> index 43eaca90d88c..74a1cd5bcdbe 100644
>> --- a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
>> @@ -19,6 +19,10 @@ properties:
>>    clocks:
>>      maxItems: 1
>>  
>> +  phy-supply:
>> +    description:
>> +      Phandle to a regulator that provides power to VBUS.
> 
> Drop redundant part. This cannot be anything else than phandle and
> regulator.
> 
> "VBUS power supply" for example. But anyway, I don't have certainty that
> this is correct hardware representation. It's your task to provide that.


Plus, if this was a vbus regulator it would not be called "phy"... Even
more confusing.

Best regards,
Krzysztof

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: phy: spacemit: add regulator support to K1 USB2 PHY
From: Krzysztof Kozlowski @ 2026-02-07 10:48 UTC (permalink / raw)
  To: Chukun Pan
  Cc: Yixun Lan, Vinod Koul, Ze Huang, Rob Herring, Mark Brown,
	Conor Dooley, Liam Girdwood, Krzysztof Kozlowski, Neil Armstrong,
	linux-riscv, linux-phy, linux-kernel, devicetree, spacemit
In-Reply-To: <20260206100009.873182-1-amadeus@jmu.edu.cn>

On Fri, Feb 06, 2026 at 06:00:08PM +0800, Chukun Pan wrote:
> Add an optional phy-supply property to describe the regulator
> supplying for USB VBUS.

Why wasn't it there before? USB did not have VBUS?

Explanation is so incomplete I suspect you are patching broken things,
so as well this could be completely different hardware (e.g. there is no
regulator for this block but e.g. connector).


> 
> Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
> ---
>  Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
> index 43eaca90d88c..74a1cd5bcdbe 100644
> --- a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
> @@ -19,6 +19,10 @@ properties:
>    clocks:
>      maxItems: 1
>  
> +  phy-supply:
> +    description:
> +      Phandle to a regulator that provides power to VBUS.

Drop redundant part. This cannot be anything else than phandle and
regulator.

"VBUS power supply" for example. But anyway, I don't have certainty that
this is correct hardware representation. It's your task to provide that.

Best regards,
Krzysztof


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 1/3] phy: qcom: edp: Correct and clean up eDP/DP combo PHY configuration values
From: Dmitry Baryshkov @ 2026-02-07 10:22 UTC (permalink / raw)
  To: Yongxing Mou
  Cc: Vinod Koul, Neil Armstrong, linux-arm-msm, linux-phy,
	linux-kernel
In-Reply-To: <20260205-edp_phy-v1-1-231882bbf3f1@oss.qualcomm.com>

On Thu, Feb 05, 2026 at 05:20:53PM +0800, Yongxing Mou wrote:
> According to the current HPG settings, most eDP/DP combo PHYs can reuse the
> same configuration values.
> DP mode:
> 	-sa8775p/sc7280/sc8280xp/x1e80100
> 	-glymur
> eDP mode(low vdiff):
> 	-glymur/sa8775p/sc8280xp/x1e80100
> 	-sc7280
> The current driver still keeps multiple versions of these tables and
> doesn't fully support every combo PHY mode. This patch removes the

See Documentation/process/submitting-patches.rst, "This patch".

> redundant configs and keeps only the sets we actually use, matching the
> platforms listed above.

Should it be combined with the 3rd patch? There you sort out all the
tables, it makes more sense to review all programming together.

> 
> Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 41 +++++++++----------------------------
>  1 file changed, 10 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index 13feab99feec..10cbb7d9a8a0 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -116,17 +116,17 @@ struct qcom_edp {
>  };
>  
>  static const u8 dp_swing_hbr_rbr[4][4] = {
> -	{ 0x08, 0x0f, 0x16, 0x1f },
> +	{ 0x07, 0x0f, 0x16, 0x1f },
>  	{ 0x11, 0x1e, 0x1f, 0xff },
>  	{ 0x16, 0x1f, 0xff, 0xff },
>  	{ 0x1f, 0xff, 0xff, 0xff }
>  };
>  
>  static const u8 dp_pre_emp_hbr_rbr[4][4] = {
> -	{ 0x00, 0x0d, 0x14, 0x1a },
> +	{ 0x00, 0x0e, 0x15, 0x1a },
>  	{ 0x00, 0x0e, 0x15, 0xff },
>  	{ 0x00, 0x0e, 0xff, 0xff },
> -	{ 0x03, 0xff, 0xff, 0xff }
> +	{ 0x04, 0xff, 0xff, 0xff }
>  };
>  
>  static const u8 dp_swing_hbr2_hbr3[4][4] = {
> @@ -158,7 +158,7 @@ static const u8 edp_swing_hbr_rbr[4][4] = {
>  };
>  
>  static const u8 edp_pre_emp_hbr_rbr[4][4] = {
> -	{ 0x05, 0x12, 0x17, 0x1d },
> +	{ 0x05, 0x11, 0x17, 0x1d },
>  	{ 0x05, 0x11, 0x18, 0xff },
>  	{ 0x06, 0x11, 0xff, 0xff },
>  	{ 0x00, 0xff, 0xff, 0xff }
> @@ -172,10 +172,10 @@ static const u8 edp_swing_hbr2_hbr3[4][4] = {
>  };
>  
>  static const u8 edp_pre_emp_hbr2_hbr3[4][4] = {
> -	{ 0x08, 0x11, 0x17, 0x1b },
> -	{ 0x00, 0x0c, 0x13, 0xff },
> -	{ 0x05, 0x10, 0xff, 0xff },
> -	{ 0x00, 0xff, 0xff, 0xff }
> +	{ 0x0c, 0x15, 0x19, 0x1e },
> +	{ 0x0b, 0x15, 0x19, 0xff },
> +	{ 0x0e, 0x14, 0xff, 0xff },
> +	{ 0x0d, 0xff, 0xff, 0xff }
>  };
>  
>  static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
> @@ -193,27 +193,6 @@ static const u8 edp_phy_vco_div_cfg_v4[4] = {
>  	0x01, 0x01, 0x02, 0x00,
>  };
>  
> -static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
> -	{ 0x05, 0x11, 0x17, 0x1d },
> -	{ 0x05, 0x11, 0x18, 0xff },
> -	{ 0x06, 0x11, 0xff, 0xff },
> -	{ 0x00, 0xff, 0xff, 0xff }
> -};
> -
> -static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
> -	{ 0x0c, 0x15, 0x19, 0x1e },
> -	{ 0x0b, 0x15, 0x19, 0xff },
> -	{ 0x0e, 0x14, 0xff, 0xff },
> -	{ 0x0d, 0xff, 0xff, 0xff }
> -};
> -
> -static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
> -	.swing_hbr_rbr = &edp_swing_hbr_rbr,
> -	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
> -	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
> -	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
> -};
> -
>  static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = {
>  	0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
>  };
> @@ -564,7 +543,7 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
>  	.is_edp = false,
>  	.aux_cfg = edp_phy_aux_cfg_v5,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> -	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
> +	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
>  
> @@ -944,7 +923,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
>  static struct qcom_edp_phy_cfg glymur_phy_cfg = {
>  	.aux_cfg = edp_phy_aux_cfg_v8,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v8,
> -	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
> +	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v8,
>  };
>  
> 
> -- 
> 2.43.0
> 

-- 
With best wishes
Dmitry

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 3/3] phy: qcom: edp: Add eDP phy mode switch support
From: Dmitry Baryshkov @ 2026-02-07 10:20 UTC (permalink / raw)
  To: Yongxing Mou
  Cc: Vinod Koul, Neil Armstrong, linux-arm-msm, linux-phy,
	linux-kernel
In-Reply-To: <20260205-edp_phy-v1-3-231882bbf3f1@oss.qualcomm.com>

On Thu, Feb 05, 2026 at 05:20:55PM +0800, Yongxing Mou wrote:
> Add DP/eDP switch support by splitting the PHY swing/pre-emphasis tables
> into separate DP and eDP configurations. This allows the driver to select
> the correct table based on the is_edp flag.
> 
> Add a dedicated table for the SC7280/glymur platforms, as they are not
> compatible with the others.

Again, describe what is not working / broken now. Is it something that
we were supposedly supporting or not? Fixes, etc.

> 
> Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 72 ++++++++++++++++++++++++++++---------
>  1 file changed, 56 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index 388226dbad7f..85caa869a8c0 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -88,7 +88,8 @@ struct qcom_edp_phy_cfg {
>  	bool is_edp;
>  	const u8 *aux_cfg;
>  	const u8 *vco_div_cfg;
> -	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
> +	const struct qcom_edp_swing_pre_emph_cfg *dp_swing_pre_emph_cfg;
> +	const struct qcom_edp_swing_pre_emph_cfg *edp_swing_pre_emph_cfg;
>  	const struct phy_ver_ops *ver_ops;
>  };
>  
> @@ -151,6 +152,20 @@ static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg = {
>  	.pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3,
>  };
>  
> +static const u8 dp_pre_emp_hbr_rbr_v8[4][4] = {
> +	{ 0x00, 0x0e, 0x15, 0x1a },
> +	{ 0x00, 0x0e, 0x15, 0xff },
> +	{ 0x00, 0x0e, 0xff, 0xff },
> +	{ 0x00, 0xff, 0xff, 0xff }
> +};
> +
> +static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg_v8 = {
> +	.swing_hbr_rbr = &dp_swing_hbr_rbr,
> +	.swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3,
> +	.pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr_v8,
> +	.pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3,
> +};
> +
>  static const u8 edp_swing_hbr_rbr[4][4] = {
>  	{ 0x07, 0x0f, 0x16, 0x1f },
>  	{ 0x0d, 0x16, 0x1e, 0xff },
> @@ -186,6 +201,27 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
>  	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
>  };
>  
> +static const u8 edp_swing_hbr2_hbr3_v3[4][4] = {
> +	{ 0x0b, 0x11, 0x16, 0x1b },
> +	{ 0x0b, 0x19, 0x1f, 0xff },
> +	{ 0x18, 0x1f, 0xff, 0xff },
> +	{ 0x1f, 0xff, 0xff, 0xff }
> +};
> +
> +static const u8 edp_pre_emp_hbr2_hbr3_v3[4][4] = {
> +	{ 0x0c, 0x15, 0x19, 0x1e },
> +	{ 0x09, 0x14, 0x19, 0xff },
> +	{ 0x0f, 0x14, 0xff, 0xff },
> +	{ 0x0d, 0xff, 0xff, 0xff }
> +};
> +
> +static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v3 = {
> +	.swing_hbr_rbr = &edp_swing_hbr_rbr,
> +	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3_v3,
> +	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr,
> +	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v3,
> +};
> +
>  static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = {
>  	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
>  };
> @@ -242,12 +278,7 @@ static int qcom_edp_phy_init(struct phy *phy)
>  	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
>  	       edp->edp + DP_PHY_PD_CTL);
>  
> -	/*
> -	 * TODO: Re-work the conditions around setting the cfg8 value
> -	 * when more information becomes available about why this is
> -	 * even needed.
> -	 */
> -	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
> +	if (!edp->is_edp)
>  		aux_cfg[8] = 0xb7;
>  
>  	writel(0xfc, edp->edp + DP_PHY_MODE);
> @@ -271,7 +302,7 @@ static int qcom_edp_phy_init(struct phy *phy)
>  
>  static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
>  {
> -	const struct qcom_edp_swing_pre_emph_cfg *cfg = edp->cfg->swing_pre_emph_cfg;
> +	const struct qcom_edp_swing_pre_emph_cfg *cfg;
>  	unsigned int v_level = 0;
>  	unsigned int p_level = 0;
>  	int ret;
> @@ -279,12 +310,14 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
>  	u8 emph;
>  	int i;
>  
> +	if (edp->is_edp)
> +		cfg = edp->cfg->edp_swing_pre_emph_cfg;
> +	else
> +		cfg = edp->cfg->dp_swing_pre_emph_cfg;
> +
>  	if (!cfg)
>  		return 0;

Is it not redundant now?

>  
> -	if (edp->is_edp)
> -		cfg = &edp_phy_swing_pre_emph_cfg;
> -
>  	for (i = 0; i < dp_opts->lanes; i++) {
>  		v_level = max(v_level, dp_opts->voltage[i]);
>  		p_level = max(p_level, dp_opts->pre[i]);
> @@ -591,20 +624,24 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
>  	.is_edp = false,
>  	.aux_cfg = edp_phy_aux_cfg_v5,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> -	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
> +	.dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
>  
>  static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>  	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> +	.dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v3,
>  	.ver_ops = &qcom_edp_phy_ops_v3,
>  };
>  
>  static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
>  	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> -	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
>  
> @@ -612,7 +649,8 @@ static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
>  	.is_edp = true,
>  	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> -	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
> +	.dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v4,
>  };
>  
> @@ -811,7 +849,8 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
>  static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
>  	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> -	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
> +	.edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v6,
>  };
>  
> @@ -991,7 +1030,8 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
>  static struct qcom_edp_phy_cfg glymur_phy_cfg = {
>  	.aux_cfg = edp_phy_aux_cfg_v8,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v8,
> -	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
> +	.dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg_v8,
> +	.edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
>  	.ver_ops = &qcom_edp_phy_ops_v8,
>  };
>  
> 
> -- 
> 2.43.0
> 

-- 
With best wishes
Dmitry

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [PATCH 2/3] phy: qcom: edp: Add per-version LDO configuration callback
From: Dmitry Baryshkov @ 2026-02-07 10:17 UTC (permalink / raw)
  To: Yongxing Mou
  Cc: Vinod Koul, Neil Armstrong, linux-arm-msm, linux-phy,
	linux-kernel
In-Reply-To: <20260205-edp_phy-v1-2-231882bbf3f1@oss.qualcomm.com>

On Thu, Feb 05, 2026 at 05:20:54PM +0800, Yongxing Mou wrote:
> Introduce the com_ldo_config callback to support per‑PHY LDO
> configuration.

Missing the why part. Is the driver programming incorrect values, or is
it an optimisation? In the former case it needs Fixes, maybe cc:stable,
maybe Reported-by, etc.

> 
> Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-edp.c | 86 ++++++++++++++++++++++++++++++++-----
>  1 file changed, 76 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
> index 10cbb7d9a8a0..388226dbad7f 100644
> --- a/drivers/phy/qualcomm/phy-qcom-edp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-edp.c
> @@ -81,6 +81,7 @@ struct phy_ver_ops {
>  	int (*com_clk_fwd_cfg)(const struct qcom_edp *edp);
>  	int (*com_configure_pll)(const struct qcom_edp *edp);
>  	int (*com_configure_ssc)(const struct qcom_edp *edp);
> +	int (*com_ldo_config)(const struct qcom_edp *edp);
>  };
>  
>  struct qcom_edp_phy_cfg {
> @@ -273,7 +274,7 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
>  	const struct qcom_edp_swing_pre_emph_cfg *cfg = edp->cfg->swing_pre_emph_cfg;
>  	unsigned int v_level = 0;
>  	unsigned int p_level = 0;
> -	u8 ldo_config;
> +	int ret;
>  	u8 swing;
>  	u8 emph;
>  	int i;
> @@ -300,13 +301,13 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
>  	if (swing == 0xff || emph == 0xff)
>  		return -EINVAL;
>  
> -	ldo_config = edp->is_edp ? 0x0 : 0x1;
> +	ret = edp->cfg->ver_ops->com_ldo_config(edp);
> +	if (ret)
> +		return ret;
>  
> -	writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
>  	writel(swing, edp->tx0 + TXn_TX_DRV_LVL);
>  	writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL);
>  
> -	writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
>  	writel(swing, edp->tx1 + TXn_TX_DRV_LVL);
>  	writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL);
>  
> @@ -530,6 +531,52 @@ static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp)
>  	return 0;
>  }
>  
> +static int qcom_edp_ldo_config_v3(const struct qcom_edp *edp)
> +{
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +	u32 ldo_config;
> +
> +	if (!edp->is_edp)
> +		ldo_config = 0x0;
> +	else if (dp_opts->link_rate <= 2700)
> +		ldo_config = 0x81;
> +	else
> +		ldo_config = 0x41;
> +
> +	writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
> +	writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
> +
> +	return 0;
> +}
> +
> +static int qcom_edp_ldo_config_v4(const struct qcom_edp *edp)
> +{
> +	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
> +	u32 ldo_config;
> +
> +	if (!edp->is_edp)
> +		ldo_config = 0x0;
> +	else if (dp_opts->link_rate <= 2700)
> +		ldo_config = 0xC1;

Lowercase hex

> +	else
> +		ldo_config = 0x81;
> +
> +	writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
> +	writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ver_ops qcom_edp_phy_ops_v3 = {
> +	.com_power_on		= qcom_edp_phy_power_on_v4,
> +	.com_resetsm_cntrl	= qcom_edp_phy_com_resetsm_cntrl_v4,
> +	.com_bias_en_clkbuflr	= qcom_edp_com_bias_en_clkbuflr_v4,
> +	.com_clk_fwd_cfg	= qcom_edp_com_clk_fwd_cfg_v4,
> +	.com_configure_pll	= qcom_edp_com_configure_pll_v4,
> +	.com_configure_ssc	= qcom_edp_com_configure_ssc_v4,
> +	.com_ldo_config		= qcom_edp_ldo_config_v3,
> +};
> +
>  static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>  	.com_power_on		= qcom_edp_phy_power_on_v4,
>  	.com_resetsm_cntrl	= qcom_edp_phy_com_resetsm_cntrl_v4,
> @@ -537,6 +584,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
>  	.com_clk_fwd_cfg	= qcom_edp_com_clk_fwd_cfg_v4,
>  	.com_configure_pll	= qcom_edp_com_configure_pll_v4,
>  	.com_configure_ssc	= qcom_edp_com_configure_ssc_v4,
> +	.com_ldo_config		= qcom_edp_ldo_config_v4,
>  };
>  
>  static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
> @@ -550,7 +598,7 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
>  static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
>  	.aux_cfg = edp_phy_aux_cfg_v4,
>  	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
> -	.ver_ops = &qcom_edp_phy_ops_v4,
> +	.ver_ops = &qcom_edp_phy_ops_v3,

This looks like an extra change. Is it intentional in this patch? If so,
mention it in the commit message.

>  };
>  
>  static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {

-- 
With best wishes
Dmitry

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [bug report] phy: apple: Add Apple Type-C PHY
From: Sven Peter @ 2026-02-06 21:48 UTC (permalink / raw)
  To: Janne Grunau, Dan Carpenter
  Cc: Neal Gompa, Neil Armstrong, asahi, linux-arm-kernel, linux-phy,
	linux-kernel
In-Reply-To: <20260206214743.GA194367@robin.jannau.net>

On 06.02.26 22:47, Janne Grunau wrote:
> On Fri, Feb 06, 2026 at 04:40:47PM +0300, Dan Carpenter wrote:
>> [ Smatch checking is paused while we raise funding.  #SadFace
>>    https://lore.kernel.org/all/aTaiGSbWZ9DJaGo7@stanley.mountain/ -dan ]
> 
> This is unfortunate, there have been useful bug reports.
> 
>> Commit 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY") from Dec 14,
>> 2025 (linux-next), leads to the following Smatch static checker
>> warning:
>>
>> 	drivers/phy/apple/atc.c:2209 atcphy_map_resources()
>> 	warn: 'resources[i]->addr' isn't an ERR_PTR
>>
>> drivers/phy/apple/atc.c
>>      2191 static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy)
>>      2192 {
>>      2193         struct {
>>      2194                 const char *name;
>>      2195                 void __iomem **addr;
>>      2196                 struct resource **res;
>>      2197         } resources[] = {
>>      2198                 { "core", &atcphy->regs.core, &atcphy->res.core },
>>      2199                 { "lpdptx", &atcphy->regs.lpdptx, NULL },
>>      2200                 { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af },
>>      2201                 { "usb2phy", &atcphy->regs.usb2phy, NULL },
>>      2202                 { "pipehandler", &atcphy->regs.pipehandler, NULL },
>>      2203         };
>>      2204         struct resource *res;
>>      2205
>>      2206         for (int i = 0; i < ARRAY_SIZE(resources); i++) {
>>      2207                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name);
>>      2208                 *resources[i].addr = devm_ioremap_resource(&pdev->dev, res);
>> --> 2209                 if (IS_ERR(resources[i].addr))
>>
>> This is checking the wrong variable.  The * is missing.
>> if (IS_ERR(*resources[i].addr)) {
> 
> This issue was identified by testing and is fixed in next by commit
> 7d55b44e2be1 ("phy: apple: atc: Actually check return value of
> devm_apple_tunable_parse").
> 
> https://lore.kernel.org/all/20260104-atcphy-tunable-fix-v2-1-84e5c2a57aaa@kernel.org/

I think I actually messed this up *twice*! Once for the tunables and 
once again for the resources here :(


Sven



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* Re: [bug report] phy: apple: Add Apple Type-C PHY
From: Janne Grunau @ 2026-02-06 21:47 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Sven Peter, Neal Gompa, Neil Armstrong, asahi, linux-arm-kernel,
	linux-phy, linux-kernel
In-Reply-To: <aYXvX1bYOXtYCgfC@stanley.mountain>

On Fri, Feb 06, 2026 at 04:40:47PM +0300, Dan Carpenter wrote:
> [ Smatch checking is paused while we raise funding.  #SadFace
>   https://lore.kernel.org/all/aTaiGSbWZ9DJaGo7@stanley.mountain/ -dan ]

This is unfortunate, there have been useful bug reports.

> Commit 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY") from Dec 14,
> 2025 (linux-next), leads to the following Smatch static checker
> warning:
> 
> 	drivers/phy/apple/atc.c:2209 atcphy_map_resources()
> 	warn: 'resources[i]->addr' isn't an ERR_PTR
> 
> drivers/phy/apple/atc.c
>     2191 static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy)
>     2192 {
>     2193         struct {
>     2194                 const char *name;
>     2195                 void __iomem **addr;
>     2196                 struct resource **res;
>     2197         } resources[] = {
>     2198                 { "core", &atcphy->regs.core, &atcphy->res.core },
>     2199                 { "lpdptx", &atcphy->regs.lpdptx, NULL },
>     2200                 { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af },
>     2201                 { "usb2phy", &atcphy->regs.usb2phy, NULL },
>     2202                 { "pipehandler", &atcphy->regs.pipehandler, NULL },
>     2203         };
>     2204         struct resource *res;
>     2205 
>     2206         for (int i = 0; i < ARRAY_SIZE(resources); i++) {
>     2207                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name);
>     2208                 *resources[i].addr = devm_ioremap_resource(&pdev->dev, res);
> --> 2209                 if (IS_ERR(resources[i].addr))
> 
> This is checking the wrong variable.  The * is missing.
> if (IS_ERR(*resources[i].addr)) {

This issue was identified by testing and is fixed in next by commit
7d55b44e2be1 ("phy: apple: atc: Actually check return value of
devm_apple_tunable_parse").

https://lore.kernel.org/all/20260104-atcphy-tunable-fix-v2-1-84e5c2a57aaa@kernel.org/

Thanks for the report

Janne

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [bug report] phy: apple: Add Apple Type-C PHY
From: Dan Carpenter @ 2026-02-06 13:40 UTC (permalink / raw)
  To: Sven Peter
  Cc: Neal Gompa, Neil Armstrong, asahi, linux-arm-kernel, linux-phy,
	linux-kernel
In-Reply-To: <caa37f28-a2e8-4e0a-a9ce-a365ce805e4b@stanley.mountain>

[ Smatch checking is paused while we raise funding.  #SadFace
  https://lore.kernel.org/all/aTaiGSbWZ9DJaGo7@stanley.mountain/ -dan ]

Hello Sven Peter,

Commit 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY") from Dec 14,
2025 (linux-next), leads to the following Smatch static checker
warning:

	drivers/phy/apple/atc.c:2209 atcphy_map_resources()
	warn: 'resources[i]->addr' isn't an ERR_PTR

drivers/phy/apple/atc.c
    2191 static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy)
    2192 {
    2193         struct {
    2194                 const char *name;
    2195                 void __iomem **addr;
    2196                 struct resource **res;
    2197         } resources[] = {
    2198                 { "core", &atcphy->regs.core, &atcphy->res.core },
    2199                 { "lpdptx", &atcphy->regs.lpdptx, NULL },
    2200                 { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af },
    2201                 { "usb2phy", &atcphy->regs.usb2phy, NULL },
    2202                 { "pipehandler", &atcphy->regs.pipehandler, NULL },
    2203         };
    2204         struct resource *res;
    2205 
    2206         for (int i = 0; i < ARRAY_SIZE(resources); i++) {
    2207                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name);
    2208                 *resources[i].addr = devm_ioremap_resource(&pdev->dev, res);
--> 2209                 if (IS_ERR(resources[i].addr))

This is checking the wrong variable.  The * is missing.
if (IS_ERR(*resources[i].addr)) {

    2210                         return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr),
    2211                                              "Unable to map %s regs", resources[i].name);
    2212 
    2213                 if (resources[i].res)
    2214                         *resources[i].res = res;
    2215         }
    2216 
    2217         return 0;
    2218 }

regards,
dan carpenter

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply

* [bug report] phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY config and DP mode support
From: Dan Carpenter @ 2026-02-06 13:39 UTC (permalink / raw)
  To: Xiangxu Yin; +Cc: Neil Armstrong, linux-arm-msm, linux-phy, linux-kernel
In-Reply-To: <caa37f28-a2e8-4e0a-a9ce-a365ce805e4b@stanley.mountain>

[ Smatch checking is paused while we raise funding.  #SadFace
  https://lore.kernel.org/all/aTaiGSbWZ9DJaGo7@stanley.mountain/ -dan ]

Hello Xiangxu Yin,

Commit 81791c45c8e0 ("phy: qcom: qmp-usbc: Add QCS615 USB/DP PHY
config and DP mode support") from Dec 15, 2025 (linux-next), leads to
the following Smatch static checker warning:

	drivers/phy/qualcomm/phy-qcom-qmp-usbc.c:803 qmp_v2_configure_dp_swing()
	index hardmax out of bounds '(*cfg->swing_tbl)[v_level]' size=4 max='4' rl='0-4'

drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
    777 static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp)
    778 {
    779         const struct qmp_phy_cfg *cfg = qmp->cfg;
    780         const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
    781         void __iomem *tx = qmp->dp_tx;
    782         void __iomem *tx2 = qmp->dp_tx2;
    783         unsigned int v_level = 0, p_level = 0;
    784         u8 voltage_swing_cfg, pre_emphasis_cfg;
    785         int i;
    786 
    787         if (dp_opts->lanes > 4) {
    788                 dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes);
    789                 return -EINVAL;
    790         }
    791 
    792         for (i = 0; i < dp_opts->lanes; i++) {
    793                 v_level = max(v_level, dp_opts->voltage[i]);
    794                 p_level = max(p_level, dp_opts->pre[i]);
    795         }
    796 
    797         if (v_level > 4 || p_level > 4) {

These should be >= 4 instead of >.

    798                 dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n",
    799                         v_level, p_level);
    800                 return -EINVAL;
    801         }
    802 
--> 803         voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level];
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is a 4x4 array.

    804         pre_emphasis_cfg = (*cfg->pre_emphasis_tbl)[v_level][p_level];
    805 
    806         voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
    807         pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
    808 
    809         if (voltage_swing_cfg == 0xff && pre_emphasis_cfg == 0xff)
    810                 return -EINVAL;
    811 
    812         writel(voltage_swing_cfg, tx + QSERDES_V2_TX_TX_DRV_LVL);
    813         writel(pre_emphasis_cfg, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL);
    814         writel(voltage_swing_cfg, tx2 + QSERDES_V2_TX_TX_DRV_LVL);
    815         writel(pre_emphasis_cfg, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL);
    816 
    817         return 0;
    818 }

regards,
dan carpenter

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply


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