From 74e26fe612179aba16df5746de596e63786452db Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Mon, 11 Jun 2007 14:37:37 +0000
Subject: [PATCH] add ar7 phy fix by stefan weil

SVN-Revision: 7564
---
 .../linux/ar7-2.6/patches/210-phy_fixed.patch | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 target/linux/ar7-2.6/patches/210-phy_fixed.patch

diff --git a/target/linux/ar7-2.6/patches/210-phy_fixed.patch b/target/linux/ar7-2.6/patches/210-phy_fixed.patch
new file mode 100644
index 0000000000..0ae2282c71
--- /dev/null
+++ b/target/linux/ar7-2.6/patches/210-phy_fixed.patch
@@ -0,0 +1,94 @@
+Index: linux-2.6.21.4/drivers/net/phy/fixed.c
+===================================================================
+--- linux-2.6.21.4.orig/drivers/net/phy/fixed.c	2007-06-11 16:30:06.418483448 +0200
++++ linux-2.6.21.4/drivers/net/phy/fixed.c	2007-06-11 16:30:11.156763120 +0200
+@@ -187,6 +187,19 @@
+ 	.driver 	= { .owner = THIS_MODULE,},
+ };
+ 
++static void fixed_mdio_release (struct device * dev)
++{
++	struct phy_device *phydev = container_of(dev, struct phy_device, dev);
++	struct mii_bus *bus = phydev->bus;
++	struct fixed_info *fixed = bus->priv;
++
++	kfree(phydev);
++	kfree(bus->dev);
++	kfree(bus);
++	kfree(fixed->regs);
++	kfree(fixed);
++}
++
+ /*-----------------------------------------------------------------------------
+  *  This func is used to create all the necessary stuff, bind
+  * the fixed phy driver and register all it on the mdio_bus_type.
+@@ -221,6 +234,12 @@
+ 	}
+ 
+ 	fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL);
++	if (NULL == fixed->regs) {
++		kfree(dev);
++		kfree(new_bus);
++		kfree(fixed);
++		return -ENOMEM;
++	}
+ 	fixed->regs_num = MII_REGS_NUM;
+ 	fixed->phy_status.speed = speed;
+ 	fixed->phy_status.duplex = duplex;
+@@ -249,8 +268,11 @@
+ 	fixed->phydev = phydev;
+ 
+ 	if(NULL == phydev) {
+-		err = -ENOMEM;
+-		goto device_create_fail;
++		kfree(dev);
++		kfree(new_bus);
++		kfree(fixed->regs);
++		kfree(fixed);
++		return -ENOMEM;
+ 	}
+ 
+ 	phydev->irq = PHY_IGNORE_INTERRUPT;
+@@ -262,8 +284,34 @@
+ 	else
+ 		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
+ 				"fixed@%d:%d", speed, duplex);
++
+ 	phydev->bus = new_bus;
+ 
++#if 1
++	phydev->dev.driver = &fixed_mdio_driver.driver;
++	phydev->dev.release = fixed_mdio_release;
++
++	err = phydev->dev.driver->probe(&phydev->dev);
++	if(err < 0) {
++		printk(KERN_ERR "Phy %s: problems with fixed driver\n",
++			phydev->dev.bus_id);
++		kfree(phydev);
++		kfree(dev);
++		kfree(new_bus);
++		kfree(fixed->regs);
++		kfree(fixed);
++		return err;
++	}
++
++	down_write(&phydev->dev.bus->subsys.rwsem);
++	err = device_register(&phydev->dev);
++	if(err) {
++		printk(KERN_ERR "Phy %s failed to register\n",
++				phydev->dev.bus_id);
++	}
++
++	return 0;
++#else
+ 	err = device_register(&phydev->dev);
+ 	if(err) {
+ 		printk(KERN_ERR "Phy %s failed to register\n",
+@@ -306,6 +354,7 @@
+ 	kfree(fixed);
+ 
+ 	return err;
++#endif
+ }
+ 
+ 
-- 
2.30.2