From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
To: netdev@vger.kernel.org
Cc: linus.walleij@linaro.org, alsi@bang-olufsen.dk, andrew@lunn.ch,
vivien.didelot@gmail.com, f.fainelli@gmail.com,
olteanv@gmail.com, davem@davemloft.net, kuba@kernel.org,
pabeni@redhat.com, robh+dt@kernel.org, krzk+dt@kernel.org,
arinc.unal@arinc9.com,
Luiz Angelo Daros de Luca <luizluca@gmail.com>
Subject: [PATCH net-next 1/2] net: dsa: realtek: support reset controller
Date: Tue, 24 Oct 2023 17:58:04 -0300 [thread overview]
Message-ID: <20231024205805.19314-1-luizluca@gmail.com> (raw)
The 'reset-gpios' will not work when the switch reset is controlled by a
reset controller.
Although the reset is optional and the driver performs a soft reset
during setup, if the initial reset state was asserted, the driver will
not detect it.
This is an example of how to use the reset controller:
switch {
compatible = "realtek,rtl8366rb";
resets = <&rst 8>;
reset-names = "switch";
...
}
The reset controller will take precedence over the reset GPIO.
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
drivers/net/dsa/realtek/realtek-mdio.c | 36 +++++++++++++++++++++-----
drivers/net/dsa/realtek/realtek-smi.c | 34 +++++++++++++++++++-----
drivers/net/dsa/realtek/realtek.h | 6 +++++
3 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index 292e6d087e8b..600124c58c00 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -140,6 +140,23 @@ static const struct regmap_config realtek_mdio_nolock_regmap_config = {
.disable_locking = true,
};
+static int realtek_mdio_hwreset(struct realtek_priv *priv, bool active)
+{
+#ifdef CONFIG_RESET_CONTROLLER
+ if (priv->reset_ctl) {
+ if (active)
+ return reset_control_assert(priv->reset_ctl);
+ else
+ return reset_control_deassert(priv->reset_ctl);
+ }
+#endif
+
+ if (priv->reset)
+ gpiod_set_value(priv->reset, active);
+
+ return 0;
+}
+
static int realtek_mdio_probe(struct mdio_device *mdiodev)
{
struct realtek_priv *priv;
@@ -194,20 +211,26 @@ static int realtek_mdio_probe(struct mdio_device *mdiodev)
dev_set_drvdata(dev, priv);
- /* TODO: if power is software controlled, set up any regulators here */
priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
+#ifdef CONFIG_RESET_CONTROLLER
+ priv->reset_ctl = devm_reset_control_get(dev, "switch");
+ if (IS_ERR(priv->reset_ctl)) {
+ dev_err(dev, "failed to get switch reset control\n");
+ return PTR_ERR(priv->reset_ctl);
+ }
+#endif
+
priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(priv->reset)) {
dev_err(dev, "failed to get RESET GPIO\n");
return PTR_ERR(priv->reset);
}
-
- if (priv->reset) {
- gpiod_set_value(priv->reset, 1);
+ if (priv->reset_ctl || priv->reset) {
+ realtek_mdio_hwreset(priv, 1);
dev_dbg(dev, "asserted RESET\n");
msleep(REALTEK_HW_STOP_DELAY);
- gpiod_set_value(priv->reset, 0);
+ realtek_mdio_hwreset(priv, 0);
msleep(REALTEK_HW_START_DELAY);
dev_dbg(dev, "deasserted RESET\n");
}
@@ -246,8 +269,7 @@ static void realtek_mdio_remove(struct mdio_device *mdiodev)
dsa_unregister_switch(priv->ds);
/* leave the device reset asserted */
- if (priv->reset)
- gpiod_set_value(priv->reset, 1);
+ realtek_mdio_hwreset(priv, 1);
}
static void realtek_mdio_shutdown(struct mdio_device *mdiodev)
diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
index bfd11591faf4..751159d71223 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -408,6 +408,23 @@ static int realtek_smi_setup_mdio(struct dsa_switch *ds)
return ret;
}
+static int realtek_smi_hwreset(struct realtek_priv *priv, bool active)
+{
+#ifdef CONFIG_RESET_CONTROLLER
+ if (priv->reset_ctl) {
+ if (active)
+ return reset_control_assert(priv->reset_ctl);
+ else
+ return reset_control_deassert(priv->reset_ctl);
+ }
+#endif
+
+ if (priv->reset)
+ gpiod_set_value(priv->reset, active);
+
+ return 0;
+}
+
static int realtek_smi_probe(struct platform_device *pdev)
{
const struct realtek_variant *var;
@@ -457,18 +474,24 @@ static int realtek_smi_probe(struct platform_device *pdev)
dev_set_drvdata(dev, priv);
spin_lock_init(&priv->lock);
- /* TODO: if power is software controlled, set up any regulators here */
+#ifdef CONFIG_RESET_CONTROLLER
+ priv->reset_ctl = devm_reset_control_get(dev, "switch");
+ if (IS_ERR(priv->reset_ctl)) {
+ dev_err(dev, "failed to get switch reset control\n");
+ return PTR_ERR(priv->reset_ctl);
+ }
+#endif
priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(priv->reset)) {
dev_err(dev, "failed to get RESET GPIO\n");
return PTR_ERR(priv->reset);
}
- if (priv->reset) {
- gpiod_set_value(priv->reset, 1);
+ if (priv->reset_ctl || priv->reset) {
+ realtek_smi_hwreset(priv, 1);
dev_dbg(dev, "asserted RESET\n");
msleep(REALTEK_HW_STOP_DELAY);
- gpiod_set_value(priv->reset, 0);
+ realtek_smi_hwreset(priv, 0);
msleep(REALTEK_HW_START_DELAY);
dev_dbg(dev, "deasserted RESET\n");
}
@@ -518,8 +541,7 @@ static void realtek_smi_remove(struct platform_device *pdev)
of_node_put(priv->slave_mii_bus->dev.of_node);
/* leave the device reset asserted */
- if (priv->reset)
- gpiod_set_value(priv->reset, 1);
+ realtek_smi_hwreset(priv, 1);
}
static void realtek_smi_shutdown(struct platform_device *pdev)
diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
index 4fa7c6ba874a..ad61e5c13f96 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -12,6 +12,9 @@
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <net/dsa.h>
+#ifdef CONFIG_RESET_CONTROLLER
+#include <linux/reset.h>
+#endif
#define REALTEK_HW_STOP_DELAY 25 /* msecs */
#define REALTEK_HW_START_DELAY 100 /* msecs */
@@ -48,6 +51,9 @@ struct rtl8366_vlan_4k {
struct realtek_priv {
struct device *dev;
+#ifdef CONFIG_RESET_CONTROLLER
+ struct reset_control *reset_ctl;
+#endif
struct gpio_desc *reset;
struct gpio_desc *mdc;
struct gpio_desc *mdio;
--
2.42.0
next reply other threads:[~2023-10-24 20:58 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-24 20:58 Luiz Angelo Daros de Luca [this message]
2023-10-24 20:58 ` [PATCH net-next 2/2] dt-bindings: net: dsa: realtek: add reset controller Luiz Angelo Daros de Luca
2023-10-24 22:39 ` Vladimir Oltean
2023-10-26 10:34 ` Arınç ÜNAL
2023-10-26 20:09 ` Luiz Angelo Daros de Luca
2023-10-26 20:58 ` Rob Herring
2023-10-26 22:03 ` Luiz Angelo Daros de Luca
2023-10-24 21:09 ` [PATCH net-next 1/2] net: dsa: realtek: support " Florian Fainelli
2023-10-24 22:02 ` Luiz Angelo Daros de Luca
2023-10-24 22:06 ` Florian Fainelli
2023-10-24 22:07 ` Vladimir Oltean
2023-10-24 22:17 ` Luiz Angelo Daros de Luca
2023-10-24 22:32 ` Andrew Lunn
2023-10-24 22:33 ` Vladimir Oltean
2023-10-25 18:30 ` Luiz Angelo Daros de Luca
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231024205805.19314-1-luizluca@gmail.com \
--to=luizluca@gmail.com \
--cc=alsi@bang-olufsen.dk \
--cc=andrew@lunn.ch \
--cc=arinc.unal@arinc9.com \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=robh+dt@kernel.org \
--cc=vivien.didelot@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.