Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/fsl_pq_mdio: Allow explicit speficition of TBIPA address

This introduces a simpler and generic method for for finding (and mapping)
the TBIPA register.

Instead of relying of complicated logic for finding the TBIPA register
address based on the MDIO or MII register block base
address, which even in some cases relies on undocumented shadow registers,
a second "reg" entry for the mdio bus devicetree node specifies the TBIPA
register.

Backwards compatibility is kept, as the existing logic is applied when
only a single "reg" mapping is specified.

Signed-off-by: Esben Haabendal <eha@deif.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Esben Haabendal and committed by
David S. Miller
21481189 4e31a684

+39 -17
+5 -1
Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
··· 6 6 of how to define a PHY. 7 7 8 8 Required properties: 9 - - reg : Offset and length of the register set for the device 9 + - reg : Offset and length of the register set for the device, and optionally 10 + the offset and length of the TBIPA register (TBI PHY address 11 + register). If TBIPA register is not specified, the driver will 12 + attempt to infer it from the register set specified (your mileage may 13 + vary). 10 14 - compatible : Should define the compatible device type for the 11 15 mdio. Currently supported strings/devices are: 12 16 - "fsl,gianfar-tbi"
+34 -16
drivers/net/ethernet/freescale/fsl_pq_mdio.c
··· 377 377 }; 378 378 MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); 379 379 380 + static void set_tbipa(const u32 tbipa_val, struct platform_device *pdev, 381 + uint32_t __iomem * (*get_tbipa)(void __iomem *), 382 + void __iomem *reg_map, struct resource *reg_res) 383 + { 384 + struct device_node *np = pdev->dev.of_node; 385 + uint32_t __iomem *tbipa; 386 + bool tbipa_mapped; 387 + 388 + tbipa = of_iomap(np, 1); 389 + if (tbipa) { 390 + tbipa_mapped = true; 391 + } else { 392 + tbipa_mapped = false; 393 + tbipa = (*get_tbipa)(reg_map); 394 + 395 + /* 396 + * Add consistency check to make sure TBI is contained within 397 + * the mapped range (not because we would get a segfault, 398 + * rather to catch bugs in computing TBI address). Print error 399 + * message but continue anyway. 400 + */ 401 + if ((void *)tbipa > reg_map + resource_size(reg_res) - 4) 402 + dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n", 403 + ((void *)tbipa - reg_map) + 4); 404 + } 405 + 406 + iowrite32be(be32_to_cpu(tbipa_val), tbipa); 407 + 408 + if (tbipa_mapped) 409 + iounmap(tbipa); 410 + } 411 + 380 412 static int fsl_pq_mdio_probe(struct platform_device *pdev) 381 413 { 382 414 const struct of_device_id *id = ··· 482 450 483 451 if (tbi) { 484 452 const u32 *prop = of_get_property(tbi, "reg", NULL); 485 - uint32_t __iomem *tbipa; 486 - 487 453 if (!prop) { 488 454 dev_err(&pdev->dev, 489 455 "missing 'reg' property in node %pOF\n", ··· 489 459 err = -EBUSY; 490 460 goto error; 491 461 } 492 - 493 - tbipa = data->get_tbipa(priv->map); 494 - 495 - /* 496 - * Add consistency check to make sure TBI is contained 497 - * within the mapped range (not because we would get a 498 - * segfault, rather to catch bugs in computing TBI 499 - * address). Print error message but continue anyway. 500 - */ 501 - if ((void *)tbipa > priv->map + resource_size(&res) - 4) 502 - dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n", 503 - ((void *)tbipa - priv->map) + 4); 504 - 505 - iowrite32be(be32_to_cpup(prop), tbipa); 462 + set_tbipa(*prop, pdev, 463 + data->get_tbipa, priv->map, &res); 506 464 } 507 465 } 508 466