From 9517ff6b8a9de42352e73a9419caa214d8c64b30 Mon Sep 17 00:00:00 2001 From: Ricardo Martins Date: Tue, 30 Sep 2014 17:09:02 +0100 Subject: [PATCH] lctr-b2xx: added last ditch effort fix. --- .../3.14.16/0007-cpsw-search-for-phy.patch | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 systems/lctr-b2xx/patches/linux/3.14.16/0007-cpsw-search-for-phy.patch diff --git a/systems/lctr-b2xx/patches/linux/3.14.16/0007-cpsw-search-for-phy.patch b/systems/lctr-b2xx/patches/linux/3.14.16/0007-cpsw-search-for-phy.patch new file mode 100644 index 0000000..2c5aa53 --- /dev/null +++ b/systems/lctr-b2xx/patches/linux/3.14.16/0007-cpsw-search-for-phy.patch @@ -0,0 +1,136 @@ +From 83ad4305da1128111b2f063e41a740d1e19836c8 Mon Sep 17 00:00:00 2001 +From: Jay at Control Module Industries +Date: Tue, 1 Jul 2014 14:49:52 -0500 +Subject: [PATCH 7/7] 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 + +Signed-off-by: Robert Nelson +--- + drivers/net/ethernet/ti/davinci_mdio.c | 83 ++++++++++++++++++++++++++++++++++ + 1 file changed, 83 insertions(+) + +diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c +index 0cca9de..0197edd 100644 +--- a/drivers/net/ethernet/ti/davinci_mdio.c ++++ b/drivers/net/ethernet/ti/davinci_mdio.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + /* + * This timeout definition is a worst-case ultra defensive measure against +@@ -97,6 +98,10 @@ struct davinci_mdio_data { + unsigned long access_time; /* jiffies */ + }; + ++#if IS_ENABLED(CONFIG_OF) ++static void davinci_mdio_update_dt_from_phymask(u32 phy_mask); ++#endif ++ + static void __davinci_mdio_reset(struct davinci_mdio_data *data) + { + u32 mdio_in, div, mdio_out_khz, access_time; +@@ -150,6 +155,11 @@ 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) ++ davinci_mdio_update_dt_from_phymask(phy_mask); ++ #endif ++ + } else { + /* desperately scan all phys */ + dev_warn(data->dev, "no live phy, scanning all\n"); +@@ -312,6 +322,79 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data, + } + #endif + ++#if IS_ENABLED(CONFIG_OF) ++static void davinci_mdio_update_dt_from_phymask(u32 phy_mask) ++{ ++ int i, len; ++ 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") { ++ ++ 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); ++ ++ ++addr; ++ } ++ } ++ } ++ ++ 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 ++ + static int davinci_mdio_probe(struct platform_device *pdev) + { + struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev); +-- +2.0.0 +