1 From 8b5f3f29a81a71934d004e21a1292c1148b05926 Mon Sep 17 00:00:00 2001
2 From: Ansuel Smith <ansuelsmth@gmail.com>
3 Date: Mon, 22 Nov 2021 16:23:44 +0100
4 Subject: net: dsa: qca8k: initial conversion to regmap helper
6 Convert any qca8k set/clear/pool to regmap helper and add
7 missing config to regmap_config struct.
8 Read/write/rmw operation are reworked to use the regmap helper
9 internally to keep the delta of this patch low. These additional
10 function will then be dropped when the code split will be proposed.
12 Ipq40xx SoC have the internal switch based on the qca8k regmap but use
13 mmio for read/write/rmw operation instead of mdio.
14 In preparation for the support of this internal switch, convert the
15 driver to regmap API to later split the driver to common and specific
16 code. The overhead introduced by the use of regamp API is marginal as the
17 internal mdio will bypass it by using its direct access and regmap will be
18 used only by configuration functions or fdb access.
20 Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
21 Signed-off-by: David S. Miller <davem@davemloft.net>
23 drivers/net/dsa/qca8k.c | 107 +++++++++++++++++++++---------------------------
24 1 file changed, 47 insertions(+), 60 deletions(-)
26 diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
27 index f63a432916360..d64a9af186beb 100644
28 --- a/drivers/net/dsa/qca8k.c
29 +++ b/drivers/net/dsa/qca8k.c
31 #include <linux/phy.h>
32 #include <linux/netdevice.h>
33 #include <linux/bitfield.h>
34 +#include <linux/regmap.h>
36 #include <linux/of_net.h>
37 #include <linux/of_mdio.h>
38 @@ -152,6 +153,25 @@ qca8k_set_page(struct mii_bus *bus, u16 page)
40 qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
42 + return regmap_read(priv->regmap, reg, val);
46 +qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
48 + return regmap_write(priv->regmap, reg, val);
52 +qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
54 + return regmap_update_bits(priv->regmap, reg, mask, write_val);
58 +qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
60 + struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
61 struct mii_bus *bus = priv->bus;
64 @@ -172,8 +192,9 @@ exit:
68 -qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
69 +qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
71 + struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
72 struct mii_bus *bus = priv->bus;
75 @@ -194,8 +215,9 @@ exit:
79 -qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
80 +qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
82 + struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
83 struct mii_bus *bus = priv->bus;
86 @@ -223,34 +245,6 @@ exit:
91 -qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val)
93 - return qca8k_rmw(priv, reg, 0, val);
97 -qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val)
99 - return qca8k_rmw(priv, reg, val, 0);
103 -qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
105 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
107 - return qca8k_read(priv, reg, val);
111 -qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
113 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
115 - return qca8k_write(priv, reg, val);
118 static const struct regmap_range qca8k_readable_ranges[] = {
119 regmap_reg_range(0x0000, 0x00e4), /* Global control */
120 regmap_reg_range(0x0100, 0x0168), /* EEE control */
121 @@ -282,26 +276,19 @@ static struct regmap_config qca8k_regmap_config = {
122 .max_register = 0x16ac, /* end MIB - Port6 range */
123 .reg_read = qca8k_regmap_read,
124 .reg_write = qca8k_regmap_write,
125 + .reg_update_bits = qca8k_regmap_update_bits,
126 .rd_table = &qca8k_readable_table,
127 + .disable_locking = true, /* Locking is handled by qca8k read/write */
128 + .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
132 qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
137 - ret = read_poll_timeout(qca8k_read, ret1, !(val & mask),
138 - 0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
141 - /* Check if qca8k_read has failed for a different reason
142 - * before returning -ETIMEDOUT
144 - if (ret < 0 && ret1 < 0)
148 + return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
149 + QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
153 @@ -568,7 +555,7 @@ qca8k_mib_init(struct qca8k_priv *priv)
156 mutex_lock(&priv->reg_mutex);
157 - ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
158 + ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
162 @@ -576,7 +563,7 @@ qca8k_mib_init(struct qca8k_priv *priv)
166 - ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
167 + ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
171 @@ -597,9 +584,9 @@ qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
172 mask |= QCA8K_PORT_STATUS_LINK_AUTO;
175 - qca8k_reg_set(priv, QCA8K_REG_PORT_STATUS(port), mask);
176 + regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
178 - qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask);
179 + regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
183 @@ -861,8 +848,8 @@ qca8k_setup_mdio_bus(struct qca8k_priv *priv)
184 * a dt-overlay and driver reload changed the configuration
187 - return qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
188 - QCA8K_MDIO_MASTER_EN);
189 + return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
190 + QCA8K_MDIO_MASTER_EN);
193 /* Check if the devicetree declare the port:phy mapping */
194 @@ -1099,16 +1086,16 @@ qca8k_setup(struct dsa_switch *ds)
197 /* Make sure MAC06 is disabled */
198 - ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL,
199 - QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
200 + ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
201 + QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
203 dev_err(priv->dev, "failed disabling MAC06 exchange");
207 /* Enable CPU Port */
208 - ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
209 - QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
210 + ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
211 + QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
213 dev_err(priv->dev, "failed enabling CPU port");
215 @@ -1176,8 +1163,8 @@ qca8k_setup(struct dsa_switch *ds)
218 /* Enable ARP Auto-learning by default */
219 - ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i),
220 - QCA8K_PORT_LOOKUP_LEARN);
221 + ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
222 + QCA8K_PORT_LOOKUP_LEARN);
226 @@ -1741,9 +1728,9 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
227 /* Add this port to the portvlan mask of the other ports
230 - ret = qca8k_reg_set(priv,
231 - QCA8K_PORT_LOOKUP_CTRL(i),
233 + ret = regmap_set_bits(priv->regmap,
234 + QCA8K_PORT_LOOKUP_CTRL(i),
239 @@ -1773,9 +1760,9 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
240 /* Remove this port to the portvlan mask of the other ports
243 - qca8k_reg_clear(priv,
244 - QCA8K_PORT_LOOKUP_CTRL(i),
246 + regmap_clear_bits(priv->regmap,
247 + QCA8K_PORT_LOOKUP_CTRL(i),
251 /* Set the cpu port to be the only one in the portvlan mask of