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 v2 3/3] net: dsa: realtek: support reset controller
Date: Fri, 27 Oct 2023 16:00:57 -0300 [thread overview]
Message-ID: <20231027190910.27044-4-luizluca@gmail.com> (raw)
In-Reply-To: <20231027190910.27044-1-luizluca@gmail.com>
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.
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 | 51 ++++++++++++++++++++++----
drivers/net/dsa/realtek/realtek-smi.c | 49 ++++++++++++++++++++++---
drivers/net/dsa/realtek/realtek.h | 2 +
3 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index 292e6d087e8b..aad94e49d4c9 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -140,6 +140,40 @@ static const struct regmap_config realtek_mdio_nolock_regmap_config = {
.disable_locking = true,
};
+static void realtek_mdio_reset_assert(struct realtek_priv *priv)
+{
+ int ret;
+
+ if (priv->reset_ctl) {
+ ret = reset_control_assert(priv->reset_ctl);
+ if (ret)
+ dev_warn(priv->dev, "Failed to assert the switch reset control. Error: %i",
+ ret);
+
+ return;
+ }
+
+ if (priv->reset)
+ gpiod_set_value(priv->reset, true);
+}
+
+static void realtek_mdio_reset_deassert(struct realtek_priv *priv)
+{
+ int ret;
+
+ if (priv->reset_ctl) {
+ ret = reset_control_deassert(priv->reset_ctl);
+ if (ret)
+ dev_warn(priv->dev, "Failed to deassert the switch reset control. Error: %i",
+ ret);
+
+ return;
+ }
+
+ if (priv->reset)
+ gpiod_set_value(priv->reset, false);
+}
+
static int realtek_mdio_probe(struct mdio_device *mdiodev)
{
struct realtek_priv *priv;
@@ -194,20 +228,24 @@ 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");
+ priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
+ if (IS_ERR(priv->reset_ctl)) {
+ ret = PTR_ERR(priv->reset_ctl);
+ return dev_err_probe(dev, ret, "failed to get reset control\n");
+ }
+
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_reset_assert(priv);
dev_dbg(dev, "asserted RESET\n");
msleep(REALTEK_HW_STOP_DELAY);
- gpiod_set_value(priv->reset, 0);
+ realtek_mdio_reset_deassert(priv);
msleep(REALTEK_HW_START_DELAY);
dev_dbg(dev, "deasserted RESET\n");
}
@@ -246,8 +284,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_reset_assert(priv);
}
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..a99e53b5b662 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -408,6 +408,40 @@ static int realtek_smi_setup_mdio(struct dsa_switch *ds)
return ret;
}
+static void realtek_smi_reset_assert(struct realtek_priv *priv)
+{
+ int ret;
+
+ if (priv->reset_ctl) {
+ ret = reset_control_assert(priv->reset_ctl);
+ if (ret)
+ dev_warn(priv->dev, "Failed to assert the switch reset control. Error: %i",
+ ret);
+
+ return;
+ }
+
+ if (priv->reset)
+ gpiod_set_value(priv->reset, true);
+}
+
+static void realtek_smi_reset_deassert(struct realtek_priv *priv)
+{
+ int ret;
+
+ if (priv->reset_ctl) {
+ ret = reset_control_deassert(priv->reset_ctl);
+ if (ret)
+ dev_warn(priv->dev, "Failed to deassert the switch reset control. Error: %i",
+ ret);
+
+ return;
+ }
+
+ if (priv->reset)
+ gpiod_set_value(priv->reset, false);
+}
+
static int realtek_smi_probe(struct platform_device *pdev)
{
const struct realtek_variant *var;
@@ -457,18 +491,22 @@ 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 */
+ priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
+ if (IS_ERR(priv->reset_ctl)) {
+ ret = PTR_ERR(priv->reset_ctl);
+ return dev_err_probe(dev, ret, "failed to get reset control\n");
+ }
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_reset_assert(priv);
dev_dbg(dev, "asserted RESET\n");
msleep(REALTEK_HW_STOP_DELAY);
- gpiod_set_value(priv->reset, 0);
+ realtek_smi_reset_deassert(priv);
msleep(REALTEK_HW_START_DELAY);
dev_dbg(dev, "deasserted RESET\n");
}
@@ -518,8 +556,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_reset_assert(priv);
}
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..516450837b74 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <net/dsa.h>
+#include <linux/reset.h>
#define REALTEK_HW_STOP_DELAY 25 /* msecs */
#define REALTEK_HW_START_DELAY 100 /* msecs */
@@ -48,6 +49,7 @@ struct rtl8366_vlan_4k {
struct realtek_priv {
struct device *dev;
+ struct reset_control *reset_ctl;
struct gpio_desc *reset;
struct gpio_desc *mdc;
struct gpio_desc *mdio;
--
2.42.0
next prev parent reply other threads:[~2023-10-27 19:10 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-27 19:00 [PATCH net-next v2 0/3] net: dsa: realtek: support reset controller Luiz Angelo Daros de Luca
2023-10-27 19:00 ` [PATCH net-next v2 1/3] dt-bindings: net: dsa: realtek: reset-gpios is not required Luiz Angelo Daros de Luca
2023-10-28 7:49 ` Arınç ÜNAL
2023-10-30 17:40 ` Rob Herring
2023-10-27 19:00 ` [PATCH net-next v2 2/3] dt-bindings: net: dsa: realtek: add reset controller Luiz Angelo Daros de Luca
2023-10-28 7:50 ` Arınç ÜNAL
2023-10-30 13:15 ` Rob Herring
2023-10-30 22:30 ` Luiz Angelo Daros de Luca
2023-10-27 19:00 ` Luiz Angelo Daros de Luca [this message]
2023-10-27 20:20 ` [PATCH net-next v2 3/3] net: dsa: realtek: support " Andrew Lunn
2023-10-30 20:50 ` Vladimir Oltean
2023-10-31 0:30 ` Luiz Angelo Daros de Luca
2023-11-01 19:55 ` Luiz Angelo Daros de Luca
2023-11-02 14:04 ` Vladimir Oltean
2023-11-02 14:59 ` Linus Walleij
2023-11-02 15:55 ` Vladimir Oltean
2023-11-02 15:57 ` Vladimir Oltean
2023-11-02 16:21 ` Vladimir Oltean
2023-11-03 17:37 ` Linus Walleij
2023-11-06 22:37 ` Luiz Angelo Daros de Luca
2023-11-07 8:03 ` Linus Walleij
2023-11-07 13:54 ` Luiz Angelo Daros de Luca
2023-11-02 14:13 ` Vladimir Oltean
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=20231027190910.27044-4-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.