Skip to content

Commit 5e9b461

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 <[email protected]>
1 parent 455b451 commit 5e9b461

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
@@ -124,6 +124,10 @@ static void __davinci_gpio_reset(struct davinci_mdio_data *data)
124124
}
125125
}
126126

127+
#if IS_ENABLED(CONFIG_OF)
128+
static void davinci_mdio_update_dt_from_phymask(u32 phy_mask);
129+
#endif
130+
127131
static void __davinci_mdio_reset(struct davinci_mdio_data *data)
128132
{
129133
u32 mdio_in, div, mdio_out_khz, access_time;
@@ -180,6 +184,12 @@ static int davinci_mdio_reset(struct mii_bus *bus)
180184
/* restrict mdio bus to live phys only */
181185
dev_info(data->dev, "detected phy mask %x\n", ~phy_mask);
182186
phy_mask = ~phy_mask;
187+
188+
#if IS_ENABLED(CONFIG_OF)
189+
if (of_machine_is_compatible("ti,am335x-bone"))
190+
davinci_mdio_update_dt_from_phymask(phy_mask);
191+
#endif
192+
183193
} else {
184194
/* desperately scan all phys */
185195
dev_warn(data->dev, "no live phy, scanning all\n");
@@ -370,6 +380,93 @@ static int davinci_mdio_probe_dt(struct davinci_mdio_data *data,
370380

371381
return 0;
372382
}
383+
static void davinci_mdio_update_dt_from_phymask(u32 phy_mask)
384+
{
385+
int i, len, skip;
386+
u32 addr;
387+
__be32 *old_phy_p, *phy_id_p;
388+
struct property *phy_id_property = NULL;
389+
struct device_node *node_p, *slave_p;
390+
391+
addr = 0;
392+
393+
for (i = 0; i < PHY_MAX_ADDR; i++) {
394+
if ((phy_mask & (1 << i)) == 0) {
395+
addr = (u32) i;
396+
break;
397+
}
398+
}
399+
400+
for_each_compatible_node(node_p, NULL, "ti,cpsw") {
401+
for_each_node_by_name(slave_p, "slave") {
402+
403+
#if IS_ENABLED(CONFIG_OF_OVERLAY)
404+
skip = 1;
405+
// Hack, the overlay fixup "slave" doesn't have phy-mode...
406+
old_phy_p = (__be32 *) of_get_property(slave_p, "phy-mode", &len);
407+
408+
if (len != (sizeof(__be32 *) * 1))
409+
{
410+
skip = 0;
411+
}
412+
413+
if (skip) {
414+
#endif
415+
416+
old_phy_p = (__be32 *) of_get_property(slave_p, "phy_id", &len);
417+
418+
if (len != (sizeof(__be32 *) * 2))
419+
goto err_out;
420+
421+
if (old_phy_p) {
422+
423+
phy_id_property = kzalloc(sizeof(*phy_id_property), GFP_KERNEL);
424+
425+
if (! phy_id_property)
426+
goto err_out;
427+
428+
phy_id_property->length = len;
429+
phy_id_property->name = kstrdup("phy_id", GFP_KERNEL);
430+
phy_id_property->value = kzalloc(len, GFP_KERNEL);
431+
432+
if (! phy_id_property->name)
433+
goto err_out;
434+
435+
if (! phy_id_property->value)
436+
goto err_out;
437+
438+
memcpy(phy_id_property->value, old_phy_p, len);
439+
440+
phy_id_p = (__be32 *) phy_id_property->value + 1;
441+
442+
*phy_id_p = cpu_to_be32(addr);
443+
444+
of_update_property(slave_p, phy_id_property);
445+
pr_info("davinci_mdio: dt: updated phy_id[%d] from phy_mask[%x]\n", addr, phy_mask);
446+
447+
++addr;
448+
}
449+
#if IS_ENABLED(CONFIG_OF_OVERLAY)
450+
}
451+
#endif
452+
}
453+
}
454+
455+
return;
456+
457+
err_out:
458+
459+
if (phy_id_property) {
460+
if (phy_id_property->name)
461+
kfree(phy_id_property->name);
462+
463+
if (phy_id_property->value)
464+
kfree(phy_id_property->value);
465+
466+
if (phy_id_property)
467+
kfree(phy_id_property);
468+
}
469+
}
373470
#endif
374471

375472
static int davinci_mdio_probe(struct platform_device *pdev)

0 commit comments

Comments
 (0)