[PATCH net-next v2 3/3] net: dsa: microchip: Set SPI as bus interface during reset for KSZ8463

Bastien Curutchet (Schneider Electric) posted 3 patches 2 weeks, 6 days ago
There is a newer version of this series
[PATCH net-next v2 3/3] net: dsa: microchip: Set SPI as bus interface during reset for KSZ8463
Posted by Bastien Curutchet 2 weeks, 6 days ago
At reset, the KSZ8463 uses a strap-based configuration to set SPI as
bus interface. SPI is the only bus supported by the driver. If the
required pull-ups/pull-downs are missing (by mistake or by design to
save power) the pins may float and the configuration can go wrong
preventing any communication with the switch.

Introduce a ksz8463_configure_straps_spi() function called during the
device reset. It relies on the 'strap-rxd*-gpios' OF properties and the
'reset' pinmux configuration to enforce SPI as bus interface.

Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
 drivers/net/dsa/microchip/ksz_common.c | 45 ++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 7292bfe2f7cac3a0d88bb51339cc287f56ca1d1f..ac05dd25b4863a61b15ac1131587b2b4df11ec41 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -23,6 +23,7 @@
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <linux/micrel_phy.h>
+#include <linux/pinctrl/consumer.h>
 #include <net/dsa.h>
 #include <net/ieee8021q.h>
 #include <net/pkt_cls.h>
@@ -5338,6 +5339,38 @@ static int ksz_parse_drive_strength(struct ksz_device *dev)
 	return 0;
 }
 
+static int ksz8463_configure_straps_spi(struct ksz_device *dev)
+{
+	struct pinctrl *pinctrl;
+	struct gpio_desc *rxd0;
+	struct gpio_desc *rxd1;
+
+	rxd0 = devm_gpiod_get_optional(dev->dev, "strap-rxd0", GPIOD_OUT_LOW);
+	if (IS_ERR(rxd0))
+		return PTR_ERR(rxd0);
+
+	rxd1 = devm_gpiod_get_optional(dev->dev, "strap-rxd1", GPIOD_OUT_HIGH);
+	if (IS_ERR(rxd1))
+		return PTR_ERR(rxd1);
+
+	if (!rxd0 && !rxd1)
+		return 0;
+
+	if ((rxd0 && !rxd1) || (rxd1 && !rxd0))
+		return -EINVAL;
+
+	pinctrl = devm_pinctrl_get_select(dev->dev, "reset");
+	if (IS_ERR(pinctrl))
+		return PTR_ERR(pinctrl);
+
+	return 0;
+}
+
+static int ksz8463_release_straps_spi(struct ksz_device *dev)
+{
+	return pinctrl_select_default_state(dev->dev);
+}
+
 int ksz_switch_register(struct ksz_device *dev)
 {
 	const struct ksz_chip_data *info;
@@ -5353,10 +5386,22 @@ int ksz_switch_register(struct ksz_device *dev)
 		return PTR_ERR(dev->reset_gpio);
 
 	if (dev->reset_gpio) {
+		if (of_device_is_compatible(dev->dev->of_node, "microchip,ksz8463")) {
+			ret = ksz8463_configure_straps_spi(dev);
+			if (ret)
+				return ret;
+		}
+
 		gpiod_set_value_cansleep(dev->reset_gpio, 1);
 		usleep_range(10000, 12000);
 		gpiod_set_value_cansleep(dev->reset_gpio, 0);
 		msleep(100);
+
+		if (of_device_is_compatible(dev->dev->of_node, "microchip,ksz8463")) {
+			ret = ksz8463_release_straps_spi(dev);
+			if (ret)
+				return ret;
+		}
 	}
 
 	mutex_init(&dev->dev_mutex);

-- 
2.51.0
Re: [PATCH net-next v2 3/3] net: dsa: microchip: Set SPI as bus interface during reset for KSZ8463
Posted by Andrew Lunn 2 weeks, 2 days ago
On Fri, Sep 12, 2025 at 11:09:14AM +0200, Bastien Curutchet wrote:
> At reset, the KSZ8463 uses a strap-based configuration to set SPI as
> bus interface. SPI is the only bus supported by the driver. If the
> required pull-ups/pull-downs are missing (by mistake or by design to
> save power) the pins may float and the configuration can go wrong
> preventing any communication with the switch.
> 
> Introduce a ksz8463_configure_straps_spi() function called during the
> device reset. It relies on the 'strap-rxd*-gpios' OF properties and the
> 'reset' pinmux configuration to enforce SPI as bus interface.
> 
> Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>

Thanks for updating the commit messages, it is now a lot clearer why
this is needed.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew