From dd1a98a375a64f050afaf55c2a80c7a78e957496 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 9 Jan 2023 13:30:10 +0100 Subject: [PATCH 1/4] dt-bindings: vendor-prefixes: add MaxLinear MaxLinear is a manufacturer of integrated circuits. https://www.maxlinear.com Signed-off-by: Michael Walle Acked-by: Krzysztof Kozlowski Signed-off-by: Paolo Abeni --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 70ffb3780621..161766b1de50 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -775,6 +775,8 @@ patternProperties: description: MaxBotix Inc. "^maxim,.*": description: Maxim Integrated Products + "^maxlinear,.*": + description: MaxLinear Inc. "^mbvl,.*": description: Mobiveil Inc. "^mcube,.*": From 90c47eb169ac5538c3376a1577cfe858c4efcf27 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 9 Jan 2023 13:30:11 +0100 Subject: [PATCH 2/4] dt-bindings: net: phy: add MaxLinear GPY2xx bindings Add the device tree bindings for the MaxLinear GPY2xx PHYs, which essentially adds just one flag: maxlinear,use-broken-interrupts. One might argue, that if interrupts are broken, just don't use the interrupt property in the first place. But it needs to be more nuanced. First, this interrupt line is also used to wake up systems by WoL, which has nothing to do with the (broken) PHY interrupt handling. Second and more importantly, there are devicetrees which have this property set. Thus, within the driver we have to switch off interrupt handling by default as a workaround. But OTOH, a systems designer who knows the hardware and knows there are no shared interrupts for example, can use this new property as a hint to the driver that it can enable the interrupt nonetheless. Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Signed-off-by: Paolo Abeni --- .../bindings/net/maxlinear,gpy2xx.yaml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/maxlinear,gpy2xx.yaml diff --git a/Documentation/devicetree/bindings/net/maxlinear,gpy2xx.yaml b/Documentation/devicetree/bindings/net/maxlinear,gpy2xx.yaml new file mode 100644 index 000000000000..d71fa9de2b64 --- /dev/null +++ b/Documentation/devicetree/bindings/net/maxlinear,gpy2xx.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/maxlinear,gpy2xx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MaxLinear GPY2xx PHY + +maintainers: + - Andrew Lunn + - Michael Walle + +allOf: + - $ref: ethernet-phy.yaml# + +properties: + maxlinear,use-broken-interrupts: + description: | + Interrupts are broken on some GPY2xx PHYs in that they keep the + interrupt line asserted even after the interrupt status register is + cleared. Thus it is blocking the interrupt line which is usually bad + for shared lines. By default interrupts are disabled for this PHY and + polling mode is used. If one can live with the consequences, this + property can be used to enable interrupt handling. + + Affected PHYs (as far as known) are GPY215B and GPY215C. + type: boolean + +dependencies: + maxlinear,use-broken-interrupts: [ interrupts ] + +unevaluatedProperties: false + +examples: + - | + ethernet { + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + reg = <0>; + interrupts-extended = <&intc 0>; + maxlinear,use-broken-interrupts; + }; + }; + +... From 7d885863e716757553197687f304da1f538f61e1 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 9 Jan 2023 13:30:12 +0100 Subject: [PATCH 3/4] net: phy: allow a phy to opt-out of interrupt handling Until now, it is not possible for a PHY driver to disable interrupts during runtime. If a driver offers the .config_intr() as well as the .handle_interrupt() ops, it is eligible for interrupt handling. Introduce a new flag for the dev_flags property of struct phy_device, which can be set by PHY driver to skip interrupt setup and fall back to polling mode. At the moment, this is used for the MaxLinear PHY which has broken interrupt handling and there is a need to disable interrupts in some cases. Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Signed-off-by: Paolo Abeni --- drivers/net/phy/phy_device.c | 7 +++++++ include/linux/phy.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 716870a4499c..e4562859ac00 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1487,6 +1487,13 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, phydev->interrupts = PHY_INTERRUPT_DISABLED; + /* PHYs can request to use poll mode even though they have an + * associated interrupt line. This could be the case if they + * detect a broken interrupt handling. + */ + if (phydev->dev_flags & PHY_F_NO_IRQ) + phydev->irq = PHY_POLL; + /* Port is set to PORT_TP by default and the actual PHY driver will set * it to different value depending on the PHY configuration. If we have * the generic PHY driver we can't figure it out, thus set the old diff --git a/include/linux/phy.h b/include/linux/phy.h index 6378c997ded5..742754d72fc0 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -739,6 +739,9 @@ struct phy_device { #endif }; +/* Generic phy_device::dev_flags */ +#define PHY_F_NO_IRQ 0x80000000 + static inline struct phy_device *to_phy_device(const struct device *dev) { return container_of(to_mdio_device(dev), struct phy_device, mdio); From 97a89ed101bbb790e80b562f9cb95f0cfd05f430 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 9 Jan 2023 13:30:13 +0100 Subject: [PATCH 4/4] net: phy: mxl-gpy: disable interrupts on GPY215 by default The interrupts on the GPY215B and GPY215C are broken and the only viable fix is to disable them altogether. There is still the possibilty to opt-in via the device tree. Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Signed-off-by: Paolo Abeni --- drivers/net/phy/mxl-gpy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c index 147d7a5a9b35..e5972b4ef6e8 100644 --- a/drivers/net/phy/mxl-gpy.c +++ b/drivers/net/phy/mxl-gpy.c @@ -12,6 +12,7 @@ #include #include #include +#include #include /* PHY ID */ @@ -292,6 +293,10 @@ static int gpy_probe(struct phy_device *phydev) phydev->priv = priv; mutex_init(&priv->mbox_lock); + if (gpy_has_broken_mdint(phydev) && + !device_property_present(dev, "maxlinear,use-broken-interrupts")) + phydev->dev_flags |= PHY_F_NO_IRQ; + fw_version = phy_read(phydev, PHY_FWV); if (fw_version < 0) return fw_version;