From ae35ff576764fb68b84fcac070e5d2b1ccb4966d Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sat, 8 Feb 2020 23:36:12 +0100 Subject: [PATCH] ath79: backport phy reset-controller patches The Siemens WS-AP3610 asserts reset to the ethernet PHY with the reset-register. Backport the necessary patches to de-assert reset when probing the PHY. These patches can be dropped when using kernel 5.4. Signed-off-by: David Bauer --- ...net-phy-add-reset-controller-support.patch | 107 ++++++++++++++++++ ...us-dont-use-managed-reset-controller.patch | 44 +++++++ 2 files changed, 151 insertions(+) create mode 100644 target/linux/ath79/patches-4.19/700-net-phy-add-reset-controller-support.patch create mode 100644 target/linux/ath79/patches-4.19/701-mdio-bus-dont-use-managed-reset-controller.patch diff --git a/target/linux/ath79/patches-4.19/700-net-phy-add-reset-controller-support.patch b/target/linux/ath79/patches-4.19/700-net-phy-add-reset-controller-support.patch new file mode 100644 index 0000000000..9f96390911 --- /dev/null +++ b/target/linux/ath79/patches-4.19/700-net-phy-add-reset-controller-support.patch @@ -0,0 +1,107 @@ +From 71dd6c0dff51b5f1fef2e9dfa6f6a948aac975f3 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Wed, 17 Apr 2019 23:59:21 +0200 +Subject: [PATCH] net: phy: add support for reset-controller + +This commit adds support for PHY reset pins handled by a reset controller. + +Signed-off-by: David Bauer +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/mdio_bus.c | 27 +++++++++++++++++++++++++-- + drivers/net/phy/mdio_device.c | 13 +++++++++++-- + include/linux/mdio.h | 1 + + 3 files changed, 37 insertions(+), 4 deletions(-) + +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -65,8 +66,23 @@ static int mdiobus_register_gpiod(struct + + mdiodev->reset = gpiod; + +- /* Assert the reset signal again */ +- mdio_device_reset(mdiodev, 1); ++ return 0; ++} ++ ++static int mdiobus_register_reset(struct mdio_device *mdiodev) ++{ ++ struct reset_control *reset = NULL; ++ ++ if (mdiodev->dev.of_node) ++ reset = devm_reset_control_get_exclusive(&mdiodev->dev, ++ "phy"); ++ if (PTR_ERR(reset) == -ENOENT || ++ PTR_ERR(reset) == -ENOTSUPP) ++ reset = NULL; ++ else if (IS_ERR(reset)) ++ return PTR_ERR(reset); ++ ++ mdiodev->reset_ctrl = reset; + + return 0; + } +@@ -82,6 +98,13 @@ int mdiobus_register_device(struct mdio_ + err = mdiobus_register_gpiod(mdiodev); + if (err) + return err; ++ ++ err = mdiobus_register_reset(mdiodev); ++ if (err) ++ return err; ++ ++ /* Assert the reset signal */ ++ mdio_device_reset(mdiodev, 1); + } + + mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev; +--- a/drivers/net/phy/mdio_device.c ++++ b/drivers/net/phy/mdio_device.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -121,10 +122,18 @@ void mdio_device_reset(struct mdio_devic + { + unsigned int d; + +- if (!mdiodev->reset) ++ if (!mdiodev->reset && !mdiodev->reset_ctrl) + return; + +- gpiod_set_value(mdiodev->reset, value); ++ if (mdiodev->reset) ++ gpiod_set_value(mdiodev->reset, value); ++ ++ if (mdiodev->reset_ctrl) { ++ if (value) ++ reset_control_assert(mdiodev->reset_ctrl); ++ else ++ reset_control_deassert(mdiodev->reset_ctrl); ++ } + + d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay; + if (d) +--- a/include/linux/mdio.h ++++ b/include/linux/mdio.h +@@ -40,6 +40,7 @@ struct mdio_device { + int addr; + int flags; + struct gpio_desc *reset; ++ struct reset_control *reset_ctrl; + unsigned int reset_assert_delay; + unsigned int reset_deassert_delay; + }; diff --git a/target/linux/ath79/patches-4.19/701-mdio-bus-dont-use-managed-reset-controller.patch b/target/linux/ath79/patches-4.19/701-mdio-bus-dont-use-managed-reset-controller.patch new file mode 100644 index 0000000000..16e7f20370 --- /dev/null +++ b/target/linux/ath79/patches-4.19/701-mdio-bus-dont-use-managed-reset-controller.patch @@ -0,0 +1,44 @@ +From 32085f25d7b68404055f3525c780142fc72e543f Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Fri, 22 Nov 2019 22:44:51 +0100 +Subject: [PATCH] mdio_bus: don't use managed reset-controller + +Geert Uytterhoeven reported that using devm_reset_controller_get leads +to a WARNING when probing a reset-controlled PHY. This is because the +device devm_reset_controller_get gets supplied is not actually the +one being probed. + +Acquire an unmanaged reset-control as well as free the reset_control on +unregister to fix this. + +Reported-by: Geert Uytterhoeven +CC: Andrew Lunn +Signed-off-by: David Bauer +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/mdio_bus.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -74,8 +74,8 @@ static int mdiobus_register_reset(struct + struct reset_control *reset = NULL; + + if (mdiodev->dev.of_node) +- reset = devm_reset_control_get_exclusive(&mdiodev->dev, +- "phy"); ++ reset = of_reset_control_get_exclusive(mdiodev->dev.of_node, ++ "phy"); + if (PTR_ERR(reset) == -ENOENT || + PTR_ERR(reset) == -ENOTSUPP) + reset = NULL; +@@ -118,6 +118,8 @@ int mdiobus_unregister_device(struct mdi + if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev) + return -EINVAL; + ++ reset_control_put(mdiodev->reset_ctrl); ++ + mdiodev->bus->mdio_map[mdiodev->addr] = NULL; + + return 0;