Skip to content

Commit c5fc6e4

Browse files
Jay at Control Module IndustriesRobertCNelson
authored andcommitted
cpsw: search for phy
I have encountered the same issue(s) on A6A boards. I couldn't find a patch, so I wrote this patch to update the device tree in the davinci_mdio driver in the 3.15.1 tree, it seems to correct it. I would welcome any input on a different approach. https://groups.google.com/d/msg/beagleboard/9mctrG26Mc8/SRlnumt0LoMJ v4.1-rcX: added hack around CONFIG_OF_OVERLAY v4.2-rc3+: added if (of_machine_is_compatible("ti,am335x-bone")) so we do not break dual ethernet am335x devices Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
1 parent 76fe5f4 commit c5fc6e4

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

drivers/net/ethernet/ti/davinci_mdio.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ struct davinci_mdio_data {
108108
u32 clk_div;
109109
};
110110

111+
#if IS_ENABLED(CONFIG_OF)
112+
static void davinci_mdio_update_dt_from_phymask(u32 phy_mask);
113+
#endif
114+
111115
static void davinci_mdio_init_clk(struct davinci_mdio_data *data)
112116
{
113117
u32 mdio_in, div, mdio_out_khz, access_time;
@@ -175,6 +179,12 @@ static int davinci_mdio_reset(struct mii_bus *bus)
175179
/* restrict mdio bus to live phys only */
176180
dev_info(data->dev, "detected phy mask %x\n", ~phy_mask);
177181
phy_mask = ~phy_mask;
182+
183+
#if IS_ENABLED(CONFIG_OF)
184+
if (of_machine_is_compatible("ti,am335x-bone"))
185+
davinci_mdio_update_dt_from_phymask(phy_mask);
186+
#endif
187+
178188
} else {
179189
/* desperately scan all phys */
180190
dev_warn(data->dev, "no live phy, scanning all\n");
@@ -490,6 +500,93 @@ static int davinci_mdio_runtime_resume(struct device *dev)
490500
davinci_mdio_enable(data);
491501
return 0;
492502
}
503+
static void davinci_mdio_update_dt_from_phymask(u32 phy_mask)
504+
{
505+
int i, len, skip;
506+
u32 addr;
507+
__be32 *old_phy_p, *phy_id_p;
508+
struct property *phy_id_property = NULL;
509+
struct device_node *node_p, *slave_p;
510+
511+
addr = 0;
512+
513+
for (i = 0; i < PHY_MAX_ADDR; i++) {
514+
if ((phy_mask & (1 << i)) == 0) {
515+
addr = (u32) i;
516+
break;
517+
}
518+
}
519+
520+
for_each_compatible_node(node_p, NULL, "ti,cpsw") {
521+
for_each_node_by_name(slave_p, "slave") {
522+
523+
#if IS_ENABLED(CONFIG_OF_OVERLAY)
524+
skip = 1;
525+
// Hack, the overlay fixup "slave" doesn't have phy-mode...
526+
old_phy_p = (__be32 *) of_get_property(slave_p, "phy-mode", &len);
527+
528+
if (len != (sizeof(__be32 *) * 1))
529+
{
530+
skip = 0;
531+
}
532+
533+
if (skip) {
534+
#endif
535+
536+
old_phy_p = (__be32 *) of_get_property(slave_p, "phy_id", &len);
537+
538+
if (len != (sizeof(__be32 *) * 2))
539+
goto err_out;
540+
541+
if (old_phy_p) {
542+
543+
phy_id_property = kzalloc(sizeof(*phy_id_property), GFP_KERNEL);
544+
545+
if (! phy_id_property)
546+
goto err_out;
547+
548+
phy_id_property->length = len;
549+
phy_id_property->name = kstrdup("phy_id", GFP_KERNEL);
550+
phy_id_property->value = kzalloc(len, GFP_KERNEL);
551+
552+
if (! phy_id_property->name)
553+
goto err_out;
554+
555+
if (! phy_id_property->value)
556+
goto err_out;
557+
558+
memcpy(phy_id_property->value, old_phy_p, len);
559+
560+
phy_id_p = (__be32 *) phy_id_property->value + 1;
561+
562+
*phy_id_p = cpu_to_be32(addr);
563+
564+
of_update_property(slave_p, phy_id_property);
565+
pr_info("davinci_mdio: dt: updated phy_id[%d] from phy_mask[%x]\n", addr, phy_mask);
566+
567+
++addr;
568+
}
569+
#if IS_ENABLED(CONFIG_OF_OVERLAY)
570+
}
571+
#endif
572+
}
573+
}
574+
575+
return;
576+
577+
err_out:
578+
579+
if (phy_id_property) {
580+
if (phy_id_property->name)
581+
kfree(phy_id_property->name);
582+
583+
if (phy_id_property->value)
584+
kfree(phy_id_property->value);
585+
586+
if (phy_id_property)
587+
kfree(phy_id_property);
588+
}
589+
}
493590
#endif
494591

495592
#ifdef CONFIG_PM_SLEEP

0 commit comments

Comments
 (0)