net: dsa: microchip: Set SPI as bus interface during reset for KSZ8463
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 'straps-rxd-gpios' OF property and the 'reset' pinmux configuration to enforce SPI as bus interface. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com> Link: https://patch.msgid.link/20250918-ksz-strap-pins-v3-3-16662e881728@bootlin.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
e469b87e0f
commit
a0b977a3d1
@@ -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>
|
||||
@@ -5345,6 +5346,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_index_optional(dev->dev, "straps-rxd", 0, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(rxd0))
|
||||
return PTR_ERR(rxd0);
|
||||
|
||||
rxd1 = devm_gpiod_get_index_optional(dev->dev, "straps-rxd", 1, 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;
|
||||
@@ -5360,10 +5393,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);
|
||||
|
||||
Reference in New Issue
Block a user