提交 05486c3e 编辑于 作者: Jay at Control Module Industries's avatar Jay at Control Module Industries 提交者: Robert Nelson
浏览文件

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: default avatarRobert Nelson <robertcnelson@gmail.com>
上级 d17fbb78
......@@ -164,6 +164,10 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)
__raw_writel(data->clk_div | CONTROL_ENABLE, &data->regs->control);
}
#if IS_ENABLED(CONFIG_OF)
static void davinci_mdio_update_dt_from_phymask(u32 phy_mask);
#endif
static int davinci_mdio_reset(struct mii_bus *bus)
{
struct davinci_mdio_data *data = bus->priv;
......@@ -193,6 +197,12 @@ static int davinci_mdio_reset(struct mii_bus *bus)
/* restrict mdio bus to live phys only */
dev_info(data->dev, "detected phy mask %x\n", ~phy_mask);
phy_mask = ~phy_mask;
#if IS_ENABLED(CONFIG_OF)
if (of_machine_is_compatible("ti,am335x-bone"))
davinci_mdio_update_dt_from_phymask(phy_mask);
#endif
} else {
/* desperately scan all phys */
dev_warn(data->dev, "no live phy, scanning all\n");
......@@ -386,6 +396,93 @@ static int davinci_mdio_probe_dt(struct davinci_mdio_data *data,
return 0;
}
static void davinci_mdio_update_dt_from_phymask(u32 phy_mask)
{
int i, len, skip;
u32 addr;
__be32 *old_phy_p, *phy_id_p;
struct property *phy_id_property = NULL;
struct device_node *node_p, *slave_p;
addr = 0;
for (i = 0; i < PHY_MAX_ADDR; i++) {
if ((phy_mask & (1 << i)) == 0) {
addr = (u32) i;
break;
}
}
for_each_compatible_node(node_p, NULL, "ti,cpsw") {
for_each_node_by_name(slave_p, "slave") {
#if IS_ENABLED(CONFIG_OF_OVERLAY)
skip = 1;
// Hack, the overlay fixup "slave" doesn't have phy-mode...
old_phy_p = (__be32 *) of_get_property(slave_p, "phy-mode", &len);
if (len != (sizeof(__be32 *) * 1))
{
skip = 0;
}
if (skip) {
#endif
old_phy_p = (__be32 *) of_get_property(slave_p, "phy_id", &len);
if (len != (sizeof(__be32 *) * 2))
goto err_out;
if (old_phy_p) {
phy_id_property = kzalloc(sizeof(*phy_id_property), GFP_KERNEL);
if (! phy_id_property)
goto err_out;
phy_id_property->length = len;
phy_id_property->name = kstrdup("phy_id", GFP_KERNEL);
phy_id_property->value = kzalloc(len, GFP_KERNEL);
if (! phy_id_property->name)
goto err_out;
if (! phy_id_property->value)
goto err_out;
memcpy(phy_id_property->value, old_phy_p, len);
phy_id_p = (__be32 *) phy_id_property->value + 1;
*phy_id_p = cpu_to_be32(addr);
of_update_property(slave_p, phy_id_property);
pr_info("davinci_mdio: dt: updated phy_id[%d] from phy_mask[%x]\n", addr, phy_mask);
++addr;
}
#if IS_ENABLED(CONFIG_OF_OVERLAY)
}
#endif
}
}
return;
err_out:
if (phy_id_property) {
if (phy_id_property->name)
kfree(phy_id_property->name);
if (phy_id_property->value)
kfree(phy_id_property->value);
if (phy_id_property)
kfree(phy_id_property);
}
}
#endif
#if IS_ENABLED(CONFIG_OF)
......
支持 Markdown
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册