lctr-b2xx: added last ditch effort fix.
This commit is contained in:
parent
e731c8b8cf
commit
9517ff6b8a
@ -0,0 +1,136 @@
|
||||
From 83ad4305da1128111b2f063e41a740d1e19836c8 Mon Sep 17 00:00:00 2001
|
||||
From: Jay at Control Module Industries <cmidroid@gmail.com>
|
||||
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 <robertcnelson@gmail.com>
|
||||
---
|
||||
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 <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
+#include <linux/phy.h>
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
Reference in New Issue
Block a user