aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2016-11-30 11:55:39 +0100
committerFelix Fietkau <nbd@nbd.name>2016-12-04 11:41:50 +0100
commit106a4605c87c91dd71b09b2814e232ebac6873ed (patch)
tree4d502434af1bb58041f8662004b29195fb688e82
parentfeb25f1a5bb46b5b82dee078d3039d3f488ae767 (diff)
downloadupstream-106a4605c87c91dd71b09b2814e232ebac6873ed.tar.gz
upstream-106a4605c87c91dd71b09b2814e232ebac6873ed.tar.bz2
upstream-106a4605c87c91dd71b09b2814e232ebac6873ed.zip
ar71xx: add support for configuring at803x PHY GPIO reset via platform data
Needed to work around ethernet hang issues on Ubiquiti NanoStation Loco XW, because ar71xx is not converted to device tree yet. Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--target/linux/ar71xx/patches-4.4/902-at803x-add-reset-gpio-pdata.patch68
1 files changed, 68 insertions, 0 deletions
diff --git a/target/linux/ar71xx/patches-4.4/902-at803x-add-reset-gpio-pdata.patch b/target/linux/ar71xx/patches-4.4/902-at803x-add-reset-gpio-pdata.patch
new file mode 100644
index 0000000000..2244f882e7
--- /dev/null
+++ b/target/linux/ar71xx/patches-4.4/902-at803x-add-reset-gpio-pdata.patch
@@ -0,0 +1,68 @@
+Add support for configuring AT803x GPIO reset via platform data.
+This is necessary, because ath79 is not converted to device tree yet.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+--- a/include/linux/platform_data/phy-at803x.h
++++ b/include/linux/platform_data/phy-at803x.h
+@@ -6,6 +6,8 @@ struct at803x_platform_data {
+ int enable_rgmii_tx_delay:1;
+ int enable_rgmii_rx_delay:1;
+ int fixup_rgmii_tx_delay:1;
++ int has_reset_gpio:1;
++ int reset_gpio;
+ };
+
+ #endif /* _PHY_AT803X_PDATA_H */
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -243,6 +243,7 @@ static int at803x_resume(struct phy_devi
+
+ static int at803x_probe(struct phy_device *phydev)
+ {
++ struct at803x_platform_data *pdata;
+ struct device *dev = &phydev->dev;
+ struct at803x_priv *priv;
+ struct gpio_desc *gpiod_reset;
+@@ -255,6 +256,12 @@ static int at803x_probe(struct phy_devic
+ phydev->drv->phy_id != ATH8032_PHY_ID)
+ goto does_not_require_reset_workaround;
+
++ pdata = dev_get_platdata(&phydev->dev);
++ if (pdata && pdata->has_reset_gpio) {
++ devm_gpio_request(dev, pdata->reset_gpio, "reset");
++ gpio_direction_output(pdata->reset_gpio, 1);
++ }
++
+ gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(gpiod_reset))
+ return PTR_ERR(gpiod_reset);
+@@ -377,15 +384,23 @@ static void at803x_link_change_notify(st
+ * cannot recover from by software.
+ */
+ if (phydev->state == PHY_NOLINK) {
+- if (priv->gpiod_reset && !priv->phy_reset) {
++ if ((priv->gpiod_reset || pdata->has_reset_gpio) &&
++ !priv->phy_reset) {
+ struct at803x_context context;
+
+ at803x_context_save(phydev, &context);
+
+- gpiod_set_value(priv->gpiod_reset, 1);
+- msleep(1);
+- gpiod_set_value(priv->gpiod_reset, 0);
+- msleep(1);
++ if (pdata->has_reset_gpio) {
++ gpio_set_value_cansleep(pdata->reset_gpio, 0);
++ msleep(1);
++ gpio_set_value_cansleep(pdata->reset_gpio, 1);
++ msleep(1);
++ } else {
++ gpiod_set_value(priv->gpiod_reset, 1);
++ msleep(1);
++ gpiod_set_value(priv->gpiod_reset, 0);
++ msleep(1);
++ }
+
+ at803x_context_restore(phydev, &context);
+