mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 08:51:46 -04:00
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: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -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,38 +111,53 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- microchip,ksz8863
|
||||
- microchip,ksz8873
|
||||
then:
|
||||
$ref: dsa.yaml#/$defs/ethernet-ports
|
||||
else:
|
||||
patternProperties:
|
||||
"^(ethernet-)?ports$":
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- microchip,ksz8863
|
||||
- microchip,ksz8873
|
||||
then:
|
||||
$ref: dsa.yaml#/$defs/ethernet-ports
|
||||
else:
|
||||
patternProperties:
|
||||
"^(ethernet-)?port@[0-2]$":
|
||||
$ref: dsa-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
microchip,rmii-clk-internal:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
When ksz88x3 is acting as clock provier (via REFCLKO) it
|
||||
can select between internal and external RMII reference
|
||||
clock. Internal reference clock means that the clock for
|
||||
the RMII of ksz88x3 is provided by the ksz88x3 internally
|
||||
and the REFCLKI pin is unconnected. For the external
|
||||
reference clock, the clock needs to be fed back to ksz88x3
|
||||
via REFCLKI.
|
||||
If microchip,rmii-clk-internal is set, ksz88x3 will provide
|
||||
rmii reference clock internally, otherwise reference clock
|
||||
should be provided externally.
|
||||
dependencies:
|
||||
microchip,rmii-clk-internal: [ethernet]
|
||||
"^(ethernet-)?ports$":
|
||||
patternProperties:
|
||||
"^(ethernet-)?port@[0-2]$":
|
||||
$ref: dsa-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
microchip,rmii-clk-internal:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
When ksz88x3 is acting as clock provier (via REFCLKO) it
|
||||
can select between internal and external RMII reference
|
||||
clock. Internal reference clock means that the clock for
|
||||
the RMII of ksz88x3 is provided by the ksz88x3 internally
|
||||
and the REFCLKI pin is unconnected. For the external
|
||||
reference clock, the clock needs to be fed back to ksz88x3
|
||||
via REFCLKI.
|
||||
If microchip,rmii-clk-internal is set, ksz88x3 will provide
|
||||
rmii reference clock internally, otherwise reference clock
|
||||
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
|
||||
|
||||
|
||||
@@ -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