Skip to content

Commit a27a762

Browse files
colin-foster-in-advantagedavem330
authored andcommitted
net: mdio: mscc-miim: convert to a regmap implementation
Utilize regmap instead of __iomem to perform indirect mdio access. This will allow for custom regmaps to be used by way of the mscc_miim_setup function. Signed-off-by: Colin Foster <[email protected]> Tested-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 77a3124 commit a27a762

File tree

1 file changed

+121
-42
lines changed

1 file changed

+121
-42
lines changed

drivers/net/mdio/mdio-mscc-miim.c

Lines changed: 121 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/of_mdio.h>
1515
#include <linux/phy.h>
1616
#include <linux/platform_device.h>
17+
#include <linux/regmap.h>
1718

1819
#define MSCC_MIIM_REG_STATUS 0x0
1920
#define MSCC_MIIM_STATUS_STAT_PENDING BIT(2)
@@ -35,37 +36,49 @@
3536
#define MSCC_PHY_REG_PHY_STATUS 0x4
3637

3738
struct mscc_miim_dev {
38-
void __iomem *regs;
39-
void __iomem *phy_regs;
39+
struct regmap *regs;
40+
struct regmap *phy_regs;
4041
};
4142

4243
/* When high resolution timers aren't built-in: we can't use usleep_range() as
4344
* we would sleep way too long. Use udelay() instead.
4445
*/
45-
#define mscc_readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \
46-
({ \
47-
if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \
48-
readl_poll_timeout_atomic(addr, val, cond, delay_us, \
49-
timeout_us); \
50-
readl_poll_timeout(addr, val, cond, delay_us, timeout_us); \
46+
#define mscc_readx_poll_timeout(op, addr, val, cond, delay_us, timeout_us)\
47+
({ \
48+
if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \
49+
readx_poll_timeout_atomic(op, addr, val, cond, delay_us, \
50+
timeout_us); \
51+
readx_poll_timeout(op, addr, val, cond, delay_us, timeout_us); \
5152
})
5253

53-
static int mscc_miim_wait_ready(struct mii_bus *bus)
54+
static int mscc_miim_status(struct mii_bus *bus)
5455
{
5556
struct mscc_miim_dev *miim = bus->priv;
57+
int val, ret;
58+
59+
ret = regmap_read(miim->regs, MSCC_MIIM_REG_STATUS, &val);
60+
if (ret < 0) {
61+
WARN_ONCE(1, "mscc miim status read error %d\n", ret);
62+
return ret;
63+
}
64+
65+
return val;
66+
}
67+
68+
static int mscc_miim_wait_ready(struct mii_bus *bus)
69+
{
5670
u32 val;
5771

58-
return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val,
72+
return mscc_readx_poll_timeout(mscc_miim_status, bus, val,
5973
!(val & MSCC_MIIM_STATUS_STAT_BUSY), 50,
6074
10000);
6175
}
6276

6377
static int mscc_miim_wait_pending(struct mii_bus *bus)
6478
{
65-
struct mscc_miim_dev *miim = bus->priv;
6679
u32 val;
6780

68-
return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val,
81+
return mscc_readx_poll_timeout(mscc_miim_status, bus, val,
6982
!(val & MSCC_MIIM_STATUS_STAT_PENDING),
7083
50, 10000);
7184
}
@@ -80,15 +93,27 @@ static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)
8093
if (ret)
8194
goto out;
8295

83-
writel(MSCC_MIIM_CMD_VLD | (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
84-
(regnum << MSCC_MIIM_CMD_REGAD_SHIFT) | MSCC_MIIM_CMD_OPR_READ,
85-
miim->regs + MSCC_MIIM_REG_CMD);
96+
ret = regmap_write(miim->regs, MSCC_MIIM_REG_CMD, MSCC_MIIM_CMD_VLD |
97+
(mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
98+
(regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
99+
MSCC_MIIM_CMD_OPR_READ);
100+
101+
if (ret < 0) {
102+
WARN_ONCE(1, "mscc miim write cmd reg error %d\n", ret);
103+
goto out;
104+
}
86105

87106
ret = mscc_miim_wait_ready(bus);
88107
if (ret)
89108
goto out;
90109

91-
val = readl(miim->regs + MSCC_MIIM_REG_DATA);
110+
ret = regmap_read(miim->regs, MSCC_MIIM_REG_DATA, &val);
111+
112+
if (ret < 0) {
113+
WARN_ONCE(1, "mscc miim read data reg error %d\n", ret);
114+
goto out;
115+
}
116+
92117
if (val & MSCC_MIIM_DATA_ERROR) {
93118
ret = -EIO;
94119
goto out;
@@ -109,64 +134,118 @@ static int mscc_miim_write(struct mii_bus *bus, int mii_id,
109134
if (ret < 0)
110135
goto out;
111136

112-
writel(MSCC_MIIM_CMD_VLD | (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
113-
(regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
114-
(value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
115-
MSCC_MIIM_CMD_OPR_WRITE,
116-
miim->regs + MSCC_MIIM_REG_CMD);
137+
ret = regmap_write(miim->regs, MSCC_MIIM_REG_CMD, MSCC_MIIM_CMD_VLD |
138+
(mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
139+
(regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
140+
(value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
141+
MSCC_MIIM_CMD_OPR_WRITE);
117142

143+
if (ret < 0)
144+
WARN_ONCE(1, "mscc miim write error %d\n", ret);
118145
out:
119146
return ret;
120147
}
121148

122149
static int mscc_miim_reset(struct mii_bus *bus)
123150
{
124151
struct mscc_miim_dev *miim = bus->priv;
152+
int ret;
125153

126154
if (miim->phy_regs) {
127-
writel(0, miim->phy_regs + MSCC_PHY_REG_PHY_CFG);
128-
writel(0x1ff, miim->phy_regs + MSCC_PHY_REG_PHY_CFG);
155+
ret = regmap_write(miim->phy_regs, MSCC_PHY_REG_PHY_CFG, 0);
156+
if (ret < 0) {
157+
WARN_ONCE(1, "mscc reset set error %d\n", ret);
158+
return ret;
159+
}
160+
161+
ret = regmap_write(miim->phy_regs, MSCC_PHY_REG_PHY_CFG, 0x1ff);
162+
if (ret < 0) {
163+
WARN_ONCE(1, "mscc reset clear error %d\n", ret);
164+
return ret;
165+
}
166+
129167
mdelay(500);
130168
}
131169

132170
return 0;
133171
}
134172

135-
static int mscc_miim_probe(struct platform_device *pdev)
173+
static const struct regmap_config mscc_miim_regmap_config = {
174+
.reg_bits = 32,
175+
.val_bits = 32,
176+
.reg_stride = 4,
177+
};
178+
179+
static int mscc_miim_setup(struct device *dev, struct mii_bus **pbus,
180+
struct regmap *mii_regmap)
136181
{
137-
struct mscc_miim_dev *dev;
138-
struct resource *res;
182+
struct mscc_miim_dev *miim;
139183
struct mii_bus *bus;
140-
int ret;
141184

142-
bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*dev));
185+
bus = devm_mdiobus_alloc_size(dev, sizeof(*miim));
143186
if (!bus)
144187
return -ENOMEM;
145188

146189
bus->name = "mscc_miim";
147190
bus->read = mscc_miim_read;
148191
bus->write = mscc_miim_write;
149192
bus->reset = mscc_miim_reset;
150-
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev));
151-
bus->parent = &pdev->dev;
193+
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev));
194+
bus->parent = dev;
195+
196+
miim = bus->priv;
197+
198+
*pbus = bus;
199+
200+
miim->regs = mii_regmap;
201+
202+
return 0;
203+
}
204+
205+
static int mscc_miim_probe(struct platform_device *pdev)
206+
{
207+
struct regmap *mii_regmap, *phy_regmap;
208+
void __iomem *regs, *phy_regs;
209+
struct mscc_miim_dev *miim;
210+
struct mii_bus *bus;
211+
int ret;
152212

153-
dev = bus->priv;
154-
dev->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
155-
if (IS_ERR(dev->regs)) {
213+
regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
214+
if (IS_ERR(regs)) {
156215
dev_err(&pdev->dev, "Unable to map MIIM registers\n");
157-
return PTR_ERR(dev->regs);
216+
return PTR_ERR(regs);
158217
}
159218

160-
/* This resource is optional */
161-
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
162-
if (res) {
163-
dev->phy_regs = devm_ioremap_resource(&pdev->dev, res);
164-
if (IS_ERR(dev->phy_regs)) {
165-
dev_err(&pdev->dev, "Unable to map internal phy registers\n");
166-
return PTR_ERR(dev->phy_regs);
167-
}
219+
mii_regmap = devm_regmap_init_mmio(&pdev->dev, regs,
220+
&mscc_miim_regmap_config);
221+
222+
if (IS_ERR(mii_regmap)) {
223+
dev_err(&pdev->dev, "Unable to create MIIM regmap\n");
224+
return PTR_ERR(mii_regmap);
168225
}
169226

227+
phy_regs = devm_platform_ioremap_resource(pdev, 1);
228+
if (IS_ERR(phy_regs)) {
229+
dev_err(&pdev->dev, "Unable to map internal phy registers\n");
230+
return PTR_ERR(phy_regs);
231+
}
232+
233+
phy_regmap = devm_regmap_init_mmio(&pdev->dev, phy_regs,
234+
&mscc_miim_regmap_config);
235+
if (IS_ERR(phy_regmap)) {
236+
dev_err(&pdev->dev, "Unable to create phy register regmap\n");
237+
return PTR_ERR(phy_regmap);
238+
}
239+
240+
ret = mscc_miim_setup(&pdev->dev, &bus, mii_regmap);
241+
if (ret < 0) {
242+
dev_err(&pdev->dev, "Unable to setup the MDIO bus\n");
243+
return ret;
244+
}
245+
246+
miim = bus->priv;
247+
miim->phy_regs = phy_regmap;
248+
170249
ret = of_mdiobus_register(bus, pdev->dev.of_node);
171250
if (ret < 0) {
172251
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);

0 commit comments

Comments
 (0)