From: Daniel Golle <daniel@makrotopia.org>
To: Andrew Lunn <andrew@lunn.ch>, Vladimir Oltean <olteanv@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Hauke Mehrtens <hauke@hauke-m.de>,
Simon Horman <horms@kernel.org>,
Russell King <linux@armlinux.org.uk>,
Florian Fainelli <f.fainelli@gmail.com>,
Arkadi Sharshevsky <arkadis@mellanox.com>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Cc: Andreas Schirm <andreas.schirm@siemens.com>,
Lukas Stockmann <lukas.stockmann@siemens.com>,
Alexander Sverdlin <alexander.sverdlin@siemens.com>,
Peter Christen <peter.christen@siemens.com>,
Avinash Jayaraman <ajayaraman@maxlinear.com>,
Bing tao Xu <bxu@maxlinear.com>, Liang Xu <lxu@maxlinear.com>,
Juraj Povazanec <jpovazanec@maxlinear.com>,
"Fanni (Fang-Yi) Chan" <fchan@maxlinear.com>,
"Benny (Ying-Tsan) Weng" <yweng@maxlinear.com>,
"Livia M. Rosu" <lrosu@maxlinear.com>,
John Crispin <john@phrozen.org>
Subject: [PATCH RFC net-next 18/23] net: dsa: lantiq_gswip: convert to use regmap
Date: Sat, 16 Aug 2025 20:56:01 +0100 [thread overview]
Message-ID: <aKDiUb084FhsmsTv@pidgin.makrotopia.org> (raw)
Use regmap for register access in preparation for supporting the MaxLinear
GSW1xx family of switches connected via MDIO or SPI.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/dsa/Kconfig | 1 +
drivers/net/dsa/lantiq_gswip.c | 157 +++++++++++++++++++++++----------
drivers/net/dsa/lantiq_gswip.h | 6 +-
3 files changed, 114 insertions(+), 50 deletions(-)
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index ec759f8cb0e2..26e54958e61e 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -30,6 +30,7 @@ config NET_DSA_LANTIQ_GSWIP
tristate "Lantiq / Intel GSWIP"
depends on HAS_IOMEM
select NET_DSA_TAG_GSWIP
+ select REGMAP
help
This enables support for the Lantiq / Intel GSWIP 2.1 found in
the xrx200 / VR9 SoC.
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 6a263a0387d1..2d91f5c79439 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -115,22 +115,41 @@ static const struct gswip_rmon_cnt_desc gswip_rmon_cnt[] = {
static u32 gswip_switch_r(struct gswip_priv *priv, u32 offset)
{
- return __raw_readl(priv->gswip + (offset * 4));
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(priv->gswip, offset, &val);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to read switch register\n");
+ return 0;
+ }
+
+ return val;
}
static void gswip_switch_w(struct gswip_priv *priv, u32 val, u32 offset)
{
- __raw_writel(val, priv->gswip + (offset * 4));
+ int ret;
+
+ ret = regmap_write(priv->gswip, offset, val);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to write switch register\n");
+ }
}
static void gswip_switch_mask(struct gswip_priv *priv, u32 clear, u32 set,
u32 offset)
{
- u32 val = gswip_switch_r(priv, offset);
+ int ret;
- val &= ~(clear);
- val |= set;
- gswip_switch_w(priv, val, offset);
+ ret = regmap_update_bits_base(priv->gswip, offset, clear | set, set,
+ NULL, false, true);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to update switch register\n");
+ }
}
static u32 gswip_switch_r_timeout(struct gswip_priv *priv, u32 offset,
@@ -138,48 +157,60 @@ static u32 gswip_switch_r_timeout(struct gswip_priv *priv, u32 offset,
{
u32 val;
- return readx_poll_timeout(__raw_readl, priv->gswip + (offset * 4), val,
- (val & cleared) == 0, 20, 50000);
+ return regmap_read_poll_timeout(priv->gswip, offset, val,
+ !(val & cleared), 20, 50000);
}
static u32 gswip_mdio_r(struct gswip_priv *priv, u32 offset)
{
- return __raw_readl(priv->mdio + (offset * 4));
+ u32 val;
+ int ret;
+
+ ret = regmap_read(priv->mdio, offset, &val);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to read mdio register\n");
+ return 0;
+ }
+
+ return val;
}
static void gswip_mdio_w(struct gswip_priv *priv, u32 val, u32 offset)
{
- __raw_writel(val, priv->mdio + (offset * 4));
+ int ret;
+
+ ret = regmap_write(priv->mdio, offset, val);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to write mdio register\n");
+ }
}
static void gswip_mdio_mask(struct gswip_priv *priv, u32 clear, u32 set,
u32 offset)
{
- u32 val = gswip_mdio_r(priv, offset);
-
- val &= ~(clear);
- val |= set;
- gswip_mdio_w(priv, val, offset);
-}
-
-static u32 gswip_mii_r(struct gswip_priv *priv, u32 offset)
-{
- return __raw_readl(priv->mii + (offset * 4));
-}
+ int ret;
-static void gswip_mii_w(struct gswip_priv *priv, u32 val, u32 offset)
-{
- __raw_writel(val, priv->mii + (offset * 4));
+ ret = regmap_update_bits_base(priv->mdio, offset, clear | set, set,
+ NULL, false, true);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to update mdio register\n");
+ }
}
static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set,
u32 offset)
{
- u32 val = gswip_mii_r(priv, offset);
+ int ret;
- val &= ~(clear);
- val |= set;
- gswip_mii_w(priv, val, offset);
+ ret = regmap_update_bits_base(priv->mii, offset, clear | set, set, NULL,
+ false, true);
+ if (ret) {
+ WARN_ON_ONCE(1);
+ dev_err(priv->dev, "failed to update mdio register\n");
+ }
}
static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set,
@@ -222,17 +253,10 @@ static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set,
static int gswip_mdio_poll(struct gswip_priv *priv)
{
- int cnt = 100;
-
- while (likely(cnt--)) {
- u32 ctrl = gswip_mdio_r(priv, GSWIP_MDIO_CTRL);
+ u32 ctrl;
- if ((ctrl & GSWIP_MDIO_CTRL_BUSY) == 0)
- return 0;
- usleep_range(20, 40);
- }
-
- return -ETIMEDOUT;
+ return regmap_read_poll_timeout(priv->mdio, GSWIP_MDIO_CTRL, ctrl,
+ !(ctrl & GSWIP_MDIO_CTRL_BUSY), 40, 4000);
}
static int gswip_mdio_wr(struct mii_bus *bus, int addr, int reg, u16 val)
@@ -2031,11 +2055,41 @@ static int gswip_allocate_vlans(struct gswip_priv *priv)
return 0;
}
+static const struct regmap_config sw_regmap_config = {
+ .name = "switch",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_shift = -2,
+ .val_format_endian = REGMAP_ENDIAN_NATIVE,
+ .max_register = GSWIP_SDMA_PCTRLp(6),
+};
+
+static const struct regmap_config mdio_regmap_config = {
+ .name = "mdio",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_shift = -2,
+ .val_format_endian = REGMAP_ENDIAN_NATIVE,
+ .max_register = GSWIP_MDIO_PHYp(0),
+};
+
+static const struct regmap_config mii_regmap_config = {
+ .name = "mii",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_shift = -2,
+ .val_format_endian = REGMAP_ENDIAN_NATIVE,
+ .max_register = GSWIP_MII_CFGp(6),
+};
+
static int gswip_probe(struct platform_device *pdev)
{
struct device_node *np, *gphy_fw_np;
struct device *dev = &pdev->dev;
struct gswip_priv *priv;
+ __iomem void *gswip;
+ __iomem void *mdio;
+ __iomem void *mii;
int err;
int i;
@@ -2043,17 +2097,26 @@ static int gswip_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- priv->gswip = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->gswip))
- return PTR_ERR(priv->gswip);
+ gswip = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(gswip))
+ return PTR_ERR(gswip);
+
+ mdio = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(mdio))
+ return PTR_ERR(mdio);
+
+ mii = devm_platform_ioremap_resource(pdev, 2);
+ if (IS_ERR(mii))
+ return PTR_ERR(mii);
+
+ priv->gswip = devm_regmap_init_mmio(&pdev->dev, gswip,
+ &sw_regmap_config);
- priv->mdio = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(priv->mdio))
- return PTR_ERR(priv->mdio);
+ priv->mdio = devm_regmap_init_mmio(&pdev->dev, mdio,
+ &mdio_regmap_config);
- priv->mii = devm_platform_ioremap_resource(pdev, 2);
- if (IS_ERR(priv->mii))
- return PTR_ERR(priv->mii);
+ priv->mii = devm_regmap_init_mmio(&pdev->dev, mii,
+ &mii_regmap_config);
priv->hw_info = of_device_get_match_data(dev);
if (!priv->hw_info)
diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
index 1b97842b77e7..8efe298a5be3 100644
--- a/drivers/net/dsa/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq_gswip.h
@@ -270,9 +270,9 @@ struct gswip_vlan {
};
struct gswip_priv {
- __iomem void *gswip;
- __iomem void *mdio;
- __iomem void *mii;
+ struct regmap *gswip;
+ struct regmap *mdio;
+ struct regmap *mii;
const struct gswip_hw_info *hw_info;
const struct xway_gphy_match_data *gphy_fw_name_cfg;
struct dsa_switch *ds;
--
2.50.1
next reply other threads:[~2025-08-16 19:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-16 19:56 Daniel Golle [this message]
2025-08-21 17:59 ` [PATCH RFC net-next 18/23] net: dsa: lantiq_gswip: convert to use regmap Sverdlin, Alexander
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=aKDiUb084FhsmsTv@pidgin.makrotopia.org \
--to=daniel@makrotopia.org \
--cc=ajayaraman@maxlinear.com \
--cc=alexander.sverdlin@siemens.com \
--cc=andreas.schirm@siemens.com \
--cc=andrew@lunn.ch \
--cc=arkadis@mellanox.com \
--cc=bxu@maxlinear.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=f.fainelli@gmail.com \
--cc=fchan@maxlinear.com \
--cc=hauke@hauke-m.de \
--cc=horms@kernel.org \
--cc=john@phrozen.org \
--cc=jpovazanec@maxlinear.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=lrosu@maxlinear.com \
--cc=lukas.stockmann@siemens.com \
--cc=lxu@maxlinear.com \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=peter.christen@siemens.com \
--cc=yweng@maxlinear.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.