summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@gmail.com>2019-06-25 10:41:51 +0200
committerDavid S. Miller <davem@davemloft.net>2019-06-27 11:17:30 -0700
commita653f2f538f9d3e2d1f1445f74a47bfdace85c2e (patch)
tree387aaedc3da7c46d8639f7d5a54d4186e1e7445f
parente7dd8a894830ca2d7b96d35dd5405993b0cfe32c (diff)
downloadlinux-stable-a653f2f538f9d3e2d1f1445f74a47bfdace85c2e.tar.gz
linux-stable-a653f2f538f9d3e2d1f1445f74a47bfdace85c2e.tar.bz2
linux-stable-a653f2f538f9d3e2d1f1445f74a47bfdace85c2e.zip
net: dsa: qca8k: introduce reset via gpio feature
The QCA8337(N) has a RESETn signal on Pin B42 that triggers a chip reset if the line is pulled low. The datasheet says that: "The active low duration must be greater than 10 ms". This can hopefully fix some of the issues related to pin strapping in OpenWrt for the EA8500 which suffers from detection issues after a SoC reset. Please note that the qca8k_probe() function does currently require to read the chip's revision register for identification purposes. Signed-off-by: Christian Lamparter <chunkeey@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/qca8k.c15
-rw-r--r--drivers/net/dsa/qca8k.h2
2 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index c4fa400efdcc..27709f866c23 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
#include <linux/of_platform.h>
#include <linux/if_bridge.h>
#include <linux/mdio.h>
+#include <linux/gpio.h>
#include <linux/etherdevice.h>
#include "qca8k.h"
@@ -1046,6 +1047,20 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
priv->bus = mdiodev->bus;
priv->dev = &mdiodev->dev;
+ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
+ GPIOD_ASIS);
+ if (IS_ERR(priv->reset_gpio))
+ return PTR_ERR(priv->reset_gpio);
+
+ if (priv->reset_gpio) {
+ gpiod_set_value_cansleep(priv->reset_gpio, 1);
+ /* The active low duration must be greater than 10 ms
+ * and checkpatch.pl wants 20 ms.
+ */
+ msleep(20);
+ gpiod_set_value_cansleep(priv->reset_gpio, 0);
+ }
+
/* read the switches ID register */
id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
id >>= QCA8K_MASK_CTRL_ID_S;
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 91557433ce2f..42d6ea24eb14 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/regmap.h>
+#include <linux/gpio.h>
#define QCA8K_NUM_PORTS 7
@@ -174,6 +175,7 @@ struct qca8k_priv {
struct mutex reg_mutex;
struct device *dev;
struct dsa_switch_ops ops;
+ struct gpio_desc *reset_gpio;
};
struct qca8k_mib_desc {