hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/net/ethernet/freescale/xgmac_mdio.c
....@@ -49,6 +49,7 @@
4949 struct mdio_fsl_priv {
5050 struct tgec_mdio_controller __iomem *mdio_base;
5151 bool is_little_endian;
52
+ bool has_a009885;
5253 bool has_a011043;
5354 };
5455
....@@ -184,10 +185,10 @@
184185 {
185186 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
186187 struct tgec_mdio_controller __iomem *regs = priv->mdio_base;
188
+ unsigned long flags;
187189 uint16_t dev_addr;
188190 uint32_t mdio_stat;
189191 uint32_t mdio_ctl;
190
- uint16_t value;
191192 int ret;
192193 bool endian = priv->is_little_endian;
193194
....@@ -219,40 +220,55 @@
219220 return ret;
220221 }
221222
223
+ if (priv->has_a009885)
224
+ /* Once the operation completes, i.e. MDIO_STAT_BSY clears, we
225
+ * must read back the data register within 16 MDC cycles.
226
+ */
227
+ local_irq_save(flags);
228
+
222229 /* Initiate the read */
223230 xgmac_write32(mdio_ctl | MDIO_CTL_READ, &regs->mdio_ctl, endian);
224231
225232 ret = xgmac_wait_until_done(&bus->dev, regs, endian);
226233 if (ret)
227
- return ret;
234
+ goto irq_restore;
228235
229236 /* Return all Fs if nothing was there */
230237 if ((xgmac_read32(&regs->mdio_stat, endian) & MDIO_STAT_RD_ER) &&
231238 !priv->has_a011043) {
232
- dev_err(&bus->dev,
239
+ dev_dbg(&bus->dev,
233240 "Error while reading PHY%d reg at %d.%hhu\n",
234241 phy_id, dev_addr, regnum);
235
- return 0xffff;
242
+ ret = 0xffff;
243
+ } else {
244
+ ret = xgmac_read32(&regs->mdio_data, endian) & 0xffff;
245
+ dev_dbg(&bus->dev, "read %04x\n", ret);
236246 }
237247
238
- value = xgmac_read32(&regs->mdio_data, endian) & 0xffff;
239
- dev_dbg(&bus->dev, "read %04x\n", value);
248
+irq_restore:
249
+ if (priv->has_a009885)
250
+ local_irq_restore(flags);
240251
241
- return value;
252
+ return ret;
242253 }
243254
244255 static int xgmac_mdio_probe(struct platform_device *pdev)
245256 {
246257 struct device_node *np = pdev->dev.of_node;
247258 struct mii_bus *bus;
248
- struct resource res;
259
+ struct resource *res;
249260 struct mdio_fsl_priv *priv;
250261 int ret;
251262
252
- ret = of_address_to_resource(np, 0, &res);
253
- if (ret) {
263
+ /* In DPAA-1, MDIO is one of the many FMan sub-devices. The FMan
264
+ * defines a register space that spans a large area, covering all the
265
+ * subdevice areas. Therefore, MDIO cannot claim exclusive access to
266
+ * this register area.
267
+ */
268
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
269
+ if (!res) {
254270 dev_err(&pdev->dev, "could not obtain address\n");
255
- return ret;
271
+ return -EINVAL;
256272 }
257273
258274 bus = mdiobus_alloc_size(sizeof(struct mdio_fsl_priv));
....@@ -263,21 +279,24 @@
263279 bus->read = xgmac_mdio_read;
264280 bus->write = xgmac_mdio_write;
265281 bus->parent = &pdev->dev;
266
- snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start);
282
+ bus->probe_capabilities = MDIOBUS_C22_C45;
283
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res->start);
267284
268285 /* Set the PHY base address */
269286 priv = bus->priv;
270
- priv->mdio_base = of_iomap(np, 0);
287
+ priv->mdio_base = ioremap(res->start, resource_size(res));
271288 if (!priv->mdio_base) {
272289 ret = -ENOMEM;
273290 goto err_ioremap;
274291 }
275292
276
- priv->is_little_endian = of_property_read_bool(pdev->dev.of_node,
277
- "little-endian");
293
+ priv->is_little_endian = device_property_read_bool(&pdev->dev,
294
+ "little-endian");
278295
279
- priv->has_a011043 = of_property_read_bool(pdev->dev.of_node,
280
- "fsl,erratum-a011043");
296
+ priv->has_a009885 = device_property_read_bool(&pdev->dev,
297
+ "fsl,erratum-a009885");
298
+ priv->has_a011043 = device_property_read_bool(&pdev->dev,
299
+ "fsl,erratum-a011043");
281300
282301 ret = of_mdiobus_register(bus, np);
283302 if (ret) {
....@@ -321,10 +340,17 @@
321340 };
322341 MODULE_DEVICE_TABLE(of, xgmac_mdio_match);
323342
343
+static const struct acpi_device_id xgmac_acpi_match[] = {
344
+ { "NXP0006" },
345
+ { }
346
+};
347
+MODULE_DEVICE_TABLE(acpi, xgmac_acpi_match);
348
+
324349 static struct platform_driver xgmac_mdio_driver = {
325350 .driver = {
326351 .name = "fsl-fman_xmdio",
327352 .of_match_table = xgmac_mdio_match,
353
+ .acpi_match_table = xgmac_acpi_match,
328354 },
329355 .probe = xgmac_mdio_probe,
330356 .remove = xgmac_mdio_remove,