Commit ab528156 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-dsa-microchip-add-strap-description-to-set-spi-as-interface-bus'

Bastien Curutchet says:

====================
net: dsa: microchip: Add strap description to set SPI as interface bus

At reset, the KSZ8463 uses a strap-based configuration to set SPI as
interface bus. 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.

This small series aims to allow to configure the KSZ8463 switch at
reset when the hardware straps are missing.

PATCH 0 and 1 add a new property to the bindings that describes the GPIOs
to be set during reset in order to configure the switch properly.

PATCH 2 implements the use of these properties in the driver.
====================

Link: https://patch.msgid.link/20250918-ksz-strap-pins-v3-0-16662e881728@bootlin.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1bcce9ec a0b977a3
Loading
Loading
Loading
Loading
+53 −34
Original line number Diff line number Diff line
@@ -10,9 +10,6 @@ maintainers:
  - Marek Vasut <marex@denx.de>
  - Woojung Huh <Woojung.Huh@microchip.com>

allOf:
  - $ref: /schemas/spi/spi-peripheral-props.yaml#

properties:
  # See Documentation/devicetree/bindings/net/dsa/dsa.yaml for a list of additional
  # required and optional properties.
@@ -37,6 +34,13 @@ properties:
      - microchip,ksz8567
      - microchip,lan9646

  pinctrl-names:
    items:
      - const: default
      - const: reset
        description:
          Used during reset for strap configuration.

  reset-gpios:
    description:
      Should be a gpio specifier for a reset line.
@@ -107,7 +111,10 @@ required:
  - compatible
  - reg

if:
allOf:
  - $ref: /schemas/spi/spi-peripheral-props.yaml#

  - if:
      not:
        properties:
          compatible:
@@ -139,6 +146,18 @@ else:
                    should be provided externally.
              dependencies:
                microchip,rmii-clk-internal: [ethernet]
  - if:
      properties:
        compatible:
          contains:
            const: microchip,ksz8463
    then:
      properties:
        straps-rxd-gpios:
          description:
            RXD0 and RXD1 pins, used to select SPI as bus interface.
          minItems: 2
          maxItems: 2

unevaluatedProperties: false

+45 −0
Original line number Diff line number Diff line
@@ -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);