All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties
@ 2009-03-19  5:00 Grant Likely
  2009-03-19  5:00 ` [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs Grant Likely
                   ` (9 more replies)
  0 siblings, 10 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

of_parse_phandle() is a helper function to read and parse a phandle
property and return a pointer to the resulting device_node.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/of/base.c  |   23 +++++++++++++++++++++++
 include/linux/of.h |    3 +++
 2 files changed, 26 insertions(+), 0 deletions(-)


diff --git a/drivers/of/base.c b/drivers/of/base.c
index cd17092..1eaada4 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -494,6 +494,29 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
 EXPORT_SYMBOL_GPL(of_modalias_node);
 
 /**
+ * of_parse_phandle - Resolve a phandle property to a device_node pointer
+ * @np: Pointer to device node holding phandle property
+ * @phandle_name: Name of property holding a phandle value
+ * @index: For properties holding a table of phandles, this is the index into
+ *         the table
+ *
+ * Returns the device_node pointer pointed to by the phandle, or NULL
+ */
+struct device_node *
+of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
+{
+	const phandle *phandle;
+	int size;
+
+	phandle = of_get_property(np, phandle_name, &size);
+	if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
+		return NULL;
+
+	return of_find_node_by_phandle(phandle[index]);
+}
+EXPORT_SYMBOL(of_parse_phandle);
+
+/**
  * of_parse_phandles_with_args - Find a node pointed by phandle in a list
  * @np:		pointer to a device tree node containing a list
  * @list_name:	property name that contains a list
diff --git a/include/linux/of.h b/include/linux/of.h
index 6a7efa2..7be2d10 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -77,6 +77,9 @@ extern int of_n_size_cells(struct device_node *np);
 extern const struct of_device_id *of_match_node(
 	const struct of_device_id *matches, const struct device_node *node);
 extern int of_modalias_node(struct device_node *node, char *modalias, int len);
+extern struct device_node *of_parse_phandle(struct device_node *np,
+					    const char *phandle_name,
+					    int index);
 extern int of_parse_phandles_with_args(struct device_node *np,
 	const char *list_name, const char *cells_name, int index,
 	struct device_node **out_node, const void **out_args);


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:05     ` Grant Likely
  2009-03-19  5:00 ` [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions Grant Likely
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

This patch makes changes in preparation for supporting open firmware
device tree descriptions of MDIO busses.  Changes include:
- Cleanup handling of phy_map[] entries; they are already NULLed when
  registering and so don't need to be re-cleared, and it is good practice
  to clear them out when unregistering.
- Split phy_device registration out into a new function so that the
  OF helpers can do two stage registration (separate allocation and
  registration steps).

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: linuxppc-dev@ozlabs.org
CC: netdev@vger.kernel.org
CC: Andy Fleming <afleming@freescale.com>
---

 drivers/net/phy/mdio_bus.c   |   29 +++-------------------------
 drivers/net/phy/phy_device.c |   43 ++++++++++++++++++++++++++++++++++++++----
 include/linux/phy.h          |    1 +
 3 files changed, 43 insertions(+), 30 deletions(-)


diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 811a637..3c39c7b 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -112,7 +112,6 @@ int mdiobus_register(struct mii_bus *bus)
 		bus->reset(bus);
 
 	for (i = 0; i < PHY_MAX_ADDR; i++) {
-		bus->phy_map[i] = NULL;
 		if ((bus->phy_mask & (1 << i)) == 0) {
 			struct phy_device *phydev;
 
@@ -149,6 +148,7 @@ void mdiobus_unregister(struct mii_bus *bus)
 	for (i = 0; i < PHY_MAX_ADDR; i++) {
 		if (bus->phy_map[i])
 			device_unregister(&bus->phy_map[i]->dev);
+		bus->phy_map[i] = NULL;
 	}
 }
 EXPORT_SYMBOL(mdiobus_unregister);
@@ -187,35 +187,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
 	if (IS_ERR(phydev) || phydev == NULL)
 		return phydev;
 
-	/* There's a PHY at this address
-	 * We need to set:
-	 * 1) IRQ
-	 * 2) bus_id
-	 * 3) parent
-	 * 4) bus
-	 * 5) mii_bus
-	 * And, we need to register it */
-
-	phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
-
-	phydev->dev.parent = bus->parent;
-	phydev->dev.bus = &mdio_bus_type;
-	dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
-
-	phydev->bus = bus;
-
-	/* Run all of the fixups for this PHY */
-	phy_scan_fixups(phydev);
-
-	err = device_register(&phydev->dev);
+	err = phy_device_register(phydev);
 	if (err) {
-		printk(KERN_ERR "phy %d failed to register\n", addr);
 		phy_device_free(phydev);
-		phydev = NULL;
+		return NULL;
 	}
 
-	bus->phy_map[addr] = phydev;
-
 	return phydev;
 }
 EXPORT_SYMBOL(mdiobus_scan);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0a06e4f..793332f 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -39,10 +39,6 @@ MODULE_DESCRIPTION("PHY library");
 MODULE_AUTHOR("Andy Fleming");
 MODULE_LICENSE("GPL");
 
-static struct phy_driver genphy_driver;
-extern int mdio_bus_init(void);
-extern void mdio_bus_exit(void);
-
 void phy_device_free(struct phy_device *phydev)
 {
 	kfree(phydev);
@@ -53,6 +49,10 @@ static void phy_device_release(struct device *dev)
 	phy_device_free(to_phy_device(dev));
 }
 
+static struct phy_driver genphy_driver;
+extern int mdio_bus_init(void);
+extern void mdio_bus_exit(void);
+
 static LIST_HEAD(phy_fixup_list);
 static DEFINE_MUTEX(phy_fixup_lock);
 
@@ -166,6 +166,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
 	dev->addr = addr;
 	dev->phy_id = phy_id;
 	dev->bus = bus;
+	dev->dev.parent = bus->parent;
+	dev->dev.bus = &mdio_bus_type;
+	dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
+	dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
 
 	dev->state = PHY_DOWN;
 
@@ -237,6 +241,37 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
 }
 
 /**
+ * phy_device_register - Register the phy device on the MDIO bus
+ * @phy_device: phy_device structure to be added to the MDIO bus
+ */
+int phy_device_register(struct phy_device *phydev)
+{
+	int err;
+
+	/* Don't register a phy if one is already registered at this
+	 * address */
+	if (phydev->bus->phy_map[phydev->addr])
+		return -EINVAL;
+	phydev->bus->phy_map[phydev->addr] = phydev;
+
+	/* Run all of the fixups for this PHY */
+	phy_scan_fixups(phydev);
+
+	err = device_register(&phydev->dev);
+	if (err) {
+		pr_err("phy %d failed to register\n", phydev->addr);
+		goto out;
+	}
+
+	return 0;
+
+ out:
+	phydev->bus->phy_map[phydev->addr] = NULL;
+	return err;
+}
+EXPORT_SYMBOL(phy_device_register);
+
+/**
  * phy_prepare_link - prepares the PHY layer to monitor link status
  * @phydev: target phy_device struct
  * @handler: callback function for link status change notifications
diff --git a/include/linux/phy.h b/include/linux/phy.h
index d7e54d9..a47d64f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -439,6 +439,7 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
 
 int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
 struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
+int phy_device_register(struct phy_device *phy);
 int phy_clear_interrupt(struct phy_device *phydev);
 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
 struct phy_device * phy_attach(struct net_device *dev,


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
  2009-03-19  5:00 ` [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:05     ` Grant Likely
  2009-03-19  5:00 ` [PATCH 4/9] openfirmware: Add OF phylib support code Grant Likely
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

Add phy_connect_direct() and phy_attach_direct() functions so that
drivers can use a pointer to the phy_device instead of trying to determine
the phy's bus_id string.

This patch is useful for OF device tree descriptions of phy devices where
the driver doesn't need or know what the bus_id value in order to get a
phy_device pointer.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/net/phy/phy_device.c |  118 ++++++++++++++++++++++++++++++------------
 include/linux/phy.h          |    5 ++
 2 files changed, 90 insertions(+), 33 deletions(-)


diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 793332f..238d21e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -290,6 +290,33 @@ void phy_prepare_link(struct phy_device *phydev,
 }
 
 /**
+ * phy_connect_direct - connect an ethernet device to a specific phy_device
+ * @dev: the network device to connect
+ * @phydev: the pointer to the phy device
+ * @handler: callback function for state change notifications
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ */
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+		       void (*handler)(struct net_device *), u32 flags,
+		       phy_interface_t interface)
+{
+	int rc;
+
+	rc = phy_attach_direct(dev, phydev, flags, interface);
+	if (rc)
+		return rc;
+
+	phy_prepare_link(phydev, handler);
+	phy_start_machine(phydev, NULL);
+	if (phydev->irq > 0)
+		phy_start_interrupts(phydev);
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_connect_direct);
+
+/**
  * phy_connect - connect an ethernet device to a PHY device
  * @dev: the network device to connect
  * @bus_id: the id string of the PHY device to connect
@@ -310,18 +337,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
 		phy_interface_t interface)
 {
 	struct phy_device *phydev;
+	struct device *d;
+	int rc;
 
-	phydev = phy_attach(dev, bus_id, flags, interface);
-
-	if (IS_ERR(phydev))
-		return phydev;
-
-	phy_prepare_link(phydev, handler);
-
-	phy_start_machine(phydev, NULL);
+	/* Search the list of PHY devices on the mdio bus for the
+	 * PHY with the requested name */
+	d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
+	if (!d) {
+		pr_err("PHY %s not found\n", bus_id);
+		return ERR_PTR(-ENODEV);
+	}
+	phydev = to_phy_device(d);
 
-	if (phydev->irq > 0)
-		phy_start_interrupts(phydev);
+	rc = phy_attach_direct(dev, phydev, flags, interface);
+	if (rc)
+		return ERR_PTR(rc);
 
 	return phydev;
 }
@@ -345,9 +375,9 @@ void phy_disconnect(struct phy_device *phydev)
 EXPORT_SYMBOL(phy_disconnect);
 
 /**
- * phy_attach - attach a network device to a particular PHY device
+ * phy_attach_direct - attach a network device to a given PHY device pointer
  * @dev: network device to attach
- * @bus_id: PHY device to attach
+ * @phydev: Pointer to phy_device to attach
  * @flags: PHY device's dev_flags
  * @interface: PHY device's interface
  *
@@ -358,22 +388,10 @@ EXPORT_SYMBOL(phy_disconnect);
  *     the attaching device, and given a callback for link status
  *     change.  The phy_device is returned to the attaching driver.
  */
-struct phy_device *phy_attach(struct net_device *dev,
-		const char *bus_id, u32 flags, phy_interface_t interface)
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+		      u32 flags, phy_interface_t interface)
 {
-	struct bus_type *bus = &mdio_bus_type;
-	struct phy_device *phydev;
-	struct device *d;
-
-	/* Search the list of PHY devices on the mdio bus for the
-	 * PHY with the requested name */
-	d = bus_find_device_by_name(bus, NULL, bus_id);
-	if (d) {
-		phydev = to_phy_device(d);
-	} else {
-		printk(KERN_ERR "%s not found\n", bus_id);
-		return ERR_PTR(-ENODEV);
-	}
+	struct device *d = &phydev->dev;
 
 	/* Assume that if there is no driver, that it doesn't
 	 * exist, and we should use the genphy driver. */
@@ -386,13 +404,12 @@ struct phy_device *phy_attach(struct net_device *dev,
 			err = device_bind_driver(d);
 
 		if (err)
-			return ERR_PTR(err);
+			return err;
 	}
 
 	if (phydev->attached_dev) {
-		printk(KERN_ERR "%s: %s already attached\n",
-				dev->name, bus_id);
-		return ERR_PTR(-EBUSY);
+		dev_err(&dev->dev, "PHY already attached\n");
+		return -EBUSY;
 	}
 
 	phydev->attached_dev = dev;
@@ -410,13 +427,48 @@ struct phy_device *phy_attach(struct net_device *dev,
 		err = phy_scan_fixups(phydev);
 
 		if (err < 0)
-			return ERR_PTR(err);
+			return err;
 
 		err = phydev->drv->config_init(phydev);
 
 		if (err < 0)
-			return ERR_PTR(err);
+			return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_attach_direct);
+
+/**
+ * phy_attach - attach a network device to a particular PHY device
+ * @dev: network device to attach
+ * @bus_id: Bus ID of PHY device to attach
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ *
+ * Description: Same as phy_attach_direct() except that a PHY bus_id
+ *     string is passed instead of a pointer to a struct phy_device.
+ */
+struct phy_device *phy_attach(struct net_device *dev,
+		const char *bus_id, u32 flags, phy_interface_t interface)
+{
+	struct bus_type *bus = &mdio_bus_type;
+	struct phy_device *phydev;
+	struct device *d;
+	int rc;
+
+	/* Search the list of PHY devices on the mdio bus for the
+	 * PHY with the requested name */
+	d = bus_find_device_by_name(bus, NULL, bus_id);
+	if (!d) {
+		pr_err("PHY %s not found\n", bus_id);
+		return ERR_PTR(-ENODEV);
 	}
+	phydev = to_phy_device(d);
+
+	rc = phy_attach_direct(dev, phydev, flags, interface);
+	if (rc)
+		return ERR_PTR(rc);
 
 	return phydev;
 }
diff --git a/include/linux/phy.h b/include/linux/phy.h
index a47d64f..97405f2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -442,8 +442,13 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
 int phy_device_register(struct phy_device *phy);
 int phy_clear_interrupt(struct phy_device *phydev);
 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+		u32 flags, phy_interface_t interface);
 struct phy_device * phy_attach(struct net_device *dev,
 		const char *bus_id, u32 flags, phy_interface_t interface);
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+		void (*handler)(struct net_device *), u32 flags,
+		phy_interface_t interface);
 struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
 		void (*handler)(struct net_device *), u32 flags,
 		phy_interface_t interface);


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 4/9] openfirmware: Add OF phylib support code
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
  2009-03-19  5:00 ` [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs Grant Likely
  2009-03-19  5:00 ` [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:06     ` Grant Likely
  2009-03-19  5:00 ` [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure Grant Likely
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

Add support for parsing the device tree for PHY devices on an MDIO bus

CC: Andy Fleming <afleming@freescale.com>
CC: linuxppc-dev@ozlabs.org
CC: devtree-discuss@ozlabs.org

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/of/Kconfig      |    6 ++
 drivers/of/Makefile     |    1 
 drivers/of/of_mdio.c    |  130 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_mdio.h |   21 ++++++++
 4 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 drivers/of/of_mdio.c
 create mode 100644 include/linux/of_mdio.h


diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index f821dbc..6fe043b 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -19,3 +19,9 @@ config OF_SPI
 	depends on OF && PPC_OF && SPI
 	help
 	  OpenFirmware SPI accessors
+
+config OF_MDIO
+	def_tristate PHYLIB
+	depends on OF && PHYLIB
+	help
+	  OpenFirmware MDIO bus (Ethernet PHY) accessors
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 4c3c6f8..bdfb5f5 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
+obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
new file mode 100644
index 0000000..6f3038a
--- /dev/null
+++ b/drivers/of/of_mdio.c
@@ -0,0 +1,130 @@
+/*
+ * OF helpers for the MDIO (Ethernet PHY) API
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ *
+ * This file is released under the GPLv2
+ *
+ * This file provides helper functions for extracting PHY device information
+ * out of the OpenFirmware device tree and using it to populate an mii_bus.
+ */
+
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_LICENSE("GPL");
+
+/**
+ * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
+ * @mdio: pointer to mii_bus structure
+ * @np: pointer to device_node of MDIO bus.
+ *
+ * This function registers the mii_bus structure and registers a phy_device
+ * for each child node of @np.
+ */
+int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+{
+	struct phy_device *phy;
+	struct device_node *child;
+	int rc, i;
+
+	/* Mask out all PHYs from auto probing.  Instead the PHYs listed in
+	 * the device tree are populated after the bus has been registered */
+	mdio->phy_mask = ~0;
+
+	/* Clear all the IRQ properties */
+	if (mdio->irq)
+		for (i=0; i<PHY_MAX_ADDR; i++)
+			mdio->irq[i] = PHY_POLL;
+
+	/* Register the MDIO bus */
+	rc = mdiobus_register(mdio);
+	if (rc)
+		return rc;
+
+	/* Loop over the child nodes and register a phy_device for each one */
+	for_each_child_of_node(np, child) {
+		const u32 *addr;
+		int len;
+
+		/* A PHY must have a reg property in the range [0-31] */
+		addr = of_get_property(child, "reg", &len);
+		if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) {
+			dev_err(&mdio->dev, "%s has invalid PHY address\n",
+				child->full_name);
+			continue;
+		}
+
+		if (mdio->irq) {
+			mdio->irq[*addr] = irq_of_parse_and_map(child, 0);
+			if (!mdio->irq[*addr])
+				mdio->irq[*addr] = PHY_POLL;
+		}
+
+		phy = get_phy_device(mdio, *addr);
+		if (!phy) {
+			dev_err(&mdio->dev, "error probing PHY at address %i\n",
+				*addr);
+			continue;
+		}
+		phy_scan_fixups(phy);
+
+		/* Associate the OF node with the device structure so it
+		 * can be looked up later */
+		of_node_get(child);
+		dev_archdata_set_node(&phy->dev.archdata, child);
+
+		/* All data is now stored in the phy struct; register it */
+		rc = phy_device_register(phy);
+		if (rc) {
+			phy_device_free(phy);
+			of_node_put(child);
+			continue;
+		}
+
+		dev_dbg(&mdio->dev, "registered phy %s at address %i\n",
+			child->name, *addr);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(of_mdiobus_register);
+
+/**
+ * of_phy_connect - Connect to the phy described in the device tree
+ * @dev: pointer to net_device claiming the phy
+ * @phy_np: Pointer to device tree node for the PHY
+ * @hndlr: Link state callback for the network device
+ * @iface: PHY data interface type
+ *
+ * Returns a pointer to the phy_device if successfull.  NULL otherwise
+ */
+struct phy_device *of_phy_connect(struct net_device *dev,
+				  struct device_node *phy_np,
+				  void (*hndlr)(struct net_device *), u32 flags,
+				  phy_interface_t iface)
+{
+	int match(struct device *dev, void *phy_np)
+	{
+		return dev_archdata_get_node(&dev->archdata) == phy_np;
+	}
+	struct device *d;
+	int rc;
+
+	if (!phy_np)
+		return NULL;
+
+	d = bus_find_device(&mdio_bus_type, NULL, phy_np, match);
+	if (!d)
+		return NULL;
+
+	rc = phy_connect_direct(dev, to_phy_device(d), hndlr, flags, iface);
+	if (rc)
+		return NULL;
+
+	return to_phy_device(d);
+}
+EXPORT_SYMBOL(of_phy_connect);
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
new file mode 100644
index 0000000..ec092cc
--- /dev/null
+++ b/include/linux/of_mdio.h
@@ -0,0 +1,21 @@
+/*
+ * OF helpers for the MDIO (Ethernet PHY) API
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_MDIO_H
+#define __LINUX_OF_MDIO_H
+
+#include <linux/phy.h>
+#include <linux/of.h>
+
+extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
+extern struct phy_device *of_phy_connect(struct net_device *dev,
+					 struct device_node *phy_np,
+					 void (*hndlr)(struct net_device *),
+					 u32 flags, phy_interface_t iface);
+
+#endif /* __LINUX_OF_MDIO_H */


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
                   ` (2 preceding siblings ...)
  2009-03-19  5:00 ` [PATCH 4/9] openfirmware: Add OF phylib support code Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:06     ` Grant Likely
  2009-03-19  5:00 ` [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions Grant Likely
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

The patch reworks the MPC5200 Fast Ethernet Controller (FEC) driver to
use the of_mdio infrastructure for registering PHY devices from data out
openfirmware device tree, and eliminates the assumption that the PHY
for the FEC is always attached to the FEC's own MDIO bus.  With this
patch, the FEC can use a PHY attached to any MDIO bus if it is described
in the device tree.
---

 drivers/net/Kconfig           |    2 
 drivers/net/fec_mpc52xx.c     |  175 +++++++++++------------------------------
 drivers/net/fec_mpc52xx_phy.c |   26 +-----
 3 files changed, 53 insertions(+), 150 deletions(-)


diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index a2f185f..3aa24f6 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1854,7 +1854,7 @@ config FEC_MPC52xx
 
 config FEC_MPC52xx_MDIO
 	bool "MPC52xx FEC MDIO bus driver"
-	depends on FEC_MPC52xx
+	depends on FEC_MPC52xx && OF_MDIO
 	default y
 	---help---
 	  The MPC5200's FEC can connect to the Ethernet either with
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 3d55f9a..12ab8ae 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -25,6 +25,7 @@
 #include <linux/hardirq.h>
 #include <linux/delay.h>
 #include <linux/of_device.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <linux/netdevice.h>
@@ -43,11 +44,9 @@
 
 #define DRIVER_NAME "mpc52xx-fec"
 
-#define FEC5200_PHYADDR_NONE	(-1)
-#define FEC5200_PHYADDR_7WIRE	(-2)
-
 /* Private driver data structure */
 struct mpc52xx_fec_priv {
+	struct net_device *ndev;
 	int duplex;
 	int speed;
 	int r_irq;
@@ -59,10 +58,11 @@ struct mpc52xx_fec_priv {
 	int msg_enable;
 
 	/* MDIO link details */
-	int phy_addr;
-	unsigned int phy_speed;
+	unsigned int mdio_speed;
+	struct device_node *phy_node;
 	struct phy_device *phydev;
 	enum phy_state link;
+	int seven_wire_mode;
 };
 
 
@@ -210,66 +210,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
 		phy_print_status(phydev);
 }
 
-static int mpc52xx_fec_init_phy(struct net_device *dev)
-{
-	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-	struct phy_device *phydev;
-	char phy_id[BUS_ID_SIZE];
-
-	snprintf(phy_id, sizeof(phy_id), "%x:%02x",
-			(unsigned int)dev->base_addr, priv->phy_addr);
-
-	priv->link = PHY_DOWN;
-	priv->speed = 0;
-	priv->duplex = -1;
-
-	phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
-	if (IS_ERR(phydev)) {
-		dev_err(&dev->dev, "phy_connect failed\n");
-		return PTR_ERR(phydev);
-	}
-	dev_info(&dev->dev, "attached phy %i to driver %s\n",
-			phydev->addr, phydev->drv->name);
-
-	priv->phydev = phydev;
-
-	return 0;
-}
-
-static int mpc52xx_fec_phy_start(struct net_device *dev)
-{
-	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-	int err;
-
-	if (priv->phy_addr < 0)
-		return 0;
-
-	err = mpc52xx_fec_init_phy(dev);
-	if (err) {
-		dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n");
-		return err;
-	}
-
-	/* reset phy - this also wakes it from PDOWN */
-	phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
-	phy_start(priv->phydev);
-
-	return 0;
-}
-
-static void mpc52xx_fec_phy_stop(struct net_device *dev)
-{
-	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-
-	if (!priv->phydev)
-		return;
-
-	phy_disconnect(priv->phydev);
-	/* power down phy */
-	phy_stop(priv->phydev);
-	phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
-}
-
 static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
 		struct mii_ioctl_data *mii_data, int cmd)
 {
@@ -279,25 +219,25 @@ static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
 	return phy_mii_ioctl(priv->phydev, mii_data, cmd);
 }
 
-static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
-{
-	struct mpc52xx_fec __iomem *fec = priv->fec;
-
-	if (priv->phydev)
-		return;
-
-	out_be32(&fec->mii_speed, priv->phy_speed);
-}
-
 static int mpc52xx_fec_open(struct net_device *dev)
 {
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 	int err = -EBUSY;
 
+	if (priv->phy_node) {
+		priv->phydev = of_phy_connect(priv->ndev, priv->phy_node,
+					      mpc52xx_fec_adjust_link, 0, 0);
+		if (!priv->phydev) {
+			dev_err(&dev->dev, "of_phy_connect failed\n");
+			return -ENODEV;
+		}
+		phy_start(priv->phydev);
+	}
+
 	if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
 	                DRIVER_NAME "_ctrl", dev)) {
 		dev_err(&dev->dev, "ctrl interrupt request failed\n");
-		goto out;
+		goto free_phy;
 	}
 	if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
 	                DRIVER_NAME "_rx", dev)) {
@@ -319,10 +259,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
 		goto free_irqs;
 	}
 
-	err = mpc52xx_fec_phy_start(dev);
-	if (err)
-		goto free_skbs;
-
 	bcom_enable(priv->rx_dmatsk);
 	bcom_enable(priv->tx_dmatsk);
 
@@ -332,16 +268,18 @@ static int mpc52xx_fec_open(struct net_device *dev)
 
 	return 0;
 
- free_skbs:
-	mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
-
  free_irqs:
 	free_irq(priv->t_irq, dev);
  free_2irqs:
 	free_irq(priv->r_irq, dev);
  free_ctrl_irq:
 	free_irq(dev->irq, dev);
- out:
+ free_phy:
+	if (priv->phydev) {
+		phy_stop(priv->phydev);
+		phy_disconnect(priv->phydev);
+		priv->phydev = NULL;
+	}
 
 	return err;
 }
@@ -360,7 +298,12 @@ static int mpc52xx_fec_close(struct net_device *dev)
 	free_irq(priv->r_irq, dev);
 	free_irq(priv->t_irq, dev);
 
-	mpc52xx_fec_phy_stop(dev);
+	if (priv->phydev) {
+		/* power down phy */
+		phy_stop(priv->phydev);
+		phy_disconnect(priv->phydev);
+		priv->phydev = NULL;
+	}
 
 	return 0;
 }
@@ -700,7 +643,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
 	/* set phy speed.
 	 * this can't be done in phy driver, since it needs to be called
 	 * before fec stuff (even on resume) */
-	mpc52xx_fec_phy_hw_init(priv);
+	out_be32(&fec->mii_speed, priv->mdio_speed);
 }
 
 /**
@@ -736,7 +679,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
 	rcntrl = FEC_RX_BUFFER_SIZE << 16;	/* max frame length */
 	rcntrl |= FEC_RCNTRL_FCE;
 
-	if (priv->phy_addr != FEC5200_PHYADDR_7WIRE)
+	if (!priv->seven_wire_mode)
 		rcntrl |= FEC_RCNTRL_MII_MODE;
 
 	if (priv->duplex == DUPLEX_FULL)
@@ -802,8 +745,6 @@ static void mpc52xx_fec_stop(struct net_device *dev)
 
 	/* Stop FEC */
 	out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
-
-	return;
 }
 
 /* reset fec and bestcomm tasks */
@@ -821,9 +762,11 @@ static void mpc52xx_fec_reset(struct net_device *dev)
 
 	mpc52xx_fec_hw_init(dev);
 
-	phy_stop(priv->phydev);
-	phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
-	phy_start(priv->phydev);
+	if (priv->phydev) {
+		phy_stop(priv->phydev);
+		phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+		phy_start(priv->phydev);
+	}
 
 	bcom_fec_rx_reset(priv->rx_dmatsk);
 	bcom_fec_tx_reset(priv->tx_dmatsk);
@@ -923,7 +866,6 @@ static const struct net_device_ops mpc52xx_fec_netdev_ops = {
 #endif
 };
 
-
 static int __devinit
 mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 {
@@ -931,8 +873,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 	struct net_device *ndev;
 	struct mpc52xx_fec_priv *priv = NULL;
 	struct resource mem;
-	struct device_node *phy_node;
-	const phandle *phy_handle;
 	const u32 *prop;
 	int prop_size;
 
@@ -945,6 +885,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 		return -ENOMEM;
 
 	priv = netdev_priv(ndev);
+	priv->ndev = ndev;
 
 	/* Reserve FEC control zone */
 	rv = of_address_to_resource(op->node, 0, &mem);
@@ -968,6 +909,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 	ndev->watchdog_timeo	= FEC_WATCHDOG_TIMEOUT;
 	ndev->base_addr		= mem.start;
 	ndev->netdev_ops = &mpc52xx_fec_netdev_ops;
+	SET_NETDEV_DEV(ndev, &op->dev);
 
 	priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
 
@@ -1017,14 +959,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 	 */
 
 	/* Start with safe defaults for link connection */
-	priv->phy_addr = FEC5200_PHYADDR_NONE;
-	priv->speed = 100;
+	priv->speed = 10;
 	priv->duplex = DUPLEX_HALF;
-	priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
-
-	/* the 7-wire property means don't use MII mode */
-	if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
-		priv->phy_addr = FEC5200_PHYADDR_7WIRE;
+	priv->mdio_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
 
 	/* The current speed preconfigures the speed of the MII link */
 	prop = of_get_property(op->node, "current-speed", &prop_size);
@@ -1033,43 +970,23 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 		priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
 	}
 
-	/* If there is a phy handle, setup link to that phy */
-	phy_handle = of_get_property(op->node, "phy-handle", &prop_size);
-	if (phy_handle && (prop_size >= sizeof(phandle))) {
-		phy_node = of_find_node_by_phandle(*phy_handle);
-		prop = of_get_property(phy_node, "reg", &prop_size);
-		if (prop && (prop_size >= sizeof(u32)))
-			if ((*prop >= 0) && (*prop < PHY_MAX_ADDR))
-				priv->phy_addr = *prop;
-		of_node_put(phy_node);
+	/* If there is a phy handle, then get the PHY node */
+	priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+
+	/* the 7-wire property means don't use MII mode */
+	if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) {
+		priv->seven_wire_mode = 1;
+		dev_info(&ndev->dev, "using 7-wire PHY mode\n");
 	}
 
 	/* Hardware init */
 	mpc52xx_fec_hw_init(ndev);
-
 	mpc52xx_fec_reset_stats(ndev);
 
-	SET_NETDEV_DEV(ndev, &op->dev);
-
-	/* Register the new network device */
 	rv = register_netdev(ndev);
 	if (rv < 0)
 		goto probe_error;
 
-	/* Now report the link setup */
-	switch (priv->phy_addr) {
-	 case FEC5200_PHYADDR_NONE:
-		dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n",
-			 priv->speed, priv->duplex ? 'F' : 'H');
-		break;
-	 case FEC5200_PHYADDR_7WIRE:
-		dev_info(&ndev->dev, "using 7-wire PHY mode\n");
-		break;
-	 default:
-		dev_info(&ndev->dev, "Using PHY at MDIO address %i\n",
-			 priv->phy_addr);
-	}
-
 	/* We're done ! */
 	dev_set_drvdata(&op->dev, ndev);
 
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index dd9bfa4..fec9f24 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -14,12 +14,14 @@
 #include <linux/netdevice.h>
 #include <linux/phy.h>
 #include <linux/of_platform.h>
+#include <linux/of_mdio.h>
 #include <asm/io.h>
 #include <asm/mpc52xx.h>
 #include "fec_mpc52xx.h"
 
 struct mpc52xx_fec_mdio_priv {
 	struct mpc52xx_fec __iomem *regs;
+	int mdio_irqs[PHY_MAX_ADDR];
 };
 
 static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
@@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
 {
 	struct mpc52xx_fec_mdio_priv *priv = bus->priv;
 	struct mpc52xx_fec __iomem *fec;
-	int tries = 100;
+	int tries = 3;
 
 	value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
 	value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
@@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
 
 	/* wait for it to finish, this takes about 23 us on lite5200b */
 	while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
-		udelay(5);
+		msleep(1);
 
 	if (!tries)
 		return -ETIMEDOUT;
@@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
 {
 	struct device *dev = &of->dev;
 	struct device_node *np = of->node;
-	struct device_node *child = NULL;
 	struct mii_bus *bus;
 	struct mpc52xx_fec_mdio_priv *priv;
 	struct resource res = {};
@@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
 	bus->write = mpc52xx_fec_mdio_write;
 
 	/* setup irqs */
-	bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
-	if (bus->irq == NULL) {
-		err = -ENOMEM;
-		goto out_free;
-	}
-	for (i=0; i<PHY_MAX_ADDR; i++)
-		bus->irq[i] = PHY_POLL;
-
-	while ((child = of_get_next_child(np, child)) != NULL) {
-		int irq = irq_of_parse_and_map(child, 0);
-		if (irq != NO_IRQ) {
-			const u32 *id = of_get_property(child, "reg", NULL);
-			if (id)
-				bus->irq[*id] = irq;
-		}
-	}
+	bus->irq = priv->mdio_irqs;
 
 	/* setup registers */
 	err = of_address_to_resource(np, 0, &res);
@@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
 	out_be32(&priv->regs->mii_speed,
 		((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
 
-	err = mdiobus_register(bus);
+	err = of_mdiobus_register(bus, np);
 	if (err)
 		goto out_unmap;
 


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
                   ` (3 preceding siblings ...)
  2009-03-19  5:00 ` [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:07     ` Grant Likely
  2009-03-19  5:00 ` [PATCH 7/9] net/ucc_geth: Rework ucc_geth " Grant Likely
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

This patch simplifies the driver by making use of more common code.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/net/gianfar.c     |   94 ++++++++++++++-------------------------------
 drivers/net/gianfar.h     |    3 +
 drivers/net/gianfar_mii.c |   52 +------------------------
 3 files changed, 34 insertions(+), 115 deletions(-)


diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 9831b3f..0521267 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -75,6 +75,7 @@
 #include <linux/if_vlan.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -155,17 +156,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
 
 static int gfar_of_init(struct net_device *dev)
 {
-	struct device_node *phy, *mdio;
-	const unsigned int *id;
 	const char *model;
 	const char *ctype;
 	const void *mac_addr;
-	const phandle *ph;
 	u64 addr, size;
 	int err = 0;
 	struct gfar_private *priv = netdev_priv(dev);
 	struct device_node *np = priv->node;
-	char bus_name[MII_BUS_ID_SIZE];
 
 	if (!np || !of_device_is_available(np))
 		return -ENODEV;
@@ -228,8 +225,8 @@ static int gfar_of_init(struct net_device *dev)
 	if (of_get_property(np, "fsl,magic-packet", NULL))
 		priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
 
-	ph = of_get_property(np, "phy-handle", NULL);
-	if (ph == NULL) {
+	priv->phy_node = of_parse_phandle(np, "phy-device", 0);
+	if (!priv->phy_node) {
 		u32 *fixed_link;
 
 		fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
@@ -237,57 +234,10 @@ static int gfar_of_init(struct net_device *dev)
 			err = -ENODEV;
 			goto err_out;
 		}
-
-		snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id),
-				PHY_ID_FMT, "0", fixed_link[0]);
-	} else {
-		phy = of_find_node_by_phandle(*ph);
-
-		if (phy == NULL) {
-			err = -ENODEV;
-			goto err_out;
-		}
-
-		mdio = of_get_parent(phy);
-
-		id = of_get_property(phy, "reg", NULL);
-
-		of_node_put(phy);
-		of_node_put(mdio);
-
-		gfar_mdio_bus_name(bus_name, mdio);
-		snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
-				bus_name, *id);
 	}
 
 	/* Find the TBI PHY.  If it's not there, we don't support SGMII */
-	ph = of_get_property(np, "tbi-handle", NULL);
-	if (ph) {
-		struct device_node *tbi = of_find_node_by_phandle(*ph);
-		struct of_device *ofdev;
-		struct mii_bus *bus;
-
-		if (!tbi)
-			return 0;
-
-		mdio = of_get_parent(tbi);
-		if (!mdio)
-			return 0;
-
-		ofdev = of_find_device_by_node(mdio);
-
-		of_node_put(mdio);
-
-		id = of_get_property(tbi, "reg", NULL);
-		if (!id)
-			return 0;
-
-		of_node_put(tbi);
-
-		bus = dev_get_drvdata(&ofdev->dev);
-
-		priv->tbiphy = bus->phy_map[*id];
-	}
+	priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
 
 	return 0;
 
@@ -661,7 +611,6 @@ static int init_phy(struct net_device *dev)
 	uint gigabit_support =
 		priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
 		SUPPORTED_1000baseT_Full : 0;
-	struct phy_device *phydev;
 	phy_interface_t interface;
 
 	priv->oldlink = 0;
@@ -670,23 +619,38 @@ static int init_phy(struct net_device *dev)
 
 	interface = gfar_get_interface(dev);
 
-	phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface);
+	if (priv->phy_node) {
+		priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link,
+					      0, interface);
+		if (!priv->phydev) {
+			dev_err(&dev->dev, "error: Could not attach to PHY\n");
+			return -ENODEV;
+		}
+	}
+
+	if (priv->tbi_node) {
+		priv->tbiphy = of_phy_connect(dev, priv->tbi_node, &adjust_link,
+					      0, interface);
+		if (!priv->tbiphy) {
+			dev_err(&dev->dev, "error: Could not attach to TBI\n");
+			goto err_tbiphy;
+		}
+	}
 
 	if (interface == PHY_INTERFACE_MODE_SGMII)
 		gfar_configure_serdes(dev);
 
-	if (IS_ERR(phydev)) {
-		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
-		return PTR_ERR(phydev);
-	}
-
 	/* Remove any features not supported by the controller */
-	phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
-	phydev->advertising = phydev->supported;
-
-	priv->phydev = phydev;
+	priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+	priv->phydev->advertising = priv->phydev->supported;
 
 	return 0;
+
+ err_tbiphy:
+	if (priv->phy_node)
+		phy_disconnect(priv->phydev);
+	priv->phydev = NULL;
+	return -ENODEV;
 }
 
 /*
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index eaa8689..d3d56a9 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -775,7 +775,8 @@ struct gfar_private {
 	spinlock_t bflock;
 
 	phy_interface_t interface;
-	char	phy_bus_id[BUS_ID_SIZE];
+	struct device_node *phy_node;
+	struct device_node *tbi_node;
 	u32 device_flags;
 	unsigned char rx_csum_enable:1,
 		extended_hash:1,
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index f49a426..c6d77bd 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -35,6 +35,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <asm/io.h>
@@ -152,45 +153,6 @@ static int gfar_mdio_reset(struct mii_bus *bus)
 	return 0;
 }
 
-/* Allocate an array which provides irq #s for each PHY on the given bus */
-static int *create_irq_map(struct device_node *np)
-{
-	int *irqs;
-	int i;
-	struct device_node *child = NULL;
-
-	irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
-
-	if (!irqs)
-		return NULL;
-
-	for (i = 0; i < PHY_MAX_ADDR; i++)
-		irqs[i] = PHY_POLL;
-
-	while ((child = of_get_next_child(np, child)) != NULL) {
-		int irq = irq_of_parse_and_map(child, 0);
-		const u32 *id;
-
-		if (irq == NO_IRQ)
-			continue;
-
-		id = of_get_property(child, "reg", NULL);
-
-		if (!id)
-			continue;
-
-		if (*id < PHY_MAX_ADDR && *id >= 0)
-			irqs[*id] = irq;
-		else
-			printk(KERN_WARNING "%s: "
-					"%d is not a valid PHY address\n",
-					np->full_name, *id);
-	}
-
-	return irqs;
-}
-
-
 void gfar_mdio_bus_name(char *name, struct device_node *np)
 {
 	const u32 *reg;
@@ -253,7 +215,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
 
 	new_bus->priv = (void __force *)regs;
 
-	new_bus->irq = create_irq_map(np);
+	new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
 
 	if (new_bus->irq == NULL) {
 		err = -ENOMEM;
@@ -301,15 +263,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
 
 	gfar_write(&enet_regs->tbipa, tbiaddr);
 
-	/*
-	 * The TBIPHY-only buses will find PHYs at every address,
-	 * so we mask them all but the TBI
-	 */
-	if (!of_device_is_compatible(np, "fsl,gianfar-mdio"))
-		new_bus->phy_mask = ~(1 << tbiaddr);
-
-	err = mdiobus_register(new_bus);
-
+	err = of_mdiobus_register(new_bus, np);
 	if (err != 0) {
 		printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
 				new_bus->name);


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 7/9] net/ucc_geth: Rework ucc_geth driver to use OF PHY/MDIO helper functions
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
                   ` (4 preceding siblings ...)
  2009-03-19  5:00 ` [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:07     ` Grant Likely
  2009-03-19  5:00 ` [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure Grant Likely
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

This patch simplifies the driver by making use of more common code.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/net/ucc_geth.c     |   27 ++++++---------------------
 drivers/net/ucc_geth_mii.c |   17 +++--------------
 2 files changed, 9 insertions(+), 35 deletions(-)


diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index e879868..45bb627 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -28,6 +28,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/workqueue.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <asm/uaccess.h>
@@ -1537,35 +1538,19 @@ static int init_phy(struct net_device *dev)
 {
 	struct ucc_geth_private *priv = netdev_priv(dev);
 	struct device_node *np = priv->node;
-	struct device_node *phy, *mdio;
-	const phandle *ph;
-	char bus_name[MII_BUS_ID_SIZE];
-	const unsigned int *id;
+	struct device_node *phy;
 	struct phy_device *phydev;
-	char phy_id[BUS_ID_SIZE];
 
 	priv->oldlink = 0;
 	priv->oldspeed = 0;
 	priv->oldduplex = -1;
 
-	ph = of_get_property(np, "phy-handle", NULL);
-	phy = of_find_node_by_phandle(*ph);
-	mdio = of_get_parent(phy);
-
-	id = of_get_property(phy, "reg", NULL);
-
+	phy = of_parse_phandle(np, "phy-handle", 0);
+	phydev = of_phy_connect(dev, phy, &adjust_link, 0, priv->phy_interface);
 	of_node_put(phy);
-	of_node_put(mdio);
-
-	uec_mdio_bus_name(bus_name, mdio);
-	snprintf(phy_id, sizeof(phy_id), "%s:%02x",
-                                bus_name, *id);
-
-	phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
-
-	if (IS_ERR(phydev)) {
+	if (!phydev) {
 		printk("%s: Could not attach to PHY\n", dev->name);
-		return PTR_ERR(phydev);
+		return -ENODEV;
 	}
 
 	phydev->supported &= (ADVERTISED_10baseT_Half |
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 0ada4ed..9f2492f 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -36,6 +36,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/fsl_devices.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <asm/io.h>
@@ -135,11 +136,10 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
 {
 	struct device *device = &ofdev->dev;
 	struct device_node *np = ofdev->node, *tempnp = NULL;
-	struct device_node *child = NULL;
 	struct ucc_mii_mng __iomem *regs;
 	struct mii_bus *new_bus;
 	struct resource res;
-	int k, err = 0;
+	int err = 0;
 
 	new_bus = mdiobus_alloc();
 	if (NULL == new_bus)
@@ -165,17 +165,6 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
 		goto reg_map_fail;
 	}
 
-	for (k = 0; k < 32; k++)
-		new_bus->irq[k] = PHY_POLL;
-
-	while ((child = of_get_next_child(np, child)) != NULL) {
-		int irq = irq_of_parse_and_map(child, 0);
-		if (irq != NO_IRQ) {
-			const u32 *id = of_get_property(child, "reg", NULL);
-			new_bus->irq[*id] = irq;
-		}
-	}
-
 	/* Set the base address */
 	regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
 
@@ -220,7 +209,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
 		}
 	}
 
-	err = mdiobus_register(new_bus);
+	err = of_mdiobus_register(new_bus, np);
 	if (0 != err) {
 		printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
 		       new_bus->name);


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
                   ` (5 preceding siblings ...)
  2009-03-19  5:00 ` [PATCH 7/9] net/ucc_geth: Rework ucc_geth " Grant Likely
@ 2009-03-19  5:00 ` Grant Likely
  2009-03-19  5:07     ` Grant Likely
  2009-03-19  5:01 ` [PATCH 9/9] net/fs_enet: Rework fs_enet " Grant Likely
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:00 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

This patch simplifies the driver by making use of more common code.
    
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/net/pasemi_mac.c |   19 +++----------------
 drivers/net/pasemi_mac.h |    1 -
 2 files changed, 3 insertions(+), 17 deletions(-)


diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index d0349e7..8c92d1f 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -1086,34 +1086,21 @@ static int pasemi_mac_phy_init(struct net_device *dev)
 	struct pasemi_mac *mac = netdev_priv(dev);
 	struct device_node *dn, *phy_dn;
 	struct phy_device *phydev;
-	unsigned int phy_id;
 	const phandle *ph;
 	const unsigned int *prop;
 	struct resource r;
 	int ret;
 
 	dn = pci_device_to_OF_node(mac->pdev);
-	ph = of_get_property(dn, "phy-handle", NULL);
-	if (!ph)
-		return -ENODEV;
-	phy_dn = of_find_node_by_phandle(*ph);
-
-	prop = of_get_property(phy_dn, "reg", NULL);
-	ret = of_address_to_resource(phy_dn->parent, 0, &r);
-	if (ret)
-		goto err;
-
-	phy_id = *prop;
-	snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
-		 (int)r.start, phy_id);
-
+	phy_dn = of_parse_phandle(dn, "phy-handle", 0);
 	of_node_put(phy_dn);
 
 	mac->link = 0;
 	mac->speed = 0;
 	mac->duplex = -1;
 
-	phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+	phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
+				PHY_INTERFACE_MODE_SGMII);
 
 	if (IS_ERR(phydev)) {
 		printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index 1a115ec..e2f4efa 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -100,7 +100,6 @@ struct pasemi_mac {
 	int	duplex;
 
 	unsigned int	msg_enable;
-	char	phy_id[BUS_ID_SIZE];
 };
 
 /* Software status descriptor (ring_info) */


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
                   ` (6 preceding siblings ...)
  2009-03-19  5:00 ` [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure Grant Likely
@ 2009-03-19  5:01 ` Grant Likely
  2009-03-19  5:07     ` Grant Likely
  2009-03-19  5:05   ` Grant Likely
  2009-03-19  5:07   ` Michael Ellerman
  9 siblings, 1 reply; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:01 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

From: Grant Likely <grant.likely@secretlab.ca>

This patch simplifies the driver by making use of more common code.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 drivers/net/fs_enet/fs_enet-main.c |   66 +++++-------------------------------
 drivers/net/fs_enet/mii-bitbang.c  |   29 +---------------
 drivers/net/fs_enet/mii-fec.c      |   26 +-------------
 include/linux/fs_enet_pd.h         |    6 +--
 4 files changed, 14 insertions(+), 113 deletions(-)


diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index ce900e5..e039d6a 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -36,6 +36,8 @@
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 
@@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev)
 	fep->oldlink = 0;
 	fep->oldspeed = 0;
 	fep->oldduplex = -1;
-	if(fep->fpi->bus_id)
-		phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0,
-				PHY_INTERFACE_MODE_MII);
+	if(fep->fpi->phy_node)
+		phydev = of_phy_connect(dev, fep->fpi->phy_node,
+					&fs_adjust_link, 0,
+					PHY_INTERFACE_MODE_MII);
 	else {
 		printk("No phy bus ID specified in BSP code\n");
 		return -EINVAL;
@@ -962,57 +965,6 @@ static void cleanup_immap(void)
 
 /**************************************************************************************/
 
-static int __devinit find_phy(struct device_node *np,
-                              struct fs_platform_info *fpi)
-{
-	struct device_node *phynode, *mdionode;
-	int ret = 0, len, bus_id;
-	const u32 *data;
-
-	data  = of_get_property(np, "fixed-link", NULL);
-	if (data) {
-		snprintf(fpi->bus_id, 16, "%x:%02x", 0, *data);
-		return 0;
-	}
-
-	data = of_get_property(np, "phy-handle", &len);
-	if (!data || len != 4)
-		return -EINVAL;
-
-	phynode = of_find_node_by_phandle(*data);
-	if (!phynode)
-		return -EINVAL;
-
-	data = of_get_property(phynode, "reg", &len);
-	if (!data || len != 4) {
-		ret = -EINVAL;
-		goto out_put_phy;
-	}
-
-	mdionode = of_get_parent(phynode);
-	if (!mdionode) {
-		ret = -EINVAL;
-		goto out_put_phy;
-	}
-
-	bus_id = of_get_gpio(mdionode, 0);
-	if (bus_id < 0) {
-		struct resource res;
-		ret = of_address_to_resource(mdionode, 0, &res);
-		if (ret)
-			goto out_put_mdio;
-		bus_id = res.start;
-	}
-
-	snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
-
-out_put_mdio:
-	of_node_put(mdionode);
-out_put_phy:
-	of_node_put(phynode);
-	return ret;
-}
-
 #ifdef CONFIG_FS_ENET_HAS_FEC
 #define IS_FEC(match) ((match)->data == &fs_fec_ops)
 #else
@@ -1046,9 +998,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
 	fpi->rx_copybreak = 240;
 	fpi->use_napi = 1;
 	fpi->napi_weight = 17;
-
-	ret = find_phy(ofdev->node, fpi);
-	if (ret)
+	fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0);
+	if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link",
+						  NULL)))
 		goto out_free_fpi;
 
 	privsize = sizeof(*fep) +
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 49b6645..93b481b 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -22,6 +22,7 @@
 #include <linux/mii.h>
 #include <linux/platform_device.h>
 #include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include "fs_enet.h"
@@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
 	return 0;
 }
 
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
-	const u32 *data;
-	int len, id, irq;
-
-	data = of_get_property(np, "reg", &len);
-	if (!data || len != 4)
-		return;
-
-	id = *data;
-	bus->phy_mask &= ~(1 << id);
-
-	irq = of_irq_to_resource(np, 0, NULL);
-	if (irq != NO_IRQ)
-		bus->irq[id] = irq;
-}
-
 static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
                                         const struct of_device_id *match)
 {
-	struct device_node *np = NULL;
 	struct mii_bus *new_bus;
 	struct bb_info *bitbang;
 	int ret = -ENOMEM;
-	int i;
 
 	bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
 	if (!bitbang)
@@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 	if (!new_bus->irq)
 		goto out_unmap_regs;
 
-	for (i = 0; i < PHY_MAX_ADDR; i++)
-		new_bus->irq[i] = -1;
-
-	while ((np = of_get_next_child(ofdev->node, np)))
-		if (!strcmp(np->type, "ethernet-phy"))
-			add_phy(new_bus, np);
-
 	new_bus->parent = &ofdev->dev;
 	dev_set_drvdata(&ofdev->dev, new_bus);
 
-	ret = mdiobus_register(new_bus);
+	ret = of_mdiobus_register(new_bus, ofdev->node);
 	if (ret)
 		goto out_free_irqs;
 
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 28077cc..bdc3160 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -102,23 +102,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
 	return 0;
 }
 
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
-	const u32 *data;
-	int len, id, irq;
-
-	data = of_get_property(np, "reg", &len);
-	if (!data || len != 4)
-		return;
-
-	id = *data;
-	bus->phy_mask &= ~(1 << id);
-
-	irq = of_irq_to_resource(np, 0, NULL);
-	if (irq != NO_IRQ)
-		bus->irq[id] = irq;
-}
-
 static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
                                         const struct of_device_id *match)
 {
@@ -165,17 +148,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 	if (!new_bus->irq)
 		goto out_unmap_regs;
 
-	for (i = 0; i < PHY_MAX_ADDR; i++)
-		new_bus->irq[i] = -1;
-
-	while ((np = of_get_next_child(ofdev->node, np)))
-		if (!strcmp(np->type, "ethernet-phy"))
-			add_phy(new_bus, np);
-
 	new_bus->parent = &ofdev->dev;
 	dev_set_drvdata(&ofdev->dev, new_bus);
 
-	ret = mdiobus_register(new_bus);
+	ret = of_mdiobus_register(new_bus, ofdev->node);
 	if (ret)
 		goto out_free_irqs;
 
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 8300cab..51b7934 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -17,6 +17,7 @@
 #define FS_ENET_PD_H
 
 #include <linux/string.h>
+#include <linux/of_mdio.h>
 #include <asm/types.h>
 
 #define FS_ENET_NAME	"fs_enet"
@@ -130,10 +131,7 @@ struct fs_platform_info {
 	
 	u32 device_flags;
 
-	int phy_addr;		/* the phy address (-1 no phy) */
-	char bus_id[16];
-	int phy_irq;		/* the phy irq (if it exists)  */
-
+	struct device_node *phy_node;
 	const struct fs_mii_bus_info *bus_info;
 
 	int rx_ring, tx_ring;	/* number of buffers on rx     */


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
@ 2009-03-19  5:05   ` Grant Likely
  2009-03-19  5:00 ` [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions Grant Likely
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:05 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

Bah!  Messed up the 'stg mail' command when sending this series and
the 'RFC' tag didn't get added.

This is firmly in the RFC category.  Please don't apply.  It doesn't
have the level of polish that I'm happy with.

This series is intended to make phy_device connecting simpler and more
robust by using the PHY's device_node as the search key when
connecting to PHY.  Changes are made to both the MDIO busses to
extract the PHY data out of the device tree, and to the drivers to use
a common helper function for finding the PHY it is interested in.

Comments please.
g.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> of_parse_phandle() is a helper function to read and parse a phandle
> property and return a pointer to the resulting device_node.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/of/base.c  |   23 +++++++++++++++++++++++
>  include/linux/of.h |    3 +++
>  2 files changed, 26 insertions(+), 0 deletions(-)
>
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index cd17092..1eaada4 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -494,6 +494,29 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
>  EXPORT_SYMBOL_GPL(of_modalias_node);
>
>  /**
> + * of_parse_phandle - Resolve a phandle property to a device_node pointer
> + * @np: Pointer to device node holding phandle property
> + * @phandle_name: Name of property holding a phandle value
> + * @index: For properties holding a table of phandles, this is the index into
> + *         the table
> + *
> + * Returns the device_node pointer pointed to by the phandle, or NULL
> + */
> +struct device_node *
> +of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
> +{
> +       const phandle *phandle;
> +       int size;
> +
> +       phandle = of_get_property(np, phandle_name, &size);
> +       if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
> +               return NULL;
> +
> +       return of_find_node_by_phandle(phandle[index]);
> +}
> +EXPORT_SYMBOL(of_parse_phandle);
> +
> +/**
>  * of_parse_phandles_with_args - Find a node pointed by phandle in a list
>  * @np:                pointer to a device tree node containing a list
>  * @list_name: property name that contains a list
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 6a7efa2..7be2d10 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -77,6 +77,9 @@ extern int of_n_size_cells(struct device_node *np);
>  extern const struct of_device_id *of_match_node(
>        const struct of_device_id *matches, const struct device_node *node);
>  extern int of_modalias_node(struct device_node *node, char *modalias, int len);
> +extern struct device_node *of_parse_phandle(struct device_node *np,
> +                                           const char *phandle_name,
> +                                           int index);
>  extern int of_parse_phandles_with_args(struct device_node *np,
>        const char *list_name, const char *cells_name, int index,
>        struct device_node **out_node, const void **out_args);
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties
@ 2009-03-19  5:05   ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:05 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

Bah!  Messed up the 'stg mail' command when sending this series and
the 'RFC' tag didn't get added.

This is firmly in the RFC category.  Please don't apply.  It doesn't
have the level of polish that I'm happy with.

This series is intended to make phy_device connecting simpler and more
robust by using the PHY's device_node as the search key when
connecting to PHY.  Changes are made to both the MDIO busses to
extract the PHY data out of the device tree, and to the drivers to use
a common helper function for finding the PHY it is interested in.

Comments please.
g.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> of_parse_phandle() is a helper function to read and parse a phandle
> property and return a pointer to the resulting device_node.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/of/base.c =A0| =A0 23 +++++++++++++++++++++++
> =A0include/linux/of.h | =A0 =A03 +++
> =A02 files changed, 26 insertions(+), 0 deletions(-)
>
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index cd17092..1eaada4 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -494,6 +494,29 @@ int of_modalias_node(struct device_node *node, char =
*modalias, int len)
> =A0EXPORT_SYMBOL_GPL(of_modalias_node);
>
> =A0/**
> + * of_parse_phandle - Resolve a phandle property to a device_node pointe=
r
> + * @np: Pointer to device node holding phandle property
> + * @phandle_name: Name of property holding a phandle value
> + * @index: For properties holding a table of phandles, this is the index=
 into
> + * =A0 =A0 =A0 =A0 the table
> + *
> + * Returns the device_node pointer pointed to by the phandle, or NULL
> + */
> +struct device_node *
> +of_parse_phandle(struct device_node *np, const char *phandle_name, int i=
ndex)
> +{
> + =A0 =A0 =A0 const phandle *phandle;
> + =A0 =A0 =A0 int size;
> +
> + =A0 =A0 =A0 phandle =3D of_get_property(np, phandle_name, &size);
> + =A0 =A0 =A0 if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
> +
> + =A0 =A0 =A0 return of_find_node_by_phandle(phandle[index]);
> +}
> +EXPORT_SYMBOL(of_parse_phandle);
> +
> +/**
> =A0* of_parse_phandles_with_args - Find a node pointed by phandle in a li=
st
> =A0* @np: =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pointer to a device tree node co=
ntaining a list
> =A0* @list_name: property name that contains a list
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 6a7efa2..7be2d10 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -77,6 +77,9 @@ extern int of_n_size_cells(struct device_node *np);
> =A0extern const struct of_device_id *of_match_node(
> =A0 =A0 =A0 =A0const struct of_device_id *matches, const struct device_no=
de *node);
> =A0extern int of_modalias_node(struct device_node *node, char *modalias, =
int len);
> +extern struct device_node *of_parse_phandle(struct device_node *np,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 const char *phandle_name,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 int index);
> =A0extern int of_parse_phandles_with_args(struct device_node *np,
> =A0 =A0 =A0 =A0const char *list_name, const char *cells_name, int index,
> =A0 =A0 =A0 =A0struct device_node **out_node, const void **out_args);
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs
  2009-03-19  5:00 ` [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs Grant Likely
@ 2009-03-19  5:05     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:05 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch makes changes in preparation for supporting open firmware
> device tree descriptions of MDIO busses.  Changes include:
> - Cleanup handling of phy_map[] entries; they are already NULLed when
>  registering and so don't need to be re-cleared, and it is good practice
>  to clear them out when unregistering.
> - Split phy_device registration out into a new function so that the
>  OF helpers can do two stage registration (separate allocation and
>  registration steps).
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: linuxppc-dev@ozlabs.org
> CC: netdev@vger.kernel.org
> CC: Andy Fleming <afleming@freescale.com>
> ---
>
>  drivers/net/phy/mdio_bus.c   |   29 +++-------------------------
>  drivers/net/phy/phy_device.c |   43 ++++++++++++++++++++++++++++++++++++++----
>  include/linux/phy.h          |    1 +
>  3 files changed, 43 insertions(+), 30 deletions(-)
>
>
> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
> index 811a637..3c39c7b 100644
> --- a/drivers/net/phy/mdio_bus.c
> +++ b/drivers/net/phy/mdio_bus.c
> @@ -112,7 +112,6 @@ int mdiobus_register(struct mii_bus *bus)
>                bus->reset(bus);
>
>        for (i = 0; i < PHY_MAX_ADDR; i++) {
> -               bus->phy_map[i] = NULL;
>                if ((bus->phy_mask & (1 << i)) == 0) {
>                        struct phy_device *phydev;
>
> @@ -149,6 +148,7 @@ void mdiobus_unregister(struct mii_bus *bus)
>        for (i = 0; i < PHY_MAX_ADDR; i++) {
>                if (bus->phy_map[i])
>                        device_unregister(&bus->phy_map[i]->dev);
> +               bus->phy_map[i] = NULL;
>        }
>  }
>  EXPORT_SYMBOL(mdiobus_unregister);
> @@ -187,35 +187,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
>        if (IS_ERR(phydev) || phydev == NULL)
>                return phydev;
>
> -       /* There's a PHY at this address
> -        * We need to set:
> -        * 1) IRQ
> -        * 2) bus_id
> -        * 3) parent
> -        * 4) bus
> -        * 5) mii_bus
> -        * And, we need to register it */
> -
> -       phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
> -
> -       phydev->dev.parent = bus->parent;
> -       phydev->dev.bus = &mdio_bus_type;
> -       dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
> -
> -       phydev->bus = bus;
> -
> -       /* Run all of the fixups for this PHY */
> -       phy_scan_fixups(phydev);
> -
> -       err = device_register(&phydev->dev);
> +       err = phy_device_register(phydev);
>        if (err) {
> -               printk(KERN_ERR "phy %d failed to register\n", addr);
>                phy_device_free(phydev);
> -               phydev = NULL;
> +               return NULL;
>        }
>
> -       bus->phy_map[addr] = phydev;
> -
>        return phydev;
>  }
>  EXPORT_SYMBOL(mdiobus_scan);
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 0a06e4f..793332f 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -39,10 +39,6 @@ MODULE_DESCRIPTION("PHY library");
>  MODULE_AUTHOR("Andy Fleming");
>  MODULE_LICENSE("GPL");
>
> -static struct phy_driver genphy_driver;
> -extern int mdio_bus_init(void);
> -extern void mdio_bus_exit(void);
> -
>  void phy_device_free(struct phy_device *phydev)
>  {
>        kfree(phydev);
> @@ -53,6 +49,10 @@ static void phy_device_release(struct device *dev)
>        phy_device_free(to_phy_device(dev));
>  }
>
> +static struct phy_driver genphy_driver;
> +extern int mdio_bus_init(void);
> +extern void mdio_bus_exit(void);
> +
>  static LIST_HEAD(phy_fixup_list);
>  static DEFINE_MUTEX(phy_fixup_lock);
>
> @@ -166,6 +166,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
>        dev->addr = addr;
>        dev->phy_id = phy_id;
>        dev->bus = bus;
> +       dev->dev.parent = bus->parent;
> +       dev->dev.bus = &mdio_bus_type;
> +       dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
> +       dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
>
>        dev->state = PHY_DOWN;
>
> @@ -237,6 +241,37 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
>  }
>
>  /**
> + * phy_device_register - Register the phy device on the MDIO bus
> + * @phy_device: phy_device structure to be added to the MDIO bus
> + */
> +int phy_device_register(struct phy_device *phydev)
> +{
> +       int err;
> +
> +       /* Don't register a phy if one is already registered at this
> +        * address */
> +       if (phydev->bus->phy_map[phydev->addr])
> +               return -EINVAL;
> +       phydev->bus->phy_map[phydev->addr] = phydev;
> +
> +       /* Run all of the fixups for this PHY */
> +       phy_scan_fixups(phydev);
> +
> +       err = device_register(&phydev->dev);
> +       if (err) {
> +               pr_err("phy %d failed to register\n", phydev->addr);
> +               goto out;
> +       }
> +
> +       return 0;
> +
> + out:
> +       phydev->bus->phy_map[phydev->addr] = NULL;
> +       return err;
> +}
> +EXPORT_SYMBOL(phy_device_register);
> +
> +/**
>  * phy_prepare_link - prepares the PHY layer to monitor link status
>  * @phydev: target phy_device struct
>  * @handler: callback function for link status change notifications
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index d7e54d9..a47d64f 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -439,6 +439,7 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
>
>  int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
>  struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
> +int phy_device_register(struct phy_device *phy);
>  int phy_clear_interrupt(struct phy_device *phydev);
>  int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
>  struct phy_device * phy_attach(struct net_device *dev,
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs
@ 2009-03-19  5:05     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:05 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch makes changes in preparation for supporting open firmware
> device tree descriptions of MDIO busses. =A0Changes include:
> - Cleanup handling of phy_map[] entries; they are already NULLed when
> =A0registering and so don't need to be re-cleared, and it is good practic=
e
> =A0to clear them out when unregistering.
> - Split phy_device registration out into a new function so that the
> =A0OF helpers can do two stage registration (separate allocation and
> =A0registration steps).
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: linuxppc-dev@ozlabs.org
> CC: netdev@vger.kernel.org
> CC: Andy Fleming <afleming@freescale.com>
> ---
>
> =A0drivers/net/phy/mdio_bus.c =A0 | =A0 29 +++-------------------------
> =A0drivers/net/phy/phy_device.c | =A0 43 ++++++++++++++++++++++++++++++++=
++++++----
> =A0include/linux/phy.h =A0 =A0 =A0 =A0 =A0| =A0 =A01 +
> =A03 files changed, 43 insertions(+), 30 deletions(-)
>
>
> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
> index 811a637..3c39c7b 100644
> --- a/drivers/net/phy/mdio_bus.c
> +++ b/drivers/net/phy/mdio_bus.c
> @@ -112,7 +112,6 @@ int mdiobus_register(struct mii_bus *bus)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bus->reset(bus);
>
> =A0 =A0 =A0 =A0for (i =3D 0; i < PHY_MAX_ADDR; i++) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus->phy_map[i] =3D NULL;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if ((bus->phy_mask & (1 << i)) =3D=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct phy_device *phydev;
>
> @@ -149,6 +148,7 @@ void mdiobus_unregister(struct mii_bus *bus)
> =A0 =A0 =A0 =A0for (i =3D 0; i < PHY_MAX_ADDR; i++) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (bus->phy_map[i])
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0device_unregister(&bus->ph=
y_map[i]->dev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus->phy_map[i] =3D NULL;
> =A0 =A0 =A0 =A0}
> =A0}
> =A0EXPORT_SYMBOL(mdiobus_unregister);
> @@ -187,35 +187,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus=
, int addr)
> =A0 =A0 =A0 =A0if (IS_ERR(phydev) || phydev =3D=3D NULL)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return phydev;
>
> - =A0 =A0 =A0 /* There's a PHY at this address
> - =A0 =A0 =A0 =A0* We need to set:
> - =A0 =A0 =A0 =A0* 1) IRQ
> - =A0 =A0 =A0 =A0* 2) bus_id
> - =A0 =A0 =A0 =A0* 3) parent
> - =A0 =A0 =A0 =A0* 4) bus
> - =A0 =A0 =A0 =A0* 5) mii_bus
> - =A0 =A0 =A0 =A0* And, we need to register it */
> -
> - =A0 =A0 =A0 phydev->irq =3D bus->irq !=3D NULL ? bus->irq[addr] : PHY_P=
OLL;
> -
> - =A0 =A0 =A0 phydev->dev.parent =3D bus->parent;
> - =A0 =A0 =A0 phydev->dev.bus =3D &mdio_bus_type;
> - =A0 =A0 =A0 dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
> -
> - =A0 =A0 =A0 phydev->bus =3D bus;
> -
> - =A0 =A0 =A0 /* Run all of the fixups for this PHY */
> - =A0 =A0 =A0 phy_scan_fixups(phydev);
> -
> - =A0 =A0 =A0 err =3D device_register(&phydev->dev);
> + =A0 =A0 =A0 err =3D phy_device_register(phydev);
> =A0 =A0 =A0 =A0if (err) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "phy %d failed to register\=
n", addr);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0phy_device_free(phydev);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 phydev =3D NULL;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 bus->phy_map[addr] =3D phydev;
> -
> =A0 =A0 =A0 =A0return phydev;
> =A0}
> =A0EXPORT_SYMBOL(mdiobus_scan);
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 0a06e4f..793332f 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -39,10 +39,6 @@ MODULE_DESCRIPTION("PHY library");
> =A0MODULE_AUTHOR("Andy Fleming");
> =A0MODULE_LICENSE("GPL");
>
> -static struct phy_driver genphy_driver;
> -extern int mdio_bus_init(void);
> -extern void mdio_bus_exit(void);
> -
> =A0void phy_device_free(struct phy_device *phydev)
> =A0{
> =A0 =A0 =A0 =A0kfree(phydev);
> @@ -53,6 +49,10 @@ static void phy_device_release(struct device *dev)
> =A0 =A0 =A0 =A0phy_device_free(to_phy_device(dev));
> =A0}
>
> +static struct phy_driver genphy_driver;
> +extern int mdio_bus_init(void);
> +extern void mdio_bus_exit(void);
> +
> =A0static LIST_HEAD(phy_fixup_list);
> =A0static DEFINE_MUTEX(phy_fixup_lock);
>
> @@ -166,6 +166,10 @@ struct phy_device* phy_device_create(struct mii_bus =
*bus, int addr, int phy_id)
> =A0 =A0 =A0 =A0dev->addr =3D addr;
> =A0 =A0 =A0 =A0dev->phy_id =3D phy_id;
> =A0 =A0 =A0 =A0dev->bus =3D bus;
> + =A0 =A0 =A0 dev->dev.parent =3D bus->parent;
> + =A0 =A0 =A0 dev->dev.bus =3D &mdio_bus_type;
> + =A0 =A0 =A0 dev->irq =3D bus->irq !=3D NULL ? bus->irq[addr] : PHY_POLL=
;
> + =A0 =A0 =A0 dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
>
> =A0 =A0 =A0 =A0dev->state =3D PHY_DOWN;
>
> @@ -237,6 +241,37 @@ struct phy_device * get_phy_device(struct mii_bus *b=
us, int addr)
> =A0}
>
> =A0/**
> + * phy_device_register - Register the phy device on the MDIO bus
> + * @phy_device: phy_device structure to be added to the MDIO bus
> + */
> +int phy_device_register(struct phy_device *phydev)
> +{
> + =A0 =A0 =A0 int err;
> +
> + =A0 =A0 =A0 /* Don't register a phy if one is already registered at thi=
s
> + =A0 =A0 =A0 =A0* address */
> + =A0 =A0 =A0 if (phydev->bus->phy_map[phydev->addr])
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EINVAL;
> + =A0 =A0 =A0 phydev->bus->phy_map[phydev->addr] =3D phydev;
> +
> + =A0 =A0 =A0 /* Run all of the fixups for this PHY */
> + =A0 =A0 =A0 phy_scan_fixups(phydev);
> +
> + =A0 =A0 =A0 err =3D device_register(&phydev->dev);
> + =A0 =A0 =A0 if (err) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pr_err("phy %d failed to register\n", phyde=
v->addr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 return 0;
> +
> + out:
> + =A0 =A0 =A0 phydev->bus->phy_map[phydev->addr] =3D NULL;
> + =A0 =A0 =A0 return err;
> +}
> +EXPORT_SYMBOL(phy_device_register);
> +
> +/**
> =A0* phy_prepare_link - prepares the PHY layer to monitor link status
> =A0* @phydev: target phy_device struct
> =A0* @handler: callback function for link status change notifications
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index d7e54d9..a47d64f 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -439,6 +439,7 @@ static inline int phy_write(struct phy_device *phydev=
, u16 regnum, u16 val)
>
> =A0int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
> =A0struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
> +int phy_device_register(struct phy_device *phy);
> =A0int phy_clear_interrupt(struct phy_device *phydev);
> =A0int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
> =A0struct phy_device * phy_attach(struct net_device *dev,
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions
  2009-03-19  5:00 ` [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions Grant Likely
@ 2009-03-19  5:05     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:05 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Add phy_connect_direct() and phy_attach_direct() functions so that
> drivers can use a pointer to the phy_device instead of trying to determine
> the phy's bus_id string.
>
> This patch is useful for OF device tree descriptions of phy devices where
> the driver doesn't need or know what the bus_id value in order to get a
> phy_device pointer.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/net/phy/phy_device.c |  118 ++++++++++++++++++++++++++++++------------
>  include/linux/phy.h          |    5 ++
>  2 files changed, 90 insertions(+), 33 deletions(-)
>
>
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 793332f..238d21e 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -290,6 +290,33 @@ void phy_prepare_link(struct phy_device *phydev,
>  }
>
>  /**
> + * phy_connect_direct - connect an ethernet device to a specific phy_device
> + * @dev: the network device to connect
> + * @phydev: the pointer to the phy device
> + * @handler: callback function for state change notifications
> + * @flags: PHY device's dev_flags
> + * @interface: PHY device's interface
> + */
> +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
> +                      void (*handler)(struct net_device *), u32 flags,
> +                      phy_interface_t interface)
> +{
> +       int rc;
> +
> +       rc = phy_attach_direct(dev, phydev, flags, interface);
> +       if (rc)
> +               return rc;
> +
> +       phy_prepare_link(phydev, handler);
> +       phy_start_machine(phydev, NULL);
> +       if (phydev->irq > 0)
> +               phy_start_interrupts(phydev);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(phy_connect_direct);
> +
> +/**
>  * phy_connect - connect an ethernet device to a PHY device
>  * @dev: the network device to connect
>  * @bus_id: the id string of the PHY device to connect
> @@ -310,18 +337,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
>                phy_interface_t interface)
>  {
>        struct phy_device *phydev;
> +       struct device *d;
> +       int rc;
>
> -       phydev = phy_attach(dev, bus_id, flags, interface);
> -
> -       if (IS_ERR(phydev))
> -               return phydev;
> -
> -       phy_prepare_link(phydev, handler);
> -
> -       phy_start_machine(phydev, NULL);
> +       /* Search the list of PHY devices on the mdio bus for the
> +        * PHY with the requested name */
> +       d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
> +       if (!d) {
> +               pr_err("PHY %s not found\n", bus_id);
> +               return ERR_PTR(-ENODEV);
> +       }
> +       phydev = to_phy_device(d);
>
> -       if (phydev->irq > 0)
> -               phy_start_interrupts(phydev);
> +       rc = phy_attach_direct(dev, phydev, flags, interface);
> +       if (rc)
> +               return ERR_PTR(rc);
>
>        return phydev;
>  }
> @@ -345,9 +375,9 @@ void phy_disconnect(struct phy_device *phydev)
>  EXPORT_SYMBOL(phy_disconnect);
>
>  /**
> - * phy_attach - attach a network device to a particular PHY device
> + * phy_attach_direct - attach a network device to a given PHY device pointer
>  * @dev: network device to attach
> - * @bus_id: PHY device to attach
> + * @phydev: Pointer to phy_device to attach
>  * @flags: PHY device's dev_flags
>  * @interface: PHY device's interface
>  *
> @@ -358,22 +388,10 @@ EXPORT_SYMBOL(phy_disconnect);
>  *     the attaching device, and given a callback for link status
>  *     change.  The phy_device is returned to the attaching driver.
>  */
> -struct phy_device *phy_attach(struct net_device *dev,
> -               const char *bus_id, u32 flags, phy_interface_t interface)
> +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
> +                     u32 flags, phy_interface_t interface)
>  {
> -       struct bus_type *bus = &mdio_bus_type;
> -       struct phy_device *phydev;
> -       struct device *d;
> -
> -       /* Search the list of PHY devices on the mdio bus for the
> -        * PHY with the requested name */
> -       d = bus_find_device_by_name(bus, NULL, bus_id);
> -       if (d) {
> -               phydev = to_phy_device(d);
> -       } else {
> -               printk(KERN_ERR "%s not found\n", bus_id);
> -               return ERR_PTR(-ENODEV);
> -       }
> +       struct device *d = &phydev->dev;
>
>        /* Assume that if there is no driver, that it doesn't
>         * exist, and we should use the genphy driver. */
> @@ -386,13 +404,12 @@ struct phy_device *phy_attach(struct net_device *dev,
>                        err = device_bind_driver(d);
>
>                if (err)
> -                       return ERR_PTR(err);
> +                       return err;
>        }
>
>        if (phydev->attached_dev) {
> -               printk(KERN_ERR "%s: %s already attached\n",
> -                               dev->name, bus_id);
> -               return ERR_PTR(-EBUSY);
> +               dev_err(&dev->dev, "PHY already attached\n");
> +               return -EBUSY;
>        }
>
>        phydev->attached_dev = dev;
> @@ -410,13 +427,48 @@ struct phy_device *phy_attach(struct net_device *dev,
>                err = phy_scan_fixups(phydev);
>
>                if (err < 0)
> -                       return ERR_PTR(err);
> +                       return err;
>
>                err = phydev->drv->config_init(phydev);
>
>                if (err < 0)
> -                       return ERR_PTR(err);
> +                       return err;
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(phy_attach_direct);
> +
> +/**
> + * phy_attach - attach a network device to a particular PHY device
> + * @dev: network device to attach
> + * @bus_id: Bus ID of PHY device to attach
> + * @flags: PHY device's dev_flags
> + * @interface: PHY device's interface
> + *
> + * Description: Same as phy_attach_direct() except that a PHY bus_id
> + *     string is passed instead of a pointer to a struct phy_device.
> + */
> +struct phy_device *phy_attach(struct net_device *dev,
> +               const char *bus_id, u32 flags, phy_interface_t interface)
> +{
> +       struct bus_type *bus = &mdio_bus_type;
> +       struct phy_device *phydev;
> +       struct device *d;
> +       int rc;
> +
> +       /* Search the list of PHY devices on the mdio bus for the
> +        * PHY with the requested name */
> +       d = bus_find_device_by_name(bus, NULL, bus_id);
> +       if (!d) {
> +               pr_err("PHY %s not found\n", bus_id);
> +               return ERR_PTR(-ENODEV);
>        }
> +       phydev = to_phy_device(d);
> +
> +       rc = phy_attach_direct(dev, phydev, flags, interface);
> +       if (rc)
> +               return ERR_PTR(rc);
>
>        return phydev;
>  }
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index a47d64f..97405f2 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -442,8 +442,13 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
>  int phy_device_register(struct phy_device *phy);
>  int phy_clear_interrupt(struct phy_device *phydev);
>  int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
> +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
> +               u32 flags, phy_interface_t interface);
>  struct phy_device * phy_attach(struct net_device *dev,
>                const char *bus_id, u32 flags, phy_interface_t interface);
> +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
> +               void (*handler)(struct net_device *), u32 flags,
> +               phy_interface_t interface);
>  struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
>                void (*handler)(struct net_device *), u32 flags,
>                phy_interface_t interface);
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions
@ 2009-03-19  5:05     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:05 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Add phy_connect_direct() and phy_attach_direct() functions so that
> drivers can use a pointer to the phy_device instead of trying to determin=
e
> the phy's bus_id string.
>
> This patch is useful for OF device tree descriptions of phy devices where
> the driver doesn't need or know what the bus_id value in order to get a
> phy_device pointer.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/net/phy/phy_device.c | =A0118 ++++++++++++++++++++++++++++++--=
----------
> =A0include/linux/phy.h =A0 =A0 =A0 =A0 =A0| =A0 =A05 ++
> =A02 files changed, 90 insertions(+), 33 deletions(-)
>
>
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 793332f..238d21e 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -290,6 +290,33 @@ void phy_prepare_link(struct phy_device *phydev,
> =A0}
>
> =A0/**
> + * phy_connect_direct - connect an ethernet device to a specific phy_dev=
ice
> + * @dev: the network device to connect
> + * @phydev: the pointer to the phy device
> + * @handler: callback function for state change notifications
> + * @flags: PHY device's dev_flags
> + * @interface: PHY device's interface
> + */
> +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev=
,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void (*handler)(struct net_d=
evice *), u32 flags,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0phy_interface_t interface)
> +{
> + =A0 =A0 =A0 int rc;
> +
> + =A0 =A0 =A0 rc =3D phy_attach_direct(dev, phydev, flags, interface);
> + =A0 =A0 =A0 if (rc)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return rc;
> +
> + =A0 =A0 =A0 phy_prepare_link(phydev, handler);
> + =A0 =A0 =A0 phy_start_machine(phydev, NULL);
> + =A0 =A0 =A0 if (phydev->irq > 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_start_interrupts(phydev);
> +
> + =A0 =A0 =A0 return 0;
> +}
> +EXPORT_SYMBOL(phy_connect_direct);
> +
> +/**
> =A0* phy_connect - connect an ethernet device to a PHY device
> =A0* @dev: the network device to connect
> =A0* @bus_id: the id string of the PHY device to connect
> @@ -310,18 +337,21 @@ struct phy_device * phy_connect(struct net_device *=
dev, const char *bus_id,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0phy_interface_t interface)
> =A0{
> =A0 =A0 =A0 =A0struct phy_device *phydev;
> + =A0 =A0 =A0 struct device *d;
> + =A0 =A0 =A0 int rc;
>
> - =A0 =A0 =A0 phydev =3D phy_attach(dev, bus_id, flags, interface);
> -
> - =A0 =A0 =A0 if (IS_ERR(phydev))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return phydev;
> -
> - =A0 =A0 =A0 phy_prepare_link(phydev, handler);
> -
> - =A0 =A0 =A0 phy_start_machine(phydev, NULL);
> + =A0 =A0 =A0 /* Search the list of PHY devices on the mdio bus for the
> + =A0 =A0 =A0 =A0* PHY with the requested name */
> + =A0 =A0 =A0 d =3D bus_find_device_by_name(&mdio_bus_type, NULL, bus_id)=
;
> + =A0 =A0 =A0 if (!d) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pr_err("PHY %s not found\n", bus_id);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(-ENODEV);
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 phydev =3D to_phy_device(d);
>
> - =A0 =A0 =A0 if (phydev->irq > 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_start_interrupts(phydev);
> + =A0 =A0 =A0 rc =3D phy_attach_direct(dev, phydev, flags, interface);
> + =A0 =A0 =A0 if (rc)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(rc);
>
> =A0 =A0 =A0 =A0return phydev;
> =A0}
> @@ -345,9 +375,9 @@ void phy_disconnect(struct phy_device *phydev)
> =A0EXPORT_SYMBOL(phy_disconnect);
>
> =A0/**
> - * phy_attach - attach a network device to a particular PHY device
> + * phy_attach_direct - attach a network device to a given PHY device poi=
nter
> =A0* @dev: network device to attach
> - * @bus_id: PHY device to attach
> + * @phydev: Pointer to phy_device to attach
> =A0* @flags: PHY device's dev_flags
> =A0* @interface: PHY device's interface
> =A0*
> @@ -358,22 +388,10 @@ EXPORT_SYMBOL(phy_disconnect);
> =A0* =A0 =A0 the attaching device, and given a callback for link status
> =A0* =A0 =A0 change. =A0The phy_device is returned to the attaching drive=
r.
> =A0*/
> -struct phy_device *phy_attach(struct net_device *dev,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *bus_id, u32 flags, phy_interfac=
e_t interface)
> +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 u32 flags, phy_interface_t inte=
rface)
> =A0{
> - =A0 =A0 =A0 struct bus_type *bus =3D &mdio_bus_type;
> - =A0 =A0 =A0 struct phy_device *phydev;
> - =A0 =A0 =A0 struct device *d;
> -
> - =A0 =A0 =A0 /* Search the list of PHY devices on the mdio bus for the
> - =A0 =A0 =A0 =A0* PHY with the requested name */
> - =A0 =A0 =A0 d =3D bus_find_device_by_name(bus, NULL, bus_id);
> - =A0 =A0 =A0 if (d) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 phydev =3D to_phy_device(d);
> - =A0 =A0 =A0 } else {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "%s not found\n", bus_id);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(-ENODEV);
> - =A0 =A0 =A0 }
> + =A0 =A0 =A0 struct device *d =3D &phydev->dev;
>
> =A0 =A0 =A0 =A0/* Assume that if there is no driver, that it doesn't
> =A0 =A0 =A0 =A0 * exist, and we should use the genphy driver. */
> @@ -386,13 +404,12 @@ struct phy_device *phy_attach(struct net_device *de=
v,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0err =3D device_bind_driver=
(d);
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (err)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(err);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return err;
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0if (phydev->attached_dev) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "%s: %s already attached\n"=
,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev->name, =
bus_id);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(-EBUSY);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&dev->dev, "PHY already attached\n"=
);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EBUSY;
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0phydev->attached_dev =3D dev;
> @@ -410,13 +427,48 @@ struct phy_device *phy_attach(struct net_device *de=
v,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0err =3D phy_scan_fixups(phydev);
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (err < 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(err);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return err;
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0err =3D phydev->drv->config_init(phydev);
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (err < 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(err);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return err;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 return 0;
> +}
> +EXPORT_SYMBOL(phy_attach_direct);
> +
> +/**
> + * phy_attach - attach a network device to a particular PHY device
> + * @dev: network device to attach
> + * @bus_id: Bus ID of PHY device to attach
> + * @flags: PHY device's dev_flags
> + * @interface: PHY device's interface
> + *
> + * Description: Same as phy_attach_direct() except that a PHY bus_id
> + * =A0 =A0 string is passed instead of a pointer to a struct phy_device.
> + */
> +struct phy_device *phy_attach(struct net_device *dev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *bus_id, u32 flags, phy_interfac=
e_t interface)
> +{
> + =A0 =A0 =A0 struct bus_type *bus =3D &mdio_bus_type;
> + =A0 =A0 =A0 struct phy_device *phydev;
> + =A0 =A0 =A0 struct device *d;
> + =A0 =A0 =A0 int rc;
> +
> + =A0 =A0 =A0 /* Search the list of PHY devices on the mdio bus for the
> + =A0 =A0 =A0 =A0* PHY with the requested name */
> + =A0 =A0 =A0 d =3D bus_find_device_by_name(bus, NULL, bus_id);
> + =A0 =A0 =A0 if (!d) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pr_err("PHY %s not found\n", bus_id);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(-ENODEV);
> =A0 =A0 =A0 =A0}
> + =A0 =A0 =A0 phydev =3D to_phy_device(d);
> +
> + =A0 =A0 =A0 rc =3D phy_attach_direct(dev, phydev, flags, interface);
> + =A0 =A0 =A0 if (rc)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return ERR_PTR(rc);
>
> =A0 =A0 =A0 =A0return phydev;
> =A0}
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index a47d64f..97405f2 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -442,8 +442,13 @@ struct phy_device* get_phy_device(struct mii_bus *bu=
s, int addr);
> =A0int phy_device_register(struct phy_device *phy);
> =A0int phy_clear_interrupt(struct phy_device *phydev);
> =A0int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
> +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 u32 flags, phy_interface_t interface);
> =A0struct phy_device * phy_attach(struct net_device *dev,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *bus_id, u32 flags, phy_interfa=
ce_t interface);
> +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev=
,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 void (*handler)(struct net_device *), u32 f=
lags,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_interface_t interface);
> =A0struct phy_device * phy_connect(struct net_device *dev, const char *bu=
s_id,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void (*handler)(struct net_device *), u32 =
flags,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0phy_interface_t interface);
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 4/9] openfirmware: Add OF phylib support code
  2009-03-19  5:00 ` [PATCH 4/9] openfirmware: Add OF phylib support code Grant Likely
@ 2009-03-19  5:06     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:06 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Add support for parsing the device tree for PHY devices on an MDIO bus
>
> CC: Andy Fleming <afleming@freescale.com>
> CC: linuxppc-dev@ozlabs.org
> CC: devtree-discuss@ozlabs.org
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/of/Kconfig      |    6 ++
>  drivers/of/Makefile     |    1
>  drivers/of/of_mdio.c    |  130 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_mdio.h |   21 ++++++++
>  4 files changed, 158 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/of/of_mdio.c
>  create mode 100644 include/linux/of_mdio.h
>
>
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index f821dbc..6fe043b 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -19,3 +19,9 @@ config OF_SPI
>        depends on OF && PPC_OF && SPI
>        help
>          OpenFirmware SPI accessors
> +
> +config OF_MDIO
> +       def_tristate PHYLIB
> +       depends on OF && PHYLIB
> +       help
> +         OpenFirmware MDIO bus (Ethernet PHY) accessors
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 4c3c6f8..bdfb5f5 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) += device.o platform.o
>  obj-$(CONFIG_OF_GPIO)   += gpio.o
>  obj-$(CONFIG_OF_I2C)   += of_i2c.o
>  obj-$(CONFIG_OF_SPI)   += of_spi.o
> +obj-$(CONFIG_OF_MDIO)  += of_mdio.o
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> new file mode 100644
> index 0000000..6f3038a
> --- /dev/null
> +++ b/drivers/of/of_mdio.c
> @@ -0,0 +1,130 @@
> +/*
> + * OF helpers for the MDIO (Ethernet PHY) API
> + *
> + * Copyright (c) 2009 Secret Lab Technologies, Ltd.
> + *
> + * This file is released under the GPLv2
> + *
> + * This file provides helper functions for extracting PHY device information
> + * out of the OpenFirmware device tree and using it to populate an mii_bus.
> + */
> +
> +#include <linux/phy.h>
> +#include <linux/of.h>
> +#include <linux/of_mdio.h>
> +#include <linux/module.h>
> +
> +MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
> +MODULE_LICENSE("GPL");
> +
> +/**
> + * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
> + * @mdio: pointer to mii_bus structure
> + * @np: pointer to device_node of MDIO bus.
> + *
> + * This function registers the mii_bus structure and registers a phy_device
> + * for each child node of @np.
> + */
> +int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
> +{
> +       struct phy_device *phy;
> +       struct device_node *child;
> +       int rc, i;
> +
> +       /* Mask out all PHYs from auto probing.  Instead the PHYs listed in
> +        * the device tree are populated after the bus has been registered */
> +       mdio->phy_mask = ~0;
> +
> +       /* Clear all the IRQ properties */
> +       if (mdio->irq)
> +               for (i=0; i<PHY_MAX_ADDR; i++)
> +                       mdio->irq[i] = PHY_POLL;
> +
> +       /* Register the MDIO bus */
> +       rc = mdiobus_register(mdio);
> +       if (rc)
> +               return rc;
> +
> +       /* Loop over the child nodes and register a phy_device for each one */
> +       for_each_child_of_node(np, child) {
> +               const u32 *addr;
> +               int len;
> +
> +               /* A PHY must have a reg property in the range [0-31] */
> +               addr = of_get_property(child, "reg", &len);
> +               if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) {
> +                       dev_err(&mdio->dev, "%s has invalid PHY address\n",
> +                               child->full_name);
> +                       continue;
> +               }
> +
> +               if (mdio->irq) {
> +                       mdio->irq[*addr] = irq_of_parse_and_map(child, 0);
> +                       if (!mdio->irq[*addr])
> +                               mdio->irq[*addr] = PHY_POLL;
> +               }
> +
> +               phy = get_phy_device(mdio, *addr);
> +               if (!phy) {
> +                       dev_err(&mdio->dev, "error probing PHY at address %i\n",
> +                               *addr);
> +                       continue;
> +               }
> +               phy_scan_fixups(phy);
> +
> +               /* Associate the OF node with the device structure so it
> +                * can be looked up later */
> +               of_node_get(child);
> +               dev_archdata_set_node(&phy->dev.archdata, child);
> +
> +               /* All data is now stored in the phy struct; register it */
> +               rc = phy_device_register(phy);
> +               if (rc) {
> +                       phy_device_free(phy);
> +                       of_node_put(child);
> +                       continue;
> +               }
> +
> +               dev_dbg(&mdio->dev, "registered phy %s at address %i\n",
> +                       child->name, *addr);
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(of_mdiobus_register);
> +
> +/**
> + * of_phy_connect - Connect to the phy described in the device tree
> + * @dev: pointer to net_device claiming the phy
> + * @phy_np: Pointer to device tree node for the PHY
> + * @hndlr: Link state callback for the network device
> + * @iface: PHY data interface type
> + *
> + * Returns a pointer to the phy_device if successfull.  NULL otherwise
> + */
> +struct phy_device *of_phy_connect(struct net_device *dev,
> +                                 struct device_node *phy_np,
> +                                 void (*hndlr)(struct net_device *), u32 flags,
> +                                 phy_interface_t iface)
> +{
> +       int match(struct device *dev, void *phy_np)
> +       {
> +               return dev_archdata_get_node(&dev->archdata) == phy_np;
> +       }
> +       struct device *d;
> +       int rc;
> +
> +       if (!phy_np)
> +               return NULL;
> +
> +       d = bus_find_device(&mdio_bus_type, NULL, phy_np, match);
> +       if (!d)
> +               return NULL;
> +
> +       rc = phy_connect_direct(dev, to_phy_device(d), hndlr, flags, iface);
> +       if (rc)
> +               return NULL;
> +
> +       return to_phy_device(d);
> +}
> +EXPORT_SYMBOL(of_phy_connect);
> diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
> new file mode 100644
> index 0000000..ec092cc
> --- /dev/null
> +++ b/include/linux/of_mdio.h
> @@ -0,0 +1,21 @@
> +/*
> + * OF helpers for the MDIO (Ethernet PHY) API
> + *
> + * Copyright (c) 2009 Secret Lab Technologies, Ltd.
> + *
> + * This file is released under the GPLv2
> + */
> +
> +#ifndef __LINUX_OF_MDIO_H
> +#define __LINUX_OF_MDIO_H
> +
> +#include <linux/phy.h>
> +#include <linux/of.h>
> +
> +extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
> +extern struct phy_device *of_phy_connect(struct net_device *dev,
> +                                        struct device_node *phy_np,
> +                                        void (*hndlr)(struct net_device *),
> +                                        u32 flags, phy_interface_t iface);
> +
> +#endif /* __LINUX_OF_MDIO_H */
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 4/9] openfirmware: Add OF phylib support code
@ 2009-03-19  5:06     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:06 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Add support for parsing the device tree for PHY devices on an MDIO bus
>
> CC: Andy Fleming <afleming@freescale.com>
> CC: linuxppc-dev@ozlabs.org
> CC: devtree-discuss@ozlabs.org
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/of/Kconfig =A0 =A0 =A0| =A0 =A06 ++
> =A0drivers/of/Makefile =A0 =A0 | =A0 =A01
> =A0drivers/of/of_mdio.c =A0 =A0| =A0130 +++++++++++++++++++++++++++++++++=
++++++++++++++
> =A0include/linux/of_mdio.h | =A0 21 ++++++++
> =A04 files changed, 158 insertions(+), 0 deletions(-)
> =A0create mode 100644 drivers/of/of_mdio.c
> =A0create mode 100644 include/linux/of_mdio.h
>
>
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index f821dbc..6fe043b 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -19,3 +19,9 @@ config OF_SPI
> =A0 =A0 =A0 =A0depends on OF && PPC_OF && SPI
> =A0 =A0 =A0 =A0help
> =A0 =A0 =A0 =A0 =A0OpenFirmware SPI accessors
> +
> +config OF_MDIO
> + =A0 =A0 =A0 def_tristate PHYLIB
> + =A0 =A0 =A0 depends on OF && PHYLIB
> + =A0 =A0 =A0 help
> + =A0 =A0 =A0 =A0 OpenFirmware MDIO bus (Ethernet PHY) accessors
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 4c3c6f8..bdfb5f5 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) +=3D device.o platform.o
> =A0obj-$(CONFIG_OF_GPIO) =A0 +=3D gpio.o
> =A0obj-$(CONFIG_OF_I2C) =A0 +=3D of_i2c.o
> =A0obj-$(CONFIG_OF_SPI) =A0 +=3D of_spi.o
> +obj-$(CONFIG_OF_MDIO) =A0+=3D of_mdio.o
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> new file mode 100644
> index 0000000..6f3038a
> --- /dev/null
> +++ b/drivers/of/of_mdio.c
> @@ -0,0 +1,130 @@
> +/*
> + * OF helpers for the MDIO (Ethernet PHY) API
> + *
> + * Copyright (c) 2009 Secret Lab Technologies, Ltd.
> + *
> + * This file is released under the GPLv2
> + *
> + * This file provides helper functions for extracting PHY device informa=
tion
> + * out of the OpenFirmware device tree and using it to populate an mii_b=
us.
> + */
> +
> +#include <linux/phy.h>
> +#include <linux/of.h>
> +#include <linux/of_mdio.h>
> +#include <linux/module.h>
> +
> +MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
> +MODULE_LICENSE("GPL");
> +
> +/**
> + * of_mdiobus_register - Register mii_bus and create PHYs from the devic=
e tree
> + * @mdio: pointer to mii_bus structure
> + * @np: pointer to device_node of MDIO bus.
> + *
> + * This function registers the mii_bus structure and registers a phy_dev=
ice
> + * for each child node of @np.
> + */
> +int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
> +{
> + =A0 =A0 =A0 struct phy_device *phy;
> + =A0 =A0 =A0 struct device_node *child;
> + =A0 =A0 =A0 int rc, i;
> +
> + =A0 =A0 =A0 /* Mask out all PHYs from auto probing. =A0Instead the PHYs=
 listed in
> + =A0 =A0 =A0 =A0* the device tree are populated after the bus has been r=
egistered */
> + =A0 =A0 =A0 mdio->phy_mask =3D ~0;
> +
> + =A0 =A0 =A0 /* Clear all the IRQ properties */
> + =A0 =A0 =A0 if (mdio->irq)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (i=3D0; i<PHY_MAX_ADDR; i++)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mdio->irq[i] =3D PHY_POLL;
> +
> + =A0 =A0 =A0 /* Register the MDIO bus */
> + =A0 =A0 =A0 rc =3D mdiobus_register(mdio);
> + =A0 =A0 =A0 if (rc)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return rc;
> +
> + =A0 =A0 =A0 /* Loop over the child nodes and register a phy_device for =
each one */
> + =A0 =A0 =A0 for_each_child_of_node(np, child) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 const u32 *addr;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 int len;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* A PHY must have a reg property in the ra=
nge [0-31] */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 addr =3D of_get_property(child, "reg", &len=
);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!addr || len < sizeof(*addr) || *addr >=
=3D 32 || *addr < 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&mdio->dev, "%s has=
 invalid PHY address\n",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 child->full=
_name);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (mdio->irq) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mdio->irq[*addr] =3D irq_of=
_parse_and_map(child, 0);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!mdio->irq[*addr])
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mdio->irq[*=
addr] =3D PHY_POLL;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy =3D get_phy_device(mdio, *addr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!phy) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&mdio->dev, "error =
probing PHY at address %i\n",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *addr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_scan_fixups(phy);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Associate the OF node with the device st=
ructure so it
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* can be looked up later */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_get(child);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_archdata_set_node(&phy->dev.archdata, c=
hild);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* All data is now stored in the phy struct=
; register it */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 rc =3D phy_device_register(phy);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (rc) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_device_free(phy);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(child);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(&mdio->dev, "registered phy %s at a=
ddress %i\n",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 child->name, *addr);
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 return 0;
> +}
> +EXPORT_SYMBOL(of_mdiobus_register);
> +
> +/**
> + * of_phy_connect - Connect to the phy described in the device tree
> + * @dev: pointer to net_device claiming the phy
> + * @phy_np: Pointer to device tree node for the PHY
> + * @hndlr: Link state callback for the network device
> + * @iface: PHY data interface type
> + *
> + * Returns a pointer to the phy_device if successfull. =A0NULL otherwise
> + */
> +struct phy_device *of_phy_connect(struct net_device *dev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct =
device_node *phy_np,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void (*=
hndlr)(struct net_device *), u32 flags,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_int=
erface_t iface)
> +{
> + =A0 =A0 =A0 int match(struct device *dev, void *phy_np)
> + =A0 =A0 =A0 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return dev_archdata_get_node(&dev->archdata=
) =3D=3D phy_np;
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 struct device *d;
> + =A0 =A0 =A0 int rc;
> +
> + =A0 =A0 =A0 if (!phy_np)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
> +
> + =A0 =A0 =A0 d =3D bus_find_device(&mdio_bus_type, NULL, phy_np, match);
> + =A0 =A0 =A0 if (!d)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
> +
> + =A0 =A0 =A0 rc =3D phy_connect_direct(dev, to_phy_device(d), hndlr, fla=
gs, iface);
> + =A0 =A0 =A0 if (rc)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
> +
> + =A0 =A0 =A0 return to_phy_device(d);
> +}
> +EXPORT_SYMBOL(of_phy_connect);
> diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
> new file mode 100644
> index 0000000..ec092cc
> --- /dev/null
> +++ b/include/linux/of_mdio.h
> @@ -0,0 +1,21 @@
> +/*
> + * OF helpers for the MDIO (Ethernet PHY) API
> + *
> + * Copyright (c) 2009 Secret Lab Technologies, Ltd.
> + *
> + * This file is released under the GPLv2
> + */
> +
> +#ifndef __LINUX_OF_MDIO_H
> +#define __LINUX_OF_MDIO_H
> +
> +#include <linux/phy.h>
> +#include <linux/of.h>
> +
> +extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node =
*np);
> +extern struct phy_device *of_phy_connect(struct net_device *dev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0struct device_node *phy_np,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0void (*hndlr)(struct net_device *),
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0u32 flags, phy_interface_t iface);
> +
> +#endif /* __LINUX_OF_MDIO_H */
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure
  2009-03-19  5:00 ` [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure Grant Likely
@ 2009-03-19  5:06     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:06 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> The patch reworks the MPC5200 Fast Ethernet Controller (FEC) driver to
> use the of_mdio infrastructure for registering PHY devices from data out
> openfirmware device tree, and eliminates the assumption that the PHY
> for the FEC is always attached to the FEC's own MDIO bus.  With this
> patch, the FEC can use a PHY attached to any MDIO bus if it is described
> in the device tree.
> ---
>
>  drivers/net/Kconfig           |    2
>  drivers/net/fec_mpc52xx.c     |  175 +++++++++++------------------------------
>  drivers/net/fec_mpc52xx_phy.c |   26 +-----
>  3 files changed, 53 insertions(+), 150 deletions(-)
>
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index a2f185f..3aa24f6 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1854,7 +1854,7 @@ config FEC_MPC52xx
>
>  config FEC_MPC52xx_MDIO
>        bool "MPC52xx FEC MDIO bus driver"
> -       depends on FEC_MPC52xx
> +       depends on FEC_MPC52xx && OF_MDIO
>        default y
>        ---help---
>          The MPC5200's FEC can connect to the Ethernet either with
> diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
> index 3d55f9a..12ab8ae 100644
> --- a/drivers/net/fec_mpc52xx.c
> +++ b/drivers/net/fec_mpc52xx.c
> @@ -25,6 +25,7 @@
>  #include <linux/hardirq.h>
>  #include <linux/delay.h>
>  #include <linux/of_device.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>
>  #include <linux/netdevice.h>
> @@ -43,11 +44,9 @@
>
>  #define DRIVER_NAME "mpc52xx-fec"
>
> -#define FEC5200_PHYADDR_NONE   (-1)
> -#define FEC5200_PHYADDR_7WIRE  (-2)
> -
>  /* Private driver data structure */
>  struct mpc52xx_fec_priv {
> +       struct net_device *ndev;
>        int duplex;
>        int speed;
>        int r_irq;
> @@ -59,10 +58,11 @@ struct mpc52xx_fec_priv {
>        int msg_enable;
>
>        /* MDIO link details */
> -       int phy_addr;
> -       unsigned int phy_speed;
> +       unsigned int mdio_speed;
> +       struct device_node *phy_node;
>        struct phy_device *phydev;
>        enum phy_state link;
> +       int seven_wire_mode;
>  };
>
>
> @@ -210,66 +210,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
>                phy_print_status(phydev);
>  }
>
> -static int mpc52xx_fec_init_phy(struct net_device *dev)
> -{
> -       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
> -       struct phy_device *phydev;
> -       char phy_id[BUS_ID_SIZE];
> -
> -       snprintf(phy_id, sizeof(phy_id), "%x:%02x",
> -                       (unsigned int)dev->base_addr, priv->phy_addr);
> -
> -       priv->link = PHY_DOWN;
> -       priv->speed = 0;
> -       priv->duplex = -1;
> -
> -       phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
> -       if (IS_ERR(phydev)) {
> -               dev_err(&dev->dev, "phy_connect failed\n");
> -               return PTR_ERR(phydev);
> -       }
> -       dev_info(&dev->dev, "attached phy %i to driver %s\n",
> -                       phydev->addr, phydev->drv->name);
> -
> -       priv->phydev = phydev;
> -
> -       return 0;
> -}
> -
> -static int mpc52xx_fec_phy_start(struct net_device *dev)
> -{
> -       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
> -       int err;
> -
> -       if (priv->phy_addr < 0)
> -               return 0;
> -
> -       err = mpc52xx_fec_init_phy(dev);
> -       if (err) {
> -               dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n");
> -               return err;
> -       }
> -
> -       /* reset phy - this also wakes it from PDOWN */
> -       phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
> -       phy_start(priv->phydev);
> -
> -       return 0;
> -}
> -
> -static void mpc52xx_fec_phy_stop(struct net_device *dev)
> -{
> -       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
> -
> -       if (!priv->phydev)
> -               return;
> -
> -       phy_disconnect(priv->phydev);
> -       /* power down phy */
> -       phy_stop(priv->phydev);
> -       phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
> -}
> -
>  static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
>                struct mii_ioctl_data *mii_data, int cmd)
>  {
> @@ -279,25 +219,25 @@ static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
>        return phy_mii_ioctl(priv->phydev, mii_data, cmd);
>  }
>
> -static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
> -{
> -       struct mpc52xx_fec __iomem *fec = priv->fec;
> -
> -       if (priv->phydev)
> -               return;
> -
> -       out_be32(&fec->mii_speed, priv->phy_speed);
> -}
> -
>  static int mpc52xx_fec_open(struct net_device *dev)
>  {
>        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
>        int err = -EBUSY;
>
> +       if (priv->phy_node) {
> +               priv->phydev = of_phy_connect(priv->ndev, priv->phy_node,
> +                                             mpc52xx_fec_adjust_link, 0, 0);
> +               if (!priv->phydev) {
> +                       dev_err(&dev->dev, "of_phy_connect failed\n");
> +                       return -ENODEV;
> +               }
> +               phy_start(priv->phydev);
> +       }
> +
>        if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
>                        DRIVER_NAME "_ctrl", dev)) {
>                dev_err(&dev->dev, "ctrl interrupt request failed\n");
> -               goto out;
> +               goto free_phy;
>        }
>        if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
>                        DRIVER_NAME "_rx", dev)) {
> @@ -319,10 +259,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
>                goto free_irqs;
>        }
>
> -       err = mpc52xx_fec_phy_start(dev);
> -       if (err)
> -               goto free_skbs;
> -
>        bcom_enable(priv->rx_dmatsk);
>        bcom_enable(priv->tx_dmatsk);
>
> @@ -332,16 +268,18 @@ static int mpc52xx_fec_open(struct net_device *dev)
>
>        return 0;
>
> - free_skbs:
> -       mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
> -
>  free_irqs:
>        free_irq(priv->t_irq, dev);
>  free_2irqs:
>        free_irq(priv->r_irq, dev);
>  free_ctrl_irq:
>        free_irq(dev->irq, dev);
> - out:
> + free_phy:
> +       if (priv->phydev) {
> +               phy_stop(priv->phydev);
> +               phy_disconnect(priv->phydev);
> +               priv->phydev = NULL;
> +       }
>
>        return err;
>  }
> @@ -360,7 +298,12 @@ static int mpc52xx_fec_close(struct net_device *dev)
>        free_irq(priv->r_irq, dev);
>        free_irq(priv->t_irq, dev);
>
> -       mpc52xx_fec_phy_stop(dev);
> +       if (priv->phydev) {
> +               /* power down phy */
> +               phy_stop(priv->phydev);
> +               phy_disconnect(priv->phydev);
> +               priv->phydev = NULL;
> +       }
>
>        return 0;
>  }
> @@ -700,7 +643,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
>        /* set phy speed.
>         * this can't be done in phy driver, since it needs to be called
>         * before fec stuff (even on resume) */
> -       mpc52xx_fec_phy_hw_init(priv);
> +       out_be32(&fec->mii_speed, priv->mdio_speed);
>  }
>
>  /**
> @@ -736,7 +679,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
>        rcntrl = FEC_RX_BUFFER_SIZE << 16;      /* max frame length */
>        rcntrl |= FEC_RCNTRL_FCE;
>
> -       if (priv->phy_addr != FEC5200_PHYADDR_7WIRE)
> +       if (!priv->seven_wire_mode)
>                rcntrl |= FEC_RCNTRL_MII_MODE;
>
>        if (priv->duplex == DUPLEX_FULL)
> @@ -802,8 +745,6 @@ static void mpc52xx_fec_stop(struct net_device *dev)
>
>        /* Stop FEC */
>        out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
> -
> -       return;
>  }
>
>  /* reset fec and bestcomm tasks */
> @@ -821,9 +762,11 @@ static void mpc52xx_fec_reset(struct net_device *dev)
>
>        mpc52xx_fec_hw_init(dev);
>
> -       phy_stop(priv->phydev);
> -       phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
> -       phy_start(priv->phydev);
> +       if (priv->phydev) {
> +               phy_stop(priv->phydev);
> +               phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
> +               phy_start(priv->phydev);
> +       }
>
>        bcom_fec_rx_reset(priv->rx_dmatsk);
>        bcom_fec_tx_reset(priv->tx_dmatsk);
> @@ -923,7 +866,6 @@ static const struct net_device_ops mpc52xx_fec_netdev_ops = {
>  #endif
>  };
>
> -
>  static int __devinit
>  mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
>  {
> @@ -931,8 +873,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
>        struct net_device *ndev;
>        struct mpc52xx_fec_priv *priv = NULL;
>        struct resource mem;
> -       struct device_node *phy_node;
> -       const phandle *phy_handle;
>        const u32 *prop;
>        int prop_size;
>
> @@ -945,6 +885,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
>                return -ENOMEM;
>
>        priv = netdev_priv(ndev);
> +       priv->ndev = ndev;
>
>        /* Reserve FEC control zone */
>        rv = of_address_to_resource(op->node, 0, &mem);
> @@ -968,6 +909,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
>        ndev->watchdog_timeo    = FEC_WATCHDOG_TIMEOUT;
>        ndev->base_addr         = mem.start;
>        ndev->netdev_ops = &mpc52xx_fec_netdev_ops;
> +       SET_NETDEV_DEV(ndev, &op->dev);
>
>        priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
>
> @@ -1017,14 +959,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
>         */
>
>        /* Start with safe defaults for link connection */
> -       priv->phy_addr = FEC5200_PHYADDR_NONE;
> -       priv->speed = 100;
> +       priv->speed = 10;
>        priv->duplex = DUPLEX_HALF;
> -       priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
> -
> -       /* the 7-wire property means don't use MII mode */
> -       if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
> -               priv->phy_addr = FEC5200_PHYADDR_7WIRE;
> +       priv->mdio_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
>
>        /* The current speed preconfigures the speed of the MII link */
>        prop = of_get_property(op->node, "current-speed", &prop_size);
> @@ -1033,43 +970,23 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
>                priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
>        }
>
> -       /* If there is a phy handle, setup link to that phy */
> -       phy_handle = of_get_property(op->node, "phy-handle", &prop_size);
> -       if (phy_handle && (prop_size >= sizeof(phandle))) {
> -               phy_node = of_find_node_by_phandle(*phy_handle);
> -               prop = of_get_property(phy_node, "reg", &prop_size);
> -               if (prop && (prop_size >= sizeof(u32)))
> -                       if ((*prop >= 0) && (*prop < PHY_MAX_ADDR))
> -                               priv->phy_addr = *prop;
> -               of_node_put(phy_node);
> +       /* If there is a phy handle, then get the PHY node */
> +       priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
> +
> +       /* the 7-wire property means don't use MII mode */
> +       if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) {
> +               priv->seven_wire_mode = 1;
> +               dev_info(&ndev->dev, "using 7-wire PHY mode\n");
>        }
>
>        /* Hardware init */
>        mpc52xx_fec_hw_init(ndev);
> -
>        mpc52xx_fec_reset_stats(ndev);
>
> -       SET_NETDEV_DEV(ndev, &op->dev);
> -
> -       /* Register the new network device */
>        rv = register_netdev(ndev);
>        if (rv < 0)
>                goto probe_error;
>
> -       /* Now report the link setup */
> -       switch (priv->phy_addr) {
> -        case FEC5200_PHYADDR_NONE:
> -               dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n",
> -                        priv->speed, priv->duplex ? 'F' : 'H');
> -               break;
> -        case FEC5200_PHYADDR_7WIRE:
> -               dev_info(&ndev->dev, "using 7-wire PHY mode\n");
> -               break;
> -        default:
> -               dev_info(&ndev->dev, "Using PHY at MDIO address %i\n",
> -                        priv->phy_addr);
> -       }
> -
>        /* We're done ! */
>        dev_set_drvdata(&op->dev, ndev);
>
> diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
> index dd9bfa4..fec9f24 100644
> --- a/drivers/net/fec_mpc52xx_phy.c
> +++ b/drivers/net/fec_mpc52xx_phy.c
> @@ -14,12 +14,14 @@
>  #include <linux/netdevice.h>
>  #include <linux/phy.h>
>  #include <linux/of_platform.h>
> +#include <linux/of_mdio.h>
>  #include <asm/io.h>
>  #include <asm/mpc52xx.h>
>  #include "fec_mpc52xx.h"
>
>  struct mpc52xx_fec_mdio_priv {
>        struct mpc52xx_fec __iomem *regs;
> +       int mdio_irqs[PHY_MAX_ADDR];
>  };
>
>  static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
> @@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
>  {
>        struct mpc52xx_fec_mdio_priv *priv = bus->priv;
>        struct mpc52xx_fec __iomem *fec;
> -       int tries = 100;
> +       int tries = 3;
>
>        value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
>        value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
> @@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
>
>        /* wait for it to finish, this takes about 23 us on lite5200b */
>        while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
> -               udelay(5);
> +               msleep(1);
>
>        if (!tries)
>                return -ETIMEDOUT;
> @@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
>  {
>        struct device *dev = &of->dev;
>        struct device_node *np = of->node;
> -       struct device_node *child = NULL;
>        struct mii_bus *bus;
>        struct mpc52xx_fec_mdio_priv *priv;
>        struct resource res = {};
> @@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
>        bus->write = mpc52xx_fec_mdio_write;
>
>        /* setup irqs */
> -       bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
> -       if (bus->irq == NULL) {
> -               err = -ENOMEM;
> -               goto out_free;
> -       }
> -       for (i=0; i<PHY_MAX_ADDR; i++)
> -               bus->irq[i] = PHY_POLL;
> -
> -       while ((child = of_get_next_child(np, child)) != NULL) {
> -               int irq = irq_of_parse_and_map(child, 0);
> -               if (irq != NO_IRQ) {
> -                       const u32 *id = of_get_property(child, "reg", NULL);
> -                       if (id)
> -                               bus->irq[*id] = irq;
> -               }
> -       }
> +       bus->irq = priv->mdio_irqs;
>
>        /* setup registers */
>        err = of_address_to_resource(np, 0, &res);
> @@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
>        out_be32(&priv->regs->mii_speed,
>                ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
>
> -       err = mdiobus_register(bus);
> +       err = of_mdiobus_register(bus, np);
>        if (err)
>                goto out_unmap;
>
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure
@ 2009-03-19  5:06     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:06 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> The patch reworks the MPC5200 Fast Ethernet Controller (FEC) driver to
> use the of_mdio infrastructure for registering PHY devices from data out
> openfirmware device tree, and eliminates the assumption that the PHY
> for the FEC is always attached to the FEC's own MDIO bus. =A0With this
> patch, the FEC can use a PHY attached to any MDIO bus if it is described
> in the device tree.
> ---
>
> =A0drivers/net/Kconfig =A0 =A0 =A0 =A0 =A0 | =A0 =A02
> =A0drivers/net/fec_mpc52xx.c =A0 =A0 | =A0175 +++++++++++----------------=
--------------
> =A0drivers/net/fec_mpc52xx_phy.c | =A0 26 +-----
> =A03 files changed, 53 insertions(+), 150 deletions(-)
>
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index a2f185f..3aa24f6 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1854,7 +1854,7 @@ config FEC_MPC52xx
>
> =A0config FEC_MPC52xx_MDIO
> =A0 =A0 =A0 =A0bool "MPC52xx FEC MDIO bus driver"
> - =A0 =A0 =A0 depends on FEC_MPC52xx
> + =A0 =A0 =A0 depends on FEC_MPC52xx && OF_MDIO
> =A0 =A0 =A0 =A0default y
> =A0 =A0 =A0 =A0---help---
> =A0 =A0 =A0 =A0 =A0The MPC5200's FEC can connect to the Ethernet either w=
ith
> diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
> index 3d55f9a..12ab8ae 100644
> --- a/drivers/net/fec_mpc52xx.c
> +++ b/drivers/net/fec_mpc52xx.c
> @@ -25,6 +25,7 @@
> =A0#include <linux/hardirq.h>
> =A0#include <linux/delay.h>
> =A0#include <linux/of_device.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
>
> =A0#include <linux/netdevice.h>
> @@ -43,11 +44,9 @@
>
> =A0#define DRIVER_NAME "mpc52xx-fec"
>
> -#define FEC5200_PHYADDR_NONE =A0 (-1)
> -#define FEC5200_PHYADDR_7WIRE =A0(-2)
> -
> =A0/* Private driver data structure */
> =A0struct mpc52xx_fec_priv {
> + =A0 =A0 =A0 struct net_device *ndev;
> =A0 =A0 =A0 =A0int duplex;
> =A0 =A0 =A0 =A0int speed;
> =A0 =A0 =A0 =A0int r_irq;
> @@ -59,10 +58,11 @@ struct mpc52xx_fec_priv {
> =A0 =A0 =A0 =A0int msg_enable;
>
> =A0 =A0 =A0 =A0/* MDIO link details */
> - =A0 =A0 =A0 int phy_addr;
> - =A0 =A0 =A0 unsigned int phy_speed;
> + =A0 =A0 =A0 unsigned int mdio_speed;
> + =A0 =A0 =A0 struct device_node *phy_node;
> =A0 =A0 =A0 =A0struct phy_device *phydev;
> =A0 =A0 =A0 =A0enum phy_state link;
> + =A0 =A0 =A0 int seven_wire_mode;
> =A0};
>
>
> @@ -210,66 +210,6 @@ static void mpc52xx_fec_adjust_link(struct net_devic=
e *dev)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0phy_print_status(phydev);
> =A0}
>
> -static int mpc52xx_fec_init_phy(struct net_device *dev)
> -{
> - =A0 =A0 =A0 struct mpc52xx_fec_priv *priv =3D netdev_priv(dev);
> - =A0 =A0 =A0 struct phy_device *phydev;
> - =A0 =A0 =A0 char phy_id[BUS_ID_SIZE];
> -
> - =A0 =A0 =A0 snprintf(phy_id, sizeof(phy_id), "%x:%02x",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (unsigned int)dev->base_add=
r, priv->phy_addr);
> -
> - =A0 =A0 =A0 priv->link =3D PHY_DOWN;
> - =A0 =A0 =A0 priv->speed =3D 0;
> - =A0 =A0 =A0 priv->duplex =3D -1;
> -
> - =A0 =A0 =A0 phydev =3D phy_connect(dev, phy_id, &mpc52xx_fec_adjust_lin=
k, 0, PHY_INTERFACE_MODE_MII);
> - =A0 =A0 =A0 if (IS_ERR(phydev)) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&dev->dev, "phy_connect failed\n");
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return PTR_ERR(phydev);
> - =A0 =A0 =A0 }
> - =A0 =A0 =A0 dev_info(&dev->dev, "attached phy %i to driver %s\n",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 phydev->addr, phydev->drv->=
name);
> -
> - =A0 =A0 =A0 priv->phydev =3D phydev;
> -
> - =A0 =A0 =A0 return 0;
> -}
> -
> -static int mpc52xx_fec_phy_start(struct net_device *dev)
> -{
> - =A0 =A0 =A0 struct mpc52xx_fec_priv *priv =3D netdev_priv(dev);
> - =A0 =A0 =A0 int err;
> -
> - =A0 =A0 =A0 if (priv->phy_addr < 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return 0;
> -
> - =A0 =A0 =A0 err =3D mpc52xx_fec_init_phy(dev);
> - =A0 =A0 =A0 if (err) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&dev->dev, "mpc52xx_fec_init_phy fa=
iled\n");
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return err;
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 /* reset phy - this also wakes it from PDOWN */
> - =A0 =A0 =A0 phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
> - =A0 =A0 =A0 phy_start(priv->phydev);
> -
> - =A0 =A0 =A0 return 0;
> -}
> -
> -static void mpc52xx_fec_phy_stop(struct net_device *dev)
> -{
> - =A0 =A0 =A0 struct mpc52xx_fec_priv *priv =3D netdev_priv(dev);
> -
> - =A0 =A0 =A0 if (!priv->phydev)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> -
> - =A0 =A0 =A0 phy_disconnect(priv->phydev);
> - =A0 =A0 =A0 /* power down phy */
> - =A0 =A0 =A0 phy_stop(priv->phydev);
> - =A0 =A0 =A0 phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
> -}
> -
> =A0static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct mii_ioctl_data *mii_data, int cmd)
> =A0{
> @@ -279,25 +219,25 @@ static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx=
_fec_priv *priv,
> =A0 =A0 =A0 =A0return phy_mii_ioctl(priv->phydev, mii_data, cmd);
> =A0}
>
> -static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
> -{
> - =A0 =A0 =A0 struct mpc52xx_fec __iomem *fec =3D priv->fec;
> -
> - =A0 =A0 =A0 if (priv->phydev)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> -
> - =A0 =A0 =A0 out_be32(&fec->mii_speed, priv->phy_speed);
> -}
> -
> =A0static int mpc52xx_fec_open(struct net_device *dev)
> =A0{
> =A0 =A0 =A0 =A0struct mpc52xx_fec_priv *priv =3D netdev_priv(dev);
> =A0 =A0 =A0 =A0int err =3D -EBUSY;
>
> + =A0 =A0 =A0 if (priv->phy_node) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->phydev =3D of_phy_connect(priv->ndev,=
 priv->phy_node,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 mpc52xx_fec_adjust_link, 0, 0);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!priv->phydev) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&dev->dev, "of_phy_=
connect failed\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_start(priv->phydev);
> + =A0 =A0 =A0 }
> +
> =A0 =A0 =A0 =A0if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHA=
RED,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0DRIVER_NAME "_ctrl", dev))=
 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dev_err(&dev->dev, "ctrl interrupt request=
 failed\n");
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto free_phy;
> =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0DRIVER_NAME "_rx", dev)) {
> @@ -319,10 +259,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto free_irqs;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 err =3D mpc52xx_fec_phy_start(dev);
> - =A0 =A0 =A0 if (err)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto free_skbs;
> -
> =A0 =A0 =A0 =A0bcom_enable(priv->rx_dmatsk);
> =A0 =A0 =A0 =A0bcom_enable(priv->tx_dmatsk);
>
> @@ -332,16 +268,18 @@ static int mpc52xx_fec_open(struct net_device *dev)
>
> =A0 =A0 =A0 =A0return 0;
>
> - free_skbs:
> - =A0 =A0 =A0 mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
> -
> =A0free_irqs:
> =A0 =A0 =A0 =A0free_irq(priv->t_irq, dev);
> =A0free_2irqs:
> =A0 =A0 =A0 =A0free_irq(priv->r_irq, dev);
> =A0free_ctrl_irq:
> =A0 =A0 =A0 =A0free_irq(dev->irq, dev);
> - out:
> + free_phy:
> + =A0 =A0 =A0 if (priv->phydev) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_stop(priv->phydev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_disconnect(priv->phydev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->phydev =3D NULL;
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0return err;
> =A0}
> @@ -360,7 +298,12 @@ static int mpc52xx_fec_close(struct net_device *dev)
> =A0 =A0 =A0 =A0free_irq(priv->r_irq, dev);
> =A0 =A0 =A0 =A0free_irq(priv->t_irq, dev);
>
> - =A0 =A0 =A0 mpc52xx_fec_phy_stop(dev);
> + =A0 =A0 =A0 if (priv->phydev) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* power down phy */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_stop(priv->phydev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_disconnect(priv->phydev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->phydev =3D NULL;
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0return 0;
> =A0}
> @@ -700,7 +643,7 @@ static void mpc52xx_fec_hw_init(struct net_device *de=
v)
> =A0 =A0 =A0 =A0/* set phy speed.
> =A0 =A0 =A0 =A0 * this can't be done in phy driver, since it needs to be =
called
> =A0 =A0 =A0 =A0 * before fec stuff (even on resume) */
> - =A0 =A0 =A0 mpc52xx_fec_phy_hw_init(priv);
> + =A0 =A0 =A0 out_be32(&fec->mii_speed, priv->mdio_speed);
> =A0}
>
> =A0/**
> @@ -736,7 +679,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
> =A0 =A0 =A0 =A0rcntrl =3D FEC_RX_BUFFER_SIZE << 16; =A0 =A0 =A0/* max fra=
me length */
> =A0 =A0 =A0 =A0rcntrl |=3D FEC_RCNTRL_FCE;
>
> - =A0 =A0 =A0 if (priv->phy_addr !=3D FEC5200_PHYADDR_7WIRE)
> + =A0 =A0 =A0 if (!priv->seven_wire_mode)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0rcntrl |=3D FEC_RCNTRL_MII_MODE;
>
> =A0 =A0 =A0 =A0if (priv->duplex =3D=3D DUPLEX_FULL)
> @@ -802,8 +745,6 @@ static void mpc52xx_fec_stop(struct net_device *dev)
>
> =A0 =A0 =A0 =A0/* Stop FEC */
> =A0 =A0 =A0 =A0out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL=
_ETHER_EN);
> -
> - =A0 =A0 =A0 return;
> =A0}
>
> =A0/* reset fec and bestcomm tasks */
> @@ -821,9 +762,11 @@ static void mpc52xx_fec_reset(struct net_device *dev=
)
>
> =A0 =A0 =A0 =A0mpc52xx_fec_hw_init(dev);
>
> - =A0 =A0 =A0 phy_stop(priv->phydev);
> - =A0 =A0 =A0 phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
> - =A0 =A0 =A0 phy_start(priv->phydev);
> + =A0 =A0 =A0 if (priv->phydev) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_stop(priv->phydev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_write(priv->phydev, MII_BMCR, BMCR_RESE=
T);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_start(priv->phydev);
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0bcom_fec_rx_reset(priv->rx_dmatsk);
> =A0 =A0 =A0 =A0bcom_fec_tx_reset(priv->tx_dmatsk);
> @@ -923,7 +866,6 @@ static const struct net_device_ops mpc52xx_fec_netdev=
_ops =3D {
> =A0#endif
> =A0};
>
> -
> =A0static int __devinit
> =A0mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *mat=
ch)
> =A0{
> @@ -931,8 +873,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct =
of_device_id *match)
> =A0 =A0 =A0 =A0struct net_device *ndev;
> =A0 =A0 =A0 =A0struct mpc52xx_fec_priv *priv =3D NULL;
> =A0 =A0 =A0 =A0struct resource mem;
> - =A0 =A0 =A0 struct device_node *phy_node;
> - =A0 =A0 =A0 const phandle *phy_handle;
> =A0 =A0 =A0 =A0const u32 *prop;
> =A0 =A0 =A0 =A0int prop_size;
>
> @@ -945,6 +885,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct =
of_device_id *match)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -ENOMEM;
>
> =A0 =A0 =A0 =A0priv =3D netdev_priv(ndev);
> + =A0 =A0 =A0 priv->ndev =3D ndev;
>
> =A0 =A0 =A0 =A0/* Reserve FEC control zone */
> =A0 =A0 =A0 =A0rv =3D of_address_to_resource(op->node, 0, &mem);
> @@ -968,6 +909,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct =
of_device_id *match)
> =A0 =A0 =A0 =A0ndev->watchdog_timeo =A0 =A0=3D FEC_WATCHDOG_TIMEOUT;
> =A0 =A0 =A0 =A0ndev->base_addr =A0 =A0 =A0 =A0 =3D mem.start;
> =A0 =A0 =A0 =A0ndev->netdev_ops =3D &mpc52xx_fec_netdev_ops;
> + =A0 =A0 =A0 SET_NETDEV_DEV(ndev, &op->dev);
>
> =A0 =A0 =A0 =A0priv->t_irq =3D priv->r_irq =3D ndev->irq =3D NO_IRQ; /* I=
RQ are free for now */
>
> @@ -1017,14 +959,9 @@ mpc52xx_fec_probe(struct of_device *op, const struc=
t of_device_id *match)
> =A0 =A0 =A0 =A0 */
>
> =A0 =A0 =A0 =A0/* Start with safe defaults for link connection */
> - =A0 =A0 =A0 priv->phy_addr =3D FEC5200_PHYADDR_NONE;
> - =A0 =A0 =A0 priv->speed =3D 100;
> + =A0 =A0 =A0 priv->speed =3D 10;
> =A0 =A0 =A0 =A0priv->duplex =3D DUPLEX_HALF;
> - =A0 =A0 =A0 priv->phy_speed =3D ((mpc52xx_find_ipb_freq(op->node) >> 20=
) / 5) << 1;
> -
> - =A0 =A0 =A0 /* the 7-wire property means don't use MII mode */
> - =A0 =A0 =A0 if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->phy_addr =3D FEC5200_PHYADDR_7WIRE;
> + =A0 =A0 =A0 priv->mdio_speed =3D ((mpc52xx_find_ipb_freq(op->node) >> 2=
0) / 5) << 1;
>
> =A0 =A0 =A0 =A0/* The current speed preconfigures the speed of the MII li=
nk */
> =A0 =A0 =A0 =A0prop =3D of_get_property(op->node, "current-speed", &prop_=
size);
> @@ -1033,43 +970,23 @@ mpc52xx_fec_probe(struct of_device *op, const stru=
ct of_device_id *match)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0priv->duplex =3D prop[1] ? DUPLEX_FULL : D=
UPLEX_HALF;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 /* If there is a phy handle, setup link to that phy */
> - =A0 =A0 =A0 phy_handle =3D of_get_property(op->node, "phy-handle", &pro=
p_size);
> - =A0 =A0 =A0 if (phy_handle && (prop_size >=3D sizeof(phandle))) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_node =3D of_find_node_by_phandle(*phy_h=
andle);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 prop =3D of_get_property(phy_node, "reg", &=
prop_size);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (prop && (prop_size >=3D sizeof(u32)))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((*prop >=3D 0) && (*pro=
p < PHY_MAX_ADDR))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->phy_a=
ddr =3D *prop;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(phy_node);
> + =A0 =A0 =A0 /* If there is a phy handle, then get the PHY node */
> + =A0 =A0 =A0 priv->phy_node =3D of_parse_phandle(op->node, "phy-handle",=
 0);
> +
> + =A0 =A0 =A0 /* the 7-wire property means don't use MII mode */
> + =A0 =A0 =A0 if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->seven_wire_mode =3D 1;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_info(&ndev->dev, "using 7-wire PHY mode=
\n");
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0/* Hardware init */
> =A0 =A0 =A0 =A0mpc52xx_fec_hw_init(ndev);
> -
> =A0 =A0 =A0 =A0mpc52xx_fec_reset_stats(ndev);
>
> - =A0 =A0 =A0 SET_NETDEV_DEV(ndev, &op->dev);
> -
> - =A0 =A0 =A0 /* Register the new network device */
> =A0 =A0 =A0 =A0rv =3D register_netdev(ndev);
> =A0 =A0 =A0 =A0if (rv < 0)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto probe_error;
>
> - =A0 =A0 =A0 /* Now report the link setup */
> - =A0 =A0 =A0 switch (priv->phy_addr) {
> - =A0 =A0 =A0 =A0case FEC5200_PHYADDR_NONE:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_info(&ndev->dev, "Fixed speed MII link:=
 %i%cD\n",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0priv->speed, priv->duple=
x ? 'F' : 'H');
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 =A0case FEC5200_PHYADDR_7WIRE:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_info(&ndev->dev, "using 7-wire PHY mode=
\n");
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 =A0default:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_info(&ndev->dev, "Using PHY at MDIO add=
ress %i\n",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0priv->phy_addr);
> - =A0 =A0 =A0 }
> -
> =A0 =A0 =A0 =A0/* We're done ! */
> =A0 =A0 =A0 =A0dev_set_drvdata(&op->dev, ndev);
>
> diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.=
c
> index dd9bfa4..fec9f24 100644
> --- a/drivers/net/fec_mpc52xx_phy.c
> +++ b/drivers/net/fec_mpc52xx_phy.c
> @@ -14,12 +14,14 @@
> =A0#include <linux/netdevice.h>
> =A0#include <linux/phy.h>
> =A0#include <linux/of_platform.h>
> +#include <linux/of_mdio.h>
> =A0#include <asm/io.h>
> =A0#include <asm/mpc52xx.h>
> =A0#include "fec_mpc52xx.h"
>
> =A0struct mpc52xx_fec_mdio_priv {
> =A0 =A0 =A0 =A0struct mpc52xx_fec __iomem *regs;
> + =A0 =A0 =A0 int mdio_irqs[PHY_MAX_ADDR];
> =A0};
>
> =A0static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
> @@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bu=
s, int phy_id,
> =A0{
> =A0 =A0 =A0 =A0struct mpc52xx_fec_mdio_priv *priv =3D bus->priv;
> =A0 =A0 =A0 =A0struct mpc52xx_fec __iomem *fec;
> - =A0 =A0 =A0 int tries =3D 100;
> + =A0 =A0 =A0 int tries =3D 3;
>
> =A0 =A0 =A0 =A0value |=3D (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DAT=
A_PA_MSK;
> =A0 =A0 =A0 =A0value |=3D (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_R=
A_MSK;
> @@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bu=
s, int phy_id,
>
> =A0 =A0 =A0 =A0/* wait for it to finish, this takes about 23 us on lite52=
00b */
> =A0 =A0 =A0 =A0while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --trie=
s)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 udelay(5);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 msleep(1);
>
> =A0 =A0 =A0 =A0if (!tries)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -ETIMEDOUT;
> @@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
> =A0{
> =A0 =A0 =A0 =A0struct device *dev =3D &of->dev;
> =A0 =A0 =A0 =A0struct device_node *np =3D of->node;
> - =A0 =A0 =A0 struct device_node *child =3D NULL;
> =A0 =A0 =A0 =A0struct mii_bus *bus;
> =A0 =A0 =A0 =A0struct mpc52xx_fec_mdio_priv *priv;
> =A0 =A0 =A0 =A0struct resource res =3D {};
> @@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of=
,
> =A0 =A0 =A0 =A0bus->write =3D mpc52xx_fec_mdio_write;
>
> =A0 =A0 =A0 =A0/* setup irqs */
> - =A0 =A0 =A0 bus->irq =3D kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GF=
P_KERNEL);
> - =A0 =A0 =A0 if (bus->irq =3D=3D NULL) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 err =3D -ENOMEM;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out_free;
> - =A0 =A0 =A0 }
> - =A0 =A0 =A0 for (i=3D0; i<PHY_MAX_ADDR; i++)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus->irq[i] =3D PHY_POLL;
> -
> - =A0 =A0 =A0 while ((child =3D of_get_next_child(np, child)) !=3D NULL) =
{
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 int irq =3D irq_of_parse_and_map(child, 0);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (irq !=3D NO_IRQ) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const u32 *id =3D of_get_pr=
operty(child, "reg", NULL);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (id)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus->irq[*i=
d] =3D irq;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 }
> + =A0 =A0 =A0 bus->irq =3D priv->mdio_irqs;
>
> =A0 =A0 =A0 =A0/* setup registers */
> =A0 =A0 =A0 =A0err =3D of_address_to_resource(np, 0, &res);
> @@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *o=
f,
> =A0 =A0 =A0 =A0out_be32(&priv->regs->mii_speed,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0((mpc52xx_find_ipb_freq(of->node) >> 20) /=
 5) << 1);
>
> - =A0 =A0 =A0 err =3D mdiobus_register(bus);
> + =A0 =A0 =A0 err =3D of_mdiobus_register(bus, np);
> =A0 =A0 =A0 =A0if (err)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_unmap;
>
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions
  2009-03-19  5:00 ` [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions Grant Likely
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/net/gianfar.c     |   94 ++++++++++++++-------------------------------
>  drivers/net/gianfar.h     |    3 +
>  drivers/net/gianfar_mii.c |   52 +------------------------
>  3 files changed, 34 insertions(+), 115 deletions(-)
>
>
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index 9831b3f..0521267 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -75,6 +75,7 @@
>  #include <linux/if_vlan.h>
>  #include <linux/spinlock.h>
>  #include <linux/mm.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>  #include <linux/ip.h>
>  #include <linux/tcp.h>
> @@ -155,17 +156,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
>
>  static int gfar_of_init(struct net_device *dev)
>  {
> -       struct device_node *phy, *mdio;
> -       const unsigned int *id;
>        const char *model;
>        const char *ctype;
>        const void *mac_addr;
> -       const phandle *ph;
>        u64 addr, size;
>        int err = 0;
>        struct gfar_private *priv = netdev_priv(dev);
>        struct device_node *np = priv->node;
> -       char bus_name[MII_BUS_ID_SIZE];
>
>        if (!np || !of_device_is_available(np))
>                return -ENODEV;
> @@ -228,8 +225,8 @@ static int gfar_of_init(struct net_device *dev)
>        if (of_get_property(np, "fsl,magic-packet", NULL))
>                priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
>
> -       ph = of_get_property(np, "phy-handle", NULL);
> -       if (ph == NULL) {
> +       priv->phy_node = of_parse_phandle(np, "phy-device", 0);
> +       if (!priv->phy_node) {
>                u32 *fixed_link;
>
>                fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
> @@ -237,57 +234,10 @@ static int gfar_of_init(struct net_device *dev)
>                        err = -ENODEV;
>                        goto err_out;
>                }
> -
> -               snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id),
> -                               PHY_ID_FMT, "0", fixed_link[0]);
> -       } else {
> -               phy = of_find_node_by_phandle(*ph);
> -
> -               if (phy == NULL) {
> -                       err = -ENODEV;
> -                       goto err_out;
> -               }
> -
> -               mdio = of_get_parent(phy);
> -
> -               id = of_get_property(phy, "reg", NULL);
> -
> -               of_node_put(phy);
> -               of_node_put(mdio);
> -
> -               gfar_mdio_bus_name(bus_name, mdio);
> -               snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
> -                               bus_name, *id);
>        }
>
>        /* Find the TBI PHY.  If it's not there, we don't support SGMII */
> -       ph = of_get_property(np, "tbi-handle", NULL);
> -       if (ph) {
> -               struct device_node *tbi = of_find_node_by_phandle(*ph);
> -               struct of_device *ofdev;
> -               struct mii_bus *bus;
> -
> -               if (!tbi)
> -                       return 0;
> -
> -               mdio = of_get_parent(tbi);
> -               if (!mdio)
> -                       return 0;
> -
> -               ofdev = of_find_device_by_node(mdio);
> -
> -               of_node_put(mdio);
> -
> -               id = of_get_property(tbi, "reg", NULL);
> -               if (!id)
> -                       return 0;
> -
> -               of_node_put(tbi);
> -
> -               bus = dev_get_drvdata(&ofdev->dev);
> -
> -               priv->tbiphy = bus->phy_map[*id];
> -       }
> +       priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
>
>        return 0;
>
> @@ -661,7 +611,6 @@ static int init_phy(struct net_device *dev)
>        uint gigabit_support =
>                priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
>                SUPPORTED_1000baseT_Full : 0;
> -       struct phy_device *phydev;
>        phy_interface_t interface;
>
>        priv->oldlink = 0;
> @@ -670,23 +619,38 @@ static int init_phy(struct net_device *dev)
>
>        interface = gfar_get_interface(dev);
>
> -       phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface);
> +       if (priv->phy_node) {
> +               priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link,
> +                                             0, interface);
> +               if (!priv->phydev) {
> +                       dev_err(&dev->dev, "error: Could not attach to PHY\n");
> +                       return -ENODEV;
> +               }
> +       }
> +
> +       if (priv->tbi_node) {
> +               priv->tbiphy = of_phy_connect(dev, priv->tbi_node, &adjust_link,
> +                                             0, interface);
> +               if (!priv->tbiphy) {
> +                       dev_err(&dev->dev, "error: Could not attach to TBI\n");
> +                       goto err_tbiphy;
> +               }
> +       }
>
>        if (interface == PHY_INTERFACE_MODE_SGMII)
>                gfar_configure_serdes(dev);
>
> -       if (IS_ERR(phydev)) {
> -               printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
> -               return PTR_ERR(phydev);
> -       }
> -
>        /* Remove any features not supported by the controller */
> -       phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
> -       phydev->advertising = phydev->supported;
> -
> -       priv->phydev = phydev;
> +       priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
> +       priv->phydev->advertising = priv->phydev->supported;
>
>        return 0;
> +
> + err_tbiphy:
> +       if (priv->phy_node)
> +               phy_disconnect(priv->phydev);
> +       priv->phydev = NULL;
> +       return -ENODEV;
>  }
>
>  /*
> diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
> index eaa8689..d3d56a9 100644
> --- a/drivers/net/gianfar.h
> +++ b/drivers/net/gianfar.h
> @@ -775,7 +775,8 @@ struct gfar_private {
>        spinlock_t bflock;
>
>        phy_interface_t interface;
> -       char    phy_bus_id[BUS_ID_SIZE];
> +       struct device_node *phy_node;
> +       struct device_node *tbi_node;
>        u32 device_flags;
>        unsigned char rx_csum_enable:1,
>                extended_hash:1,
> diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
> index f49a426..c6d77bd 100644
> --- a/drivers/net/gianfar_mii.c
> +++ b/drivers/net/gianfar_mii.c
> @@ -35,6 +35,7 @@
>  #include <linux/mii.h>
>  #include <linux/phy.h>
>  #include <linux/of.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>
>  #include <asm/io.h>
> @@ -152,45 +153,6 @@ static int gfar_mdio_reset(struct mii_bus *bus)
>        return 0;
>  }
>
> -/* Allocate an array which provides irq #s for each PHY on the given bus */
> -static int *create_irq_map(struct device_node *np)
> -{
> -       int *irqs;
> -       int i;
> -       struct device_node *child = NULL;
> -
> -       irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
> -
> -       if (!irqs)
> -               return NULL;
> -
> -       for (i = 0; i < PHY_MAX_ADDR; i++)
> -               irqs[i] = PHY_POLL;
> -
> -       while ((child = of_get_next_child(np, child)) != NULL) {
> -               int irq = irq_of_parse_and_map(child, 0);
> -               const u32 *id;
> -
> -               if (irq == NO_IRQ)
> -                       continue;
> -
> -               id = of_get_property(child, "reg", NULL);
> -
> -               if (!id)
> -                       continue;
> -
> -               if (*id < PHY_MAX_ADDR && *id >= 0)
> -                       irqs[*id] = irq;
> -               else
> -                       printk(KERN_WARNING "%s: "
> -                                       "%d is not a valid PHY address\n",
> -                                       np->full_name, *id);
> -       }
> -
> -       return irqs;
> -}
> -
> -
>  void gfar_mdio_bus_name(char *name, struct device_node *np)
>  {
>        const u32 *reg;
> @@ -253,7 +215,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
>
>        new_bus->priv = (void __force *)regs;
>
> -       new_bus->irq = create_irq_map(np);
> +       new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
>
>        if (new_bus->irq == NULL) {
>                err = -ENOMEM;
> @@ -301,15 +263,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
>
>        gfar_write(&enet_regs->tbipa, tbiaddr);
>
> -       /*
> -        * The TBIPHY-only buses will find PHYs at every address,
> -        * so we mask them all but the TBI
> -        */
> -       if (!of_device_is_compatible(np, "fsl,gianfar-mdio"))
> -               new_bus->phy_mask = ~(1 << tbiaddr);
> -
> -       err = mdiobus_register(new_bus);
> -
> +       err = of_mdiobus_register(new_bus, np);
>        if (err != 0) {
>                printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
>                                new_bus->name);
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/net/gianfar.c =A0 =A0 | =A0 94 ++++++++++++++-----------------=
--------------
> =A0drivers/net/gianfar.h =A0 =A0 | =A0 =A03 +
> =A0drivers/net/gianfar_mii.c | =A0 52 +------------------------
> =A03 files changed, 34 insertions(+), 115 deletions(-)
>
>
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index 9831b3f..0521267 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -75,6 +75,7 @@
> =A0#include <linux/if_vlan.h>
> =A0#include <linux/spinlock.h>
> =A0#include <linux/mm.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
> =A0#include <linux/ip.h>
> =A0#include <linux/tcp.h>
> @@ -155,17 +156,13 @@ static inline int gfar_uses_fcb(struct gfar_private=
 *priv)
>
> =A0static int gfar_of_init(struct net_device *dev)
> =A0{
> - =A0 =A0 =A0 struct device_node *phy, *mdio;
> - =A0 =A0 =A0 const unsigned int *id;
> =A0 =A0 =A0 =A0const char *model;
> =A0 =A0 =A0 =A0const char *ctype;
> =A0 =A0 =A0 =A0const void *mac_addr;
> - =A0 =A0 =A0 const phandle *ph;
> =A0 =A0 =A0 =A0u64 addr, size;
> =A0 =A0 =A0 =A0int err =3D 0;
> =A0 =A0 =A0 =A0struct gfar_private *priv =3D netdev_priv(dev);
> =A0 =A0 =A0 =A0struct device_node *np =3D priv->node;
> - =A0 =A0 =A0 char bus_name[MII_BUS_ID_SIZE];
>
> =A0 =A0 =A0 =A0if (!np || !of_device_is_available(np))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -ENODEV;
> @@ -228,8 +225,8 @@ static int gfar_of_init(struct net_device *dev)
> =A0 =A0 =A0 =A0if (of_get_property(np, "fsl,magic-packet", NULL))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0priv->device_flags |=3D FSL_GIANFAR_DEV_HA=
S_MAGIC_PACKET;
>
> - =A0 =A0 =A0 ph =3D of_get_property(np, "phy-handle", NULL);
> - =A0 =A0 =A0 if (ph =3D=3D NULL) {
> + =A0 =A0 =A0 priv->phy_node =3D of_parse_phandle(np, "phy-device", 0);
> + =A0 =A0 =A0 if (!priv->phy_node) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0u32 *fixed_link;
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0fixed_link =3D (u32 *)of_get_property(np, =
"fixed-link", NULL);
> @@ -237,57 +234,10 @@ static int gfar_of_init(struct net_device *dev)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0err =3D -ENODEV;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto err_out;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 snprintf(priv->phy_bus_id, sizeof(priv->phy=
_bus_id),
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PHY_ID_FMT,=
 "0", fixed_link[0]);
> - =A0 =A0 =A0 } else {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy =3D of_find_node_by_phandle(*ph);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (phy =3D=3D NULL) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 err =3D -ENODEV;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_out;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 mdio =3D of_get_parent(phy);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 id =3D of_get_property(phy, "reg", NULL);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(phy);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(mdio);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 gfar_mdio_bus_name(bus_name, mdio);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 snprintf(priv->phy_bus_id, sizeof(priv->phy=
_bus_id), "%s:%02x",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus_name, *=
id);
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0/* Find the TBI PHY. =A0If it's not there, we don't suppor=
t SGMII */
> - =A0 =A0 =A0 ph =3D of_get_property(np, "tbi-handle", NULL);
> - =A0 =A0 =A0 if (ph) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct device_node *tbi =3D of_find_node_by=
_phandle(*ph);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct of_device *ofdev;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct mii_bus *bus;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!tbi)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return 0;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 mdio =3D of_get_parent(tbi);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!mdio)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return 0;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 ofdev =3D of_find_device_by_node(mdio);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(mdio);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 id =3D of_get_property(tbi, "reg", NULL);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!id)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return 0;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(tbi);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus =3D dev_get_drvdata(&ofdev->dev);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->tbiphy =3D bus->phy_map[*id];
> - =A0 =A0 =A0 }
> + =A0 =A0 =A0 priv->tbi_node =3D of_parse_phandle(np, "tbi-handle", 0);
>
> =A0 =A0 =A0 =A0return 0;
>
> @@ -661,7 +611,6 @@ static int init_phy(struct net_device *dev)
> =A0 =A0 =A0 =A0uint gigabit_support =3D
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0priv->device_flags & FSL_GIANFAR_DEV_HAS_G=
IGABIT ?
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0SUPPORTED_1000baseT_Full : 0;
> - =A0 =A0 =A0 struct phy_device *phydev;
> =A0 =A0 =A0 =A0phy_interface_t interface;
>
> =A0 =A0 =A0 =A0priv->oldlink =3D 0;
> @@ -670,23 +619,38 @@ static int init_phy(struct net_device *dev)
>
> =A0 =A0 =A0 =A0interface =3D gfar_get_interface(dev);
>
> - =A0 =A0 =A0 phydev =3D phy_connect(dev, priv->phy_bus_id, &adjust_link,=
 0, interface);
> + =A0 =A0 =A0 if (priv->phy_node) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->phydev =3D of_phy_connect(dev, priv->=
phy_node, &adjust_link,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 0, interface);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!priv->phydev) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&dev->dev, "error: =
Could not attach to PHY\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 if (priv->tbi_node) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->tbiphy =3D of_phy_connect(dev, priv->=
tbi_node, &adjust_link,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 0, interface);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!priv->tbiphy) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&dev->dev, "error: =
Could not attach to TBI\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_tbiphy;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0if (interface =3D=3D PHY_INTERFACE_MODE_SGMII)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gfar_configure_serdes(dev);
>
> - =A0 =A0 =A0 if (IS_ERR(phydev)) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "%s: Could not attach to PH=
Y\n", dev->name);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return PTR_ERR(phydev);
> - =A0 =A0 =A0 }
> -
> =A0 =A0 =A0 =A0/* Remove any features not supported by the controller */
> - =A0 =A0 =A0 phydev->supported &=3D (GFAR_SUPPORTED | gigabit_support);
> - =A0 =A0 =A0 phydev->advertising =3D phydev->supported;
> -
> - =A0 =A0 =A0 priv->phydev =3D phydev;
> + =A0 =A0 =A0 priv->phydev->supported &=3D (GFAR_SUPPORTED | gigabit_supp=
ort);
> + =A0 =A0 =A0 priv->phydev->advertising =3D priv->phydev->supported;
>
> =A0 =A0 =A0 =A0return 0;
> +
> + err_tbiphy:
> + =A0 =A0 =A0 if (priv->phy_node)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_disconnect(priv->phydev);
> + =A0 =A0 =A0 priv->phydev =3D NULL;
> + =A0 =A0 =A0 return -ENODEV;
> =A0}
>
> =A0/*
> diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
> index eaa8689..d3d56a9 100644
> --- a/drivers/net/gianfar.h
> +++ b/drivers/net/gianfar.h
> @@ -775,7 +775,8 @@ struct gfar_private {
> =A0 =A0 =A0 =A0spinlock_t bflock;
>
> =A0 =A0 =A0 =A0phy_interface_t interface;
> - =A0 =A0 =A0 char =A0 =A0phy_bus_id[BUS_ID_SIZE];
> + =A0 =A0 =A0 struct device_node *phy_node;
> + =A0 =A0 =A0 struct device_node *tbi_node;
> =A0 =A0 =A0 =A0u32 device_flags;
> =A0 =A0 =A0 =A0unsigned char rx_csum_enable:1,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0extended_hash:1,
> diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
> index f49a426..c6d77bd 100644
> --- a/drivers/net/gianfar_mii.c
> +++ b/drivers/net/gianfar_mii.c
> @@ -35,6 +35,7 @@
> =A0#include <linux/mii.h>
> =A0#include <linux/phy.h>
> =A0#include <linux/of.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
>
> =A0#include <asm/io.h>
> @@ -152,45 +153,6 @@ static int gfar_mdio_reset(struct mii_bus *bus)
> =A0 =A0 =A0 =A0return 0;
> =A0}
>
> -/* Allocate an array which provides irq #s for each PHY on the given bus=
 */
> -static int *create_irq_map(struct device_node *np)
> -{
> - =A0 =A0 =A0 int *irqs;
> - =A0 =A0 =A0 int i;
> - =A0 =A0 =A0 struct device_node *child =3D NULL;
> -
> - =A0 =A0 =A0 irqs =3D kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
> -
> - =A0 =A0 =A0 if (!irqs)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
> -
> - =A0 =A0 =A0 for (i =3D 0; i < PHY_MAX_ADDR; i++)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 irqs[i] =3D PHY_POLL;
> -
> - =A0 =A0 =A0 while ((child =3D of_get_next_child(np, child)) !=3D NULL) =
{
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 int irq =3D irq_of_parse_and_map(child, 0);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 const u32 *id;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (irq =3D=3D NO_IRQ)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 id =3D of_get_property(child, "reg", NULL);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!id)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (*id < PHY_MAX_ADDR && *id >=3D 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irqs[*id] =3D irq;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_WARNING "%s: "
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 "%d is not a valid PHY address\n",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 np->full_name, *id);
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 return irqs;
> -}
> -
> -
> =A0void gfar_mdio_bus_name(char *name, struct device_node *np)
> =A0{
> =A0 =A0 =A0 =A0const u32 *reg;
> @@ -253,7 +215,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
>
> =A0 =A0 =A0 =A0new_bus->priv =3D (void __force *)regs;
>
> - =A0 =A0 =A0 new_bus->irq =3D create_irq_map(np);
> + =A0 =A0 =A0 new_bus->irq =3D kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KER=
NEL);
>
> =A0 =A0 =A0 =A0if (new_bus->irq =3D=3D NULL) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0err =3D -ENOMEM;
> @@ -301,15 +263,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
>
> =A0 =A0 =A0 =A0gfar_write(&enet_regs->tbipa, tbiaddr);
>
> - =A0 =A0 =A0 /*
> - =A0 =A0 =A0 =A0* The TBIPHY-only buses will find PHYs at every address,
> - =A0 =A0 =A0 =A0* so we mask them all but the TBI
> - =A0 =A0 =A0 =A0*/
> - =A0 =A0 =A0 if (!of_device_is_compatible(np, "fsl,gianfar-mdio"))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_bus->phy_mask =3D ~(1 << tbiaddr);
> -
> - =A0 =A0 =A0 err =3D mdiobus_register(new_bus);
> -
> + =A0 =A0 =A0 err =3D of_mdiobus_register(new_bus, np);
> =A0 =A0 =A0 =A0if (err !=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk (KERN_ERR "%s: Cannot register as M=
DIO bus\n",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0new_bus->n=
ame);
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 7/9] net/ucc_geth: Rework ucc_geth driver to use OF PHY/MDIO helper functions
  2009-03-19  5:00 ` [PATCH 7/9] net/ucc_geth: Rework ucc_geth " Grant Likely
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/net/ucc_geth.c     |   27 ++++++---------------------
>  drivers/net/ucc_geth_mii.c |   17 +++--------------
>  2 files changed, 9 insertions(+), 35 deletions(-)
>
>
> diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
> index e879868..45bb627 100644
> --- a/drivers/net/ucc_geth.c
> +++ b/drivers/net/ucc_geth.c
> @@ -28,6 +28,7 @@
>  #include <linux/mii.h>
>  #include <linux/phy.h>
>  #include <linux/workqueue.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>
>  #include <asm/uaccess.h>
> @@ -1537,35 +1538,19 @@ static int init_phy(struct net_device *dev)
>  {
>        struct ucc_geth_private *priv = netdev_priv(dev);
>        struct device_node *np = priv->node;
> -       struct device_node *phy, *mdio;
> -       const phandle *ph;
> -       char bus_name[MII_BUS_ID_SIZE];
> -       const unsigned int *id;
> +       struct device_node *phy;
>        struct phy_device *phydev;
> -       char phy_id[BUS_ID_SIZE];
>
>        priv->oldlink = 0;
>        priv->oldspeed = 0;
>        priv->oldduplex = -1;
>
> -       ph = of_get_property(np, "phy-handle", NULL);
> -       phy = of_find_node_by_phandle(*ph);
> -       mdio = of_get_parent(phy);
> -
> -       id = of_get_property(phy, "reg", NULL);
> -
> +       phy = of_parse_phandle(np, "phy-handle", 0);
> +       phydev = of_phy_connect(dev, phy, &adjust_link, 0, priv->phy_interface);
>        of_node_put(phy);
> -       of_node_put(mdio);
> -
> -       uec_mdio_bus_name(bus_name, mdio);
> -       snprintf(phy_id, sizeof(phy_id), "%s:%02x",
> -                                bus_name, *id);
> -
> -       phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
> -
> -       if (IS_ERR(phydev)) {
> +       if (!phydev) {
>                printk("%s: Could not attach to PHY\n", dev->name);
> -               return PTR_ERR(phydev);
> +               return -ENODEV;
>        }
>
>        phydev->supported &= (ADVERTISED_10baseT_Half |
> diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
> index 0ada4ed..9f2492f 100644
> --- a/drivers/net/ucc_geth_mii.c
> +++ b/drivers/net/ucc_geth_mii.c
> @@ -36,6 +36,7 @@
>  #include <linux/mii.h>
>  #include <linux/phy.h>
>  #include <linux/fsl_devices.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>
>  #include <asm/io.h>
> @@ -135,11 +136,10 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
>  {
>        struct device *device = &ofdev->dev;
>        struct device_node *np = ofdev->node, *tempnp = NULL;
> -       struct device_node *child = NULL;
>        struct ucc_mii_mng __iomem *regs;
>        struct mii_bus *new_bus;
>        struct resource res;
> -       int k, err = 0;
> +       int err = 0;
>
>        new_bus = mdiobus_alloc();
>        if (NULL == new_bus)
> @@ -165,17 +165,6 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
>                goto reg_map_fail;
>        }
>
> -       for (k = 0; k < 32; k++)
> -               new_bus->irq[k] = PHY_POLL;
> -
> -       while ((child = of_get_next_child(np, child)) != NULL) {
> -               int irq = irq_of_parse_and_map(child, 0);
> -               if (irq != NO_IRQ) {
> -                       const u32 *id = of_get_property(child, "reg", NULL);
> -                       new_bus->irq[*id] = irq;
> -               }
> -       }
> -
>        /* Set the base address */
>        regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
>
> @@ -220,7 +209,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
>                }
>        }
>
> -       err = mdiobus_register(new_bus);
> +       err = of_mdiobus_register(new_bus, np);
>        if (0 != err) {
>                printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
>                       new_bus->name);
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 7/9] net/ucc_geth: Rework ucc_geth driver to use OF PHY/MDIO helper functions
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/net/ucc_geth.c =A0 =A0 | =A0 27 ++++++---------------------
> =A0drivers/net/ucc_geth_mii.c | =A0 17 +++--------------
> =A02 files changed, 9 insertions(+), 35 deletions(-)
>
>
> diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
> index e879868..45bb627 100644
> --- a/drivers/net/ucc_geth.c
> +++ b/drivers/net/ucc_geth.c
> @@ -28,6 +28,7 @@
> =A0#include <linux/mii.h>
> =A0#include <linux/phy.h>
> =A0#include <linux/workqueue.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
>
> =A0#include <asm/uaccess.h>
> @@ -1537,35 +1538,19 @@ static int init_phy(struct net_device *dev)
> =A0{
> =A0 =A0 =A0 =A0struct ucc_geth_private *priv =3D netdev_priv(dev);
> =A0 =A0 =A0 =A0struct device_node *np =3D priv->node;
> - =A0 =A0 =A0 struct device_node *phy, *mdio;
> - =A0 =A0 =A0 const phandle *ph;
> - =A0 =A0 =A0 char bus_name[MII_BUS_ID_SIZE];
> - =A0 =A0 =A0 const unsigned int *id;
> + =A0 =A0 =A0 struct device_node *phy;
> =A0 =A0 =A0 =A0struct phy_device *phydev;
> - =A0 =A0 =A0 char phy_id[BUS_ID_SIZE];
>
> =A0 =A0 =A0 =A0priv->oldlink =3D 0;
> =A0 =A0 =A0 =A0priv->oldspeed =3D 0;
> =A0 =A0 =A0 =A0priv->oldduplex =3D -1;
>
> - =A0 =A0 =A0 ph =3D of_get_property(np, "phy-handle", NULL);
> - =A0 =A0 =A0 phy =3D of_find_node_by_phandle(*ph);
> - =A0 =A0 =A0 mdio =3D of_get_parent(phy);
> -
> - =A0 =A0 =A0 id =3D of_get_property(phy, "reg", NULL);
> -
> + =A0 =A0 =A0 phy =3D of_parse_phandle(np, "phy-handle", 0);
> + =A0 =A0 =A0 phydev =3D of_phy_connect(dev, phy, &adjust_link, 0, priv->=
phy_interface);
> =A0 =A0 =A0 =A0of_node_put(phy);
> - =A0 =A0 =A0 of_node_put(mdio);
> -
> - =A0 =A0 =A0 uec_mdio_bus_name(bus_name, mdio);
> - =A0 =A0 =A0 snprintf(phy_id, sizeof(phy_id), "%s:%02x",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bus_name=
, *id);
> -
> - =A0 =A0 =A0 phydev =3D phy_connect(dev, phy_id, &adjust_link, 0, priv->=
phy_interface);
> -
> - =A0 =A0 =A0 if (IS_ERR(phydev)) {
> + =A0 =A0 =A0 if (!phydev) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk("%s: Could not attach to PHY\n", de=
v->name);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return PTR_ERR(phydev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0phydev->supported &=3D (ADVERTISED_10baseT_Half |
> diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
> index 0ada4ed..9f2492f 100644
> --- a/drivers/net/ucc_geth_mii.c
> +++ b/drivers/net/ucc_geth_mii.c
> @@ -36,6 +36,7 @@
> =A0#include <linux/mii.h>
> =A0#include <linux/phy.h>
> =A0#include <linux/fsl_devices.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
>
> =A0#include <asm/io.h>
> @@ -135,11 +136,10 @@ static int uec_mdio_probe(struct of_device *ofdev, =
const struct of_device_id *ma
> =A0{
> =A0 =A0 =A0 =A0struct device *device =3D &ofdev->dev;
> =A0 =A0 =A0 =A0struct device_node *np =3D ofdev->node, *tempnp =3D NULL;
> - =A0 =A0 =A0 struct device_node *child =3D NULL;
> =A0 =A0 =A0 =A0struct ucc_mii_mng __iomem *regs;
> =A0 =A0 =A0 =A0struct mii_bus *new_bus;
> =A0 =A0 =A0 =A0struct resource res;
> - =A0 =A0 =A0 int k, err =3D 0;
> + =A0 =A0 =A0 int err =3D 0;
>
> =A0 =A0 =A0 =A0new_bus =3D mdiobus_alloc();
> =A0 =A0 =A0 =A0if (NULL =3D=3D new_bus)
> @@ -165,17 +165,6 @@ static int uec_mdio_probe(struct of_device *ofdev, c=
onst struct of_device_id *ma
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto reg_map_fail;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 for (k =3D 0; k < 32; k++)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_bus->irq[k] =3D PHY_POLL;
> -
> - =A0 =A0 =A0 while ((child =3D of_get_next_child(np, child)) !=3D NULL) =
{
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 int irq =3D irq_of_parse_and_map(child, 0);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (irq !=3D NO_IRQ) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const u32 *id =3D of_get_pr=
operty(child, "reg", NULL);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_bus->irq[*id] =3D irq;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 }
> -
> =A0 =A0 =A0 =A0/* Set the base address */
> =A0 =A0 =A0 =A0regs =3D ioremap(res.start, sizeof(struct ucc_mii_mng));
>
> @@ -220,7 +209,7 @@ static int uec_mdio_probe(struct of_device *ofdev, co=
nst struct of_device_id *ma
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 err =3D mdiobus_register(new_bus);
> + =A0 =A0 =A0 err =3D of_mdiobus_register(new_bus, np);
> =A0 =A0 =A0 =A0if (0 !=3D err) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk(KERN_ERR "%s: Cannot register as MD=
IO bus\n",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_bus->name);
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure
  2009-03-19  5:00 ` [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure Grant Likely
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/net/pasemi_mac.c |   19 +++----------------
>  drivers/net/pasemi_mac.h |    1 -
>  2 files changed, 3 insertions(+), 17 deletions(-)
>
>
> diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
> index d0349e7..8c92d1f 100644
> --- a/drivers/net/pasemi_mac.c
> +++ b/drivers/net/pasemi_mac.c
> @@ -1086,34 +1086,21 @@ static int pasemi_mac_phy_init(struct net_device *dev)
>        struct pasemi_mac *mac = netdev_priv(dev);
>        struct device_node *dn, *phy_dn;
>        struct phy_device *phydev;
> -       unsigned int phy_id;
>        const phandle *ph;
>        const unsigned int *prop;
>        struct resource r;
>        int ret;
>
>        dn = pci_device_to_OF_node(mac->pdev);
> -       ph = of_get_property(dn, "phy-handle", NULL);
> -       if (!ph)
> -               return -ENODEV;
> -       phy_dn = of_find_node_by_phandle(*ph);
> -
> -       prop = of_get_property(phy_dn, "reg", NULL);
> -       ret = of_address_to_resource(phy_dn->parent, 0, &r);
> -       if (ret)
> -               goto err;
> -
> -       phy_id = *prop;
> -       snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
> -                (int)r.start, phy_id);
> -
> +       phy_dn = of_parse_phandle(dn, "phy-handle", 0);
>        of_node_put(phy_dn);
>
>        mac->link = 0;
>        mac->speed = 0;
>        mac->duplex = -1;
>
> -       phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
> +       phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
> +                               PHY_INTERFACE_MODE_SGMII);
>
>        if (IS_ERR(phydev)) {
>                printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
> diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
> index 1a115ec..e2f4efa 100644
> --- a/drivers/net/pasemi_mac.h
> +++ b/drivers/net/pasemi_mac.h
> @@ -100,7 +100,6 @@ struct pasemi_mac {
>        int     duplex;
>
>        unsigned int    msg_enable;
> -       char    phy_id[BUS_ID_SIZE];
>  };
>
>  /* Software status descriptor (ring_info) */
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/net/pasemi_mac.c | =A0 19 +++----------------
> =A0drivers/net/pasemi_mac.h | =A0 =A01 -
> =A02 files changed, 3 insertions(+), 17 deletions(-)
>
>
> diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
> index d0349e7..8c92d1f 100644
> --- a/drivers/net/pasemi_mac.c
> +++ b/drivers/net/pasemi_mac.c
> @@ -1086,34 +1086,21 @@ static int pasemi_mac_phy_init(struct net_device =
*dev)
> =A0 =A0 =A0 =A0struct pasemi_mac *mac =3D netdev_priv(dev);
> =A0 =A0 =A0 =A0struct device_node *dn, *phy_dn;
> =A0 =A0 =A0 =A0struct phy_device *phydev;
> - =A0 =A0 =A0 unsigned int phy_id;
> =A0 =A0 =A0 =A0const phandle *ph;
> =A0 =A0 =A0 =A0const unsigned int *prop;
> =A0 =A0 =A0 =A0struct resource r;
> =A0 =A0 =A0 =A0int ret;
>
> =A0 =A0 =A0 =A0dn =3D pci_device_to_OF_node(mac->pdev);
> - =A0 =A0 =A0 ph =3D of_get_property(dn, "phy-handle", NULL);
> - =A0 =A0 =A0 if (!ph)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
> - =A0 =A0 =A0 phy_dn =3D of_find_node_by_phandle(*ph);
> -
> - =A0 =A0 =A0 prop =3D of_get_property(phy_dn, "reg", NULL);
> - =A0 =A0 =A0 ret =3D of_address_to_resource(phy_dn->parent, 0, &r);
> - =A0 =A0 =A0 if (ret)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err;
> -
> - =A0 =A0 =A0 phy_id =3D *prop;
> - =A0 =A0 =A0 snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(int)r.start, phy_id);
> -
> + =A0 =A0 =A0 phy_dn =3D of_parse_phandle(dn, "phy-handle", 0);
> =A0 =A0 =A0 =A0of_node_put(phy_dn);
>
> =A0 =A0 =A0 =A0mac->link =3D 0;
> =A0 =A0 =A0 =A0mac->speed =3D 0;
> =A0 =A0 =A0 =A0mac->duplex =3D -1;
>
> - =A0 =A0 =A0 phydev =3D phy_connect(dev, mac->phy_id, &pasemi_adjust_lin=
k, 0, PHY_INTERFACE_MODE_SGMII);
> + =A0 =A0 =A0 phydev =3D of_phy_connect(dev, phy_dn, &pasemi_adjust_link,=
 0,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PHY_INTERFA=
CE_MODE_SGMII);
>
> =A0 =A0 =A0 =A0if (IS_ERR(phydev)) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk(KERN_ERR "%s: Could not attach to p=
hy\n", dev->name);
> diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
> index 1a115ec..e2f4efa 100644
> --- a/drivers/net/pasemi_mac.h
> +++ b/drivers/net/pasemi_mac.h
> @@ -100,7 +100,6 @@ struct pasemi_mac {
> =A0 =A0 =A0 =A0int =A0 =A0 duplex;
>
> =A0 =A0 =A0 =A0unsigned int =A0 =A0msg_enable;
> - =A0 =A0 =A0 char =A0 =A0phy_id[BUS_ID_SIZE];
> =A0};
>
> =A0/* Software status descriptor (ring_info) */
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
  2009-03-19  5:01 ` [PATCH 9/9] net/fs_enet: Rework fs_enet " Grant Likely
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:01 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
>  drivers/net/fs_enet/fs_enet-main.c |   66 +++++-------------------------------
>  drivers/net/fs_enet/mii-bitbang.c  |   29 +---------------
>  drivers/net/fs_enet/mii-fec.c      |   26 +-------------
>  include/linux/fs_enet_pd.h         |    6 +--
>  4 files changed, 14 insertions(+), 113 deletions(-)
>
>
> diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
> index ce900e5..e039d6a 100644
> --- a/drivers/net/fs_enet/fs_enet-main.c
> +++ b/drivers/net/fs_enet/fs_enet-main.c
> @@ -36,6 +36,8 @@
>  #include <linux/fs.h>
>  #include <linux/platform_device.h>
>  #include <linux/phy.h>
> +#include <linux/of.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>  #include <linux/of_gpio.h>
>
> @@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev)
>        fep->oldlink = 0;
>        fep->oldspeed = 0;
>        fep->oldduplex = -1;
> -       if(fep->fpi->bus_id)
> -               phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0,
> -                               PHY_INTERFACE_MODE_MII);
> +       if(fep->fpi->phy_node)
> +               phydev = of_phy_connect(dev, fep->fpi->phy_node,
> +                                       &fs_adjust_link, 0,
> +                                       PHY_INTERFACE_MODE_MII);
>        else {
>                printk("No phy bus ID specified in BSP code\n");
>                return -EINVAL;
> @@ -962,57 +965,6 @@ static void cleanup_immap(void)
>
>  /**************************************************************************************/
>
> -static int __devinit find_phy(struct device_node *np,
> -                              struct fs_platform_info *fpi)
> -{
> -       struct device_node *phynode, *mdionode;
> -       int ret = 0, len, bus_id;
> -       const u32 *data;
> -
> -       data  = of_get_property(np, "fixed-link", NULL);
> -       if (data) {
> -               snprintf(fpi->bus_id, 16, "%x:%02x", 0, *data);
> -               return 0;
> -       }
> -
> -       data = of_get_property(np, "phy-handle", &len);
> -       if (!data || len != 4)
> -               return -EINVAL;
> -
> -       phynode = of_find_node_by_phandle(*data);
> -       if (!phynode)
> -               return -EINVAL;
> -
> -       data = of_get_property(phynode, "reg", &len);
> -       if (!data || len != 4) {
> -               ret = -EINVAL;
> -               goto out_put_phy;
> -       }
> -
> -       mdionode = of_get_parent(phynode);
> -       if (!mdionode) {
> -               ret = -EINVAL;
> -               goto out_put_phy;
> -       }
> -
> -       bus_id = of_get_gpio(mdionode, 0);
> -       if (bus_id < 0) {
> -               struct resource res;
> -               ret = of_address_to_resource(mdionode, 0, &res);
> -               if (ret)
> -                       goto out_put_mdio;
> -               bus_id = res.start;
> -       }
> -
> -       snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
> -
> -out_put_mdio:
> -       of_node_put(mdionode);
> -out_put_phy:
> -       of_node_put(phynode);
> -       return ret;
> -}
> -
>  #ifdef CONFIG_FS_ENET_HAS_FEC
>  #define IS_FEC(match) ((match)->data == &fs_fec_ops)
>  #else
> @@ -1046,9 +998,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
>        fpi->rx_copybreak = 240;
>        fpi->use_napi = 1;
>        fpi->napi_weight = 17;
> -
> -       ret = find_phy(ofdev->node, fpi);
> -       if (ret)
> +       fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0);
> +       if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link",
> +                                                 NULL)))
>                goto out_free_fpi;
>
>        privsize = sizeof(*fep) +
> diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
> index 49b6645..93b481b 100644
> --- a/drivers/net/fs_enet/mii-bitbang.c
> +++ b/drivers/net/fs_enet/mii-bitbang.c
> @@ -22,6 +22,7 @@
>  #include <linux/mii.h>
>  #include <linux/platform_device.h>
>  #include <linux/mdio-bitbang.h>
> +#include <linux/of_mdio.h>
>  #include <linux/of_platform.h>
>
>  #include "fs_enet.h"
> @@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
>        return 0;
>  }
>
> -static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
> -{
> -       const u32 *data;
> -       int len, id, irq;
> -
> -       data = of_get_property(np, "reg", &len);
> -       if (!data || len != 4)
> -               return;
> -
> -       id = *data;
> -       bus->phy_mask &= ~(1 << id);
> -
> -       irq = of_irq_to_resource(np, 0, NULL);
> -       if (irq != NO_IRQ)
> -               bus->irq[id] = irq;
> -}
> -
>  static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
>                                         const struct of_device_id *match)
>  {
> -       struct device_node *np = NULL;
>        struct mii_bus *new_bus;
>        struct bb_info *bitbang;
>        int ret = -ENOMEM;
> -       int i;
>
>        bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
>        if (!bitbang)
> @@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
>        if (!new_bus->irq)
>                goto out_unmap_regs;
>
> -       for (i = 0; i < PHY_MAX_ADDR; i++)
> -               new_bus->irq[i] = -1;
> -
> -       while ((np = of_get_next_child(ofdev->node, np)))
> -               if (!strcmp(np->type, "ethernet-phy"))
> -                       add_phy(new_bus, np);
> -
>        new_bus->parent = &ofdev->dev;
>        dev_set_drvdata(&ofdev->dev, new_bus);
>
> -       ret = mdiobus_register(new_bus);
> +       ret = of_mdiobus_register(new_bus, ofdev->node);
>        if (ret)
>                goto out_free_irqs;
>
> diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
> index 28077cc..bdc3160 100644
> --- a/drivers/net/fs_enet/mii-fec.c
> +++ b/drivers/net/fs_enet/mii-fec.c
> @@ -102,23 +102,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
>        return 0;
>  }
>
> -static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
> -{
> -       const u32 *data;
> -       int len, id, irq;
> -
> -       data = of_get_property(np, "reg", &len);
> -       if (!data || len != 4)
> -               return;
> -
> -       id = *data;
> -       bus->phy_mask &= ~(1 << id);
> -
> -       irq = of_irq_to_resource(np, 0, NULL);
> -       if (irq != NO_IRQ)
> -               bus->irq[id] = irq;
> -}
> -
>  static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
>                                         const struct of_device_id *match)
>  {
> @@ -165,17 +148,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
>        if (!new_bus->irq)
>                goto out_unmap_regs;
>
> -       for (i = 0; i < PHY_MAX_ADDR; i++)
> -               new_bus->irq[i] = -1;
> -
> -       while ((np = of_get_next_child(ofdev->node, np)))
> -               if (!strcmp(np->type, "ethernet-phy"))
> -                       add_phy(new_bus, np);
> -
>        new_bus->parent = &ofdev->dev;
>        dev_set_drvdata(&ofdev->dev, new_bus);
>
> -       ret = mdiobus_register(new_bus);
> +       ret = of_mdiobus_register(new_bus, ofdev->node);
>        if (ret)
>                goto out_free_irqs;
>
> diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
> index 8300cab..51b7934 100644
> --- a/include/linux/fs_enet_pd.h
> +++ b/include/linux/fs_enet_pd.h
> @@ -17,6 +17,7 @@
>  #define FS_ENET_PD_H
>
>  #include <linux/string.h>
> +#include <linux/of_mdio.h>
>  #include <asm/types.h>
>
>  #define FS_ENET_NAME   "fs_enet"
> @@ -130,10 +131,7 @@ struct fs_platform_info {
>
>        u32 device_flags;
>
> -       int phy_addr;           /* the phy address (-1 no phy) */
> -       char bus_id[16];
> -       int phy_irq;            /* the phy irq (if it exists)  */
> -
> +       struct device_node *phy_node;
>        const struct fs_mii_bus_info *bus_info;
>
>        int rx_ring, tx_ring;   /* number of buffers on rx     */
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
@ 2009-03-19  5:07     ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  5:07 UTC (permalink / raw)
  To: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:01 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> =A0drivers/net/fs_enet/fs_enet-main.c | =A0 66 +++++---------------------=
----------
> =A0drivers/net/fs_enet/mii-bitbang.c =A0| =A0 29 +---------------
> =A0drivers/net/fs_enet/mii-fec.c =A0 =A0 =A0| =A0 26 +-------------
> =A0include/linux/fs_enet_pd.h =A0 =A0 =A0 =A0 | =A0 =A06 +--
> =A04 files changed, 14 insertions(+), 113 deletions(-)
>
>
> diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_=
enet-main.c
> index ce900e5..e039d6a 100644
> --- a/drivers/net/fs_enet/fs_enet-main.c
> +++ b/drivers/net/fs_enet/fs_enet-main.c
> @@ -36,6 +36,8 @@
> =A0#include <linux/fs.h>
> =A0#include <linux/platform_device.h>
> =A0#include <linux/phy.h>
> +#include <linux/of.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
> =A0#include <linux/of_gpio.h>
>
> @@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev)
> =A0 =A0 =A0 =A0fep->oldlink =3D 0;
> =A0 =A0 =A0 =A0fep->oldspeed =3D 0;
> =A0 =A0 =A0 =A0fep->oldduplex =3D -1;
> - =A0 =A0 =A0 if(fep->fpi->bus_id)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 phydev =3D phy_connect(dev, fep->fpi->bus_i=
d, &fs_adjust_link, 0,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PHY_INTERFA=
CE_MODE_MII);
> + =A0 =A0 =A0 if(fep->fpi->phy_node)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phydev =3D of_phy_connect(dev, fep->fpi->ph=
y_node,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 &fs_adjust_link, 0,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 PHY_INTERFACE_MODE_MII);
> =A0 =A0 =A0 =A0else {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk("No phy bus ID specified in BSP cod=
e\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -EINVAL;
> @@ -962,57 +965,6 @@ static void cleanup_immap(void)
>
> =A0/*********************************************************************=
*****************/
>
> -static int __devinit find_phy(struct device_node *np,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct fs_pl=
atform_info *fpi)
> -{
> - =A0 =A0 =A0 struct device_node *phynode, *mdionode;
> - =A0 =A0 =A0 int ret =3D 0, len, bus_id;
> - =A0 =A0 =A0 const u32 *data;
> -
> - =A0 =A0 =A0 data =A0=3D of_get_property(np, "fixed-link", NULL);
> - =A0 =A0 =A0 if (data) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 snprintf(fpi->bus_id, 16, "%x:%02x", 0, *da=
ta);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return 0;
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 data =3D of_get_property(np, "phy-handle", &len);
> - =A0 =A0 =A0 if (!data || len !=3D 4)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EINVAL;
> -
> - =A0 =A0 =A0 phynode =3D of_find_node_by_phandle(*data);
> - =A0 =A0 =A0 if (!phynode)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EINVAL;
> -
> - =A0 =A0 =A0 data =3D of_get_property(phynode, "reg", &len);
> - =A0 =A0 =A0 if (!data || len !=3D 4) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D -EINVAL;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out_put_phy;
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 mdionode =3D of_get_parent(phynode);
> - =A0 =A0 =A0 if (!mdionode) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D -EINVAL;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out_put_phy;
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 bus_id =3D of_get_gpio(mdionode, 0);
> - =A0 =A0 =A0 if (bus_id < 0) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct resource res;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D of_address_to_resource(mdionode, 0,=
 &res);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ret)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out_put_mdio;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus_id =3D res.start;
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
> -
> -out_put_mdio:
> - =A0 =A0 =A0 of_node_put(mdionode);
> -out_put_phy:
> - =A0 =A0 =A0 of_node_put(phynode);
> - =A0 =A0 =A0 return ret;
> -}
> -
> =A0#ifdef CONFIG_FS_ENET_HAS_FEC
> =A0#define IS_FEC(match) ((match)->data =3D=3D &fs_fec_ops)
> =A0#else
> @@ -1046,9 +998,9 @@ static int __devinit fs_enet_probe(struct of_device =
*ofdev,
> =A0 =A0 =A0 =A0fpi->rx_copybreak =3D 240;
> =A0 =A0 =A0 =A0fpi->use_napi =3D 1;
> =A0 =A0 =A0 =A0fpi->napi_weight =3D 17;
> -
> - =A0 =A0 =A0 ret =3D find_phy(ofdev->node, fpi);
> - =A0 =A0 =A0 if (ret)
> + =A0 =A0 =A0 fpi->phy_node =3D of_parse_phandle(ofdev->node, "phy-handle=
", 0);
> + =A0 =A0 =A0 if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fix=
ed-link",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 =A0 =A0 NULL)))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_free_fpi;
>
> =A0 =A0 =A0 =A0privsize =3D sizeof(*fep) +
> diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-=
bitbang.c
> index 49b6645..93b481b 100644
> --- a/drivers/net/fs_enet/mii-bitbang.c
> +++ b/drivers/net/fs_enet/mii-bitbang.c
> @@ -22,6 +22,7 @@
> =A0#include <linux/mii.h>
> =A0#include <linux/platform_device.h>
> =A0#include <linux/mdio-bitbang.h>
> +#include <linux/of_mdio.h>
> =A0#include <linux/of_platform.h>
>
> =A0#include "fs_enet.h"
> @@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii=
_bus *bus,
> =A0 =A0 =A0 =A0return 0;
> =A0}
>
> -static void __devinit add_phy(struct mii_bus *bus, struct device_node *n=
p)
> -{
> - =A0 =A0 =A0 const u32 *data;
> - =A0 =A0 =A0 int len, id, irq;
> -
> - =A0 =A0 =A0 data =3D of_get_property(np, "reg", &len);
> - =A0 =A0 =A0 if (!data || len !=3D 4)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> -
> - =A0 =A0 =A0 id =3D *data;
> - =A0 =A0 =A0 bus->phy_mask &=3D ~(1 << id);
> -
> - =A0 =A0 =A0 irq =3D of_irq_to_resource(np, 0, NULL);
> - =A0 =A0 =A0 if (irq !=3D NO_IRQ)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus->irq[id] =3D irq;
> -}
> -
> =A0static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 const struct of_device_id *match)
> =A0{
> - =A0 =A0 =A0 struct device_node *np =3D NULL;
> =A0 =A0 =A0 =A0struct mii_bus *new_bus;
> =A0 =A0 =A0 =A0struct bb_info *bitbang;
> =A0 =A0 =A0 =A0int ret =3D -ENOMEM;
> - =A0 =A0 =A0 int i;
>
> =A0 =A0 =A0 =A0bitbang =3D kzalloc(sizeof(struct bb_info), GFP_KERNEL);
> =A0 =A0 =A0 =A0if (!bitbang)
> @@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_d=
evice *ofdev,
> =A0 =A0 =A0 =A0if (!new_bus->irq)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_unmap_regs;
>
> - =A0 =A0 =A0 for (i =3D 0; i < PHY_MAX_ADDR; i++)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_bus->irq[i] =3D -1;
> -
> - =A0 =A0 =A0 while ((np =3D of_get_next_child(ofdev->node, np)))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!strcmp(np->type, "ethernet-phy"))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 add_phy(new_bus, np);
> -
> =A0 =A0 =A0 =A0new_bus->parent =3D &ofdev->dev;
> =A0 =A0 =A0 =A0dev_set_drvdata(&ofdev->dev, new_bus);
>
> - =A0 =A0 =A0 ret =3D mdiobus_register(new_bus);
> + =A0 =A0 =A0 ret =3D of_mdiobus_register(new_bus, ofdev->node);
> =A0 =A0 =A0 =A0if (ret)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_free_irqs;
>
> diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.=
c
> index 28077cc..bdc3160 100644
> --- a/drivers/net/fs_enet/mii-fec.c
> +++ b/drivers/net/fs_enet/mii-fec.c
> @@ -102,23 +102,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus=
)
> =A0 =A0 =A0 =A0return 0;
> =A0}
>
> -static void __devinit add_phy(struct mii_bus *bus, struct device_node *n=
p)
> -{
> - =A0 =A0 =A0 const u32 *data;
> - =A0 =A0 =A0 int len, id, irq;
> -
> - =A0 =A0 =A0 data =3D of_get_property(np, "reg", &len);
> - =A0 =A0 =A0 if (!data || len !=3D 4)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> -
> - =A0 =A0 =A0 id =3D *data;
> - =A0 =A0 =A0 bus->phy_mask &=3D ~(1 << id);
> -
> - =A0 =A0 =A0 irq =3D of_irq_to_resource(np, 0, NULL);
> - =A0 =A0 =A0 if (irq !=3D NO_IRQ)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus->irq[id] =3D irq;
> -}
> -
> =A0static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 const struct of_device_id *match)
> =A0{
> @@ -165,17 +148,10 @@ static int __devinit fs_enet_mdio_probe(struct of_d=
evice *ofdev,
> =A0 =A0 =A0 =A0if (!new_bus->irq)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_unmap_regs;
>
> - =A0 =A0 =A0 for (i =3D 0; i < PHY_MAX_ADDR; i++)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 new_bus->irq[i] =3D -1;
> -
> - =A0 =A0 =A0 while ((np =3D of_get_next_child(ofdev->node, np)))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!strcmp(np->type, "ethernet-phy"))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 add_phy(new_bus, np);
> -
> =A0 =A0 =A0 =A0new_bus->parent =3D &ofdev->dev;
> =A0 =A0 =A0 =A0dev_set_drvdata(&ofdev->dev, new_bus);
>
> - =A0 =A0 =A0 ret =3D mdiobus_register(new_bus);
> + =A0 =A0 =A0 ret =3D of_mdiobus_register(new_bus, ofdev->node);
> =A0 =A0 =A0 =A0if (ret)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_free_irqs;
>
> diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
> index 8300cab..51b7934 100644
> --- a/include/linux/fs_enet_pd.h
> +++ b/include/linux/fs_enet_pd.h
> @@ -17,6 +17,7 @@
> =A0#define FS_ENET_PD_H
>
> =A0#include <linux/string.h>
> +#include <linux/of_mdio.h>
> =A0#include <asm/types.h>
>
> =A0#define FS_ENET_NAME =A0 "fs_enet"
> @@ -130,10 +131,7 @@ struct fs_platform_info {
>
> =A0 =A0 =A0 =A0u32 device_flags;
>
> - =A0 =A0 =A0 int phy_addr; =A0 =A0 =A0 =A0 =A0 /* the phy address (-1 no=
 phy) */
> - =A0 =A0 =A0 char bus_id[16];
> - =A0 =A0 =A0 int phy_irq; =A0 =A0 =A0 =A0 =A0 =A0/* the phy irq (if it e=
xists) =A0*/
> -
> + =A0 =A0 =A0 struct device_node *phy_node;
> =A0 =A0 =A0 =A0const struct fs_mii_bus_info *bus_info;
>
> =A0 =A0 =A0 =A0int rx_ring, tx_ring; =A0 /* number of buffers on rx =A0 =
=A0 */
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties
  2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
@ 2009-03-19  5:07   ` Michael Ellerman
  2009-03-19  5:00 ` [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions Grant Likely
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 33+ messages in thread
From: Michael Ellerman @ 2009-03-19  5:07 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev, netdev, afleming, avorontsov, davem, galak

[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]

On Wed, 2009-03-18 at 23:00 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> of_parse_phandle() is a helper function to read and parse a phandle
> property and return a pointer to the resulting device_node.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> 
>  drivers/of/base.c  |   23 +++++++++++++++++++++++
>  include/linux/of.h |    3 +++
>  2 files changed, 26 insertions(+), 0 deletions(-)
> 
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index cd17092..1eaada4 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -494,6 +494,29 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
>  EXPORT_SYMBOL_GPL(of_modalias_node);
>  
>  /**
> + * of_parse_phandle - Resolve a phandle property to a device_node pointer
> + * @np: Pointer to device node holding phandle property
> + * @phandle_name: Name of property holding a phandle value
> + * @index: For properties holding a table of phandles, this is the index into
> + *         the table
> + *
> + * Returns the device_node pointer pointed to by the phandle, or NULL
> + */

I think it would good to follow the convention of many of the other of_
routines and have an explicit comment about the refcounting, eg:

 *      Returns a node pointer with refcount incremented, use
 *      of_node_put() on it when done.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties
@ 2009-03-19  5:07   ` Michael Ellerman
  0 siblings, 0 replies; 33+ messages in thread
From: Michael Ellerman @ 2009-03-19  5:07 UTC (permalink / raw)
  To: Grant Likely; +Cc: netdev, linuxppc-dev, afleming, davem

[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]

On Wed, 2009-03-18 at 23:00 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> of_parse_phandle() is a helper function to read and parse a phandle
> property and return a pointer to the resulting device_node.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> 
>  drivers/of/base.c  |   23 +++++++++++++++++++++++
>  include/linux/of.h |    3 +++
>  2 files changed, 26 insertions(+), 0 deletions(-)
> 
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index cd17092..1eaada4 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -494,6 +494,29 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
>  EXPORT_SYMBOL_GPL(of_modalias_node);
>  
>  /**
> + * of_parse_phandle - Resolve a phandle property to a device_node pointer
> + * @np: Pointer to device node holding phandle property
> + * @phandle_name: Name of property holding a phandle value
> + * @index: For properties holding a table of phandles, this is the index into
> + *         the table
> + *
> + * Returns the device_node pointer pointed to by the phandle, or NULL
> + */

I think it would good to follow the convention of many of the other of_
routines and have an explicit comment about the refcounting, eg:

 *      Returns a node pointer with refcount incremented, use
 *      of_node_put() on it when done.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
  2009-03-19  5:07     ` Grant Likely
@ 2009-03-19  5:42       ` David Miller
  -1 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2009-03-19  5:42 UTC (permalink / raw)
  To: grant.likely; +Cc: linuxppc-dev, netdev, afleming, avorontsov, galak

From: Grant Likely <grant.likely@secretlab.ca>
Date: Wed, 18 Mar 2009 23:07:35 -0600

> RFC, please don't apply yet.

You know, if you have posted a "0/9" patch explaining the purpose
and intent of the patch series, you'd only need to re-shit into
my inbox one time to say this stuff is RFC and "don't apply yet"
instead of 9 FREAKIN' TIMES!

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
@ 2009-03-19  5:42       ` David Miller
  0 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2009-03-19  5:42 UTC (permalink / raw)
  To: grant.likely; +Cc: linuxppc-dev, afleming, netdev

From: Grant Likely <grant.likely@secretlab.ca>
Date: Wed, 18 Mar 2009 23:07:35 -0600

> RFC, please don't apply yet.

You know, if you have posted a "0/9" patch explaining the purpose
and intent of the patch series, you'd only need to re-shit into
my inbox one time to say this stuff is RFC and "don't apply yet"
instead of 9 FREAKIN' TIMES!

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
  2009-03-19  5:42       ` David Miller
@ 2009-03-19  6:11         ` Grant Likely
  -1 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  6:11 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev, netdev, afleming, avorontsov, galak

On Wed, Mar 18, 2009 at 11:42 PM, David Miller <davem@davemloft.net> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> Date: Wed, 18 Mar 2009 23:07:35 -0600
>
>> RFC, please don't apply yet.
>
> You know, if you have posted a "0/9" patch explaining the purpose
> and intent of the patch series, you'd only need to re-shit into
> my inbox one time to say this stuff is RFC and "don't apply yet"
> instead of 9 FREAKIN' TIMES!

Ugh.  Sorry.  My lame excuse is that its late and I'm tired.  Normally
I do actually know better.

g.


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio infrastructure
@ 2009-03-19  6:11         ` Grant Likely
  0 siblings, 0 replies; 33+ messages in thread
From: Grant Likely @ 2009-03-19  6:11 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev, afleming, netdev

On Wed, Mar 18, 2009 at 11:42 PM, David Miller <davem@davemloft.net> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> Date: Wed, 18 Mar 2009 23:07:35 -0600
>
>> RFC, please don't apply yet.
>
> You know, if you have posted a "0/9" patch explaining the purpose
> and intent of the patch series, you'd only need to re-shit into
> my inbox one time to say this stuff is RFC and "don't apply yet"
> instead of 9 FREAKIN' TIMES!

Ugh.  Sorry.  My lame excuse is that its late and I'm tired.  Normally
I do actually know better.

g.


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2009-03-19  6:11 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-19  5:00 [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
2009-03-19  5:00 ` [PATCH 2/9] phylib: rework to prepare for OF registration of PHYs Grant Likely
2009-03-19  5:05   ` Grant Likely
2009-03-19  5:05     ` Grant Likely
2009-03-19  5:00 ` [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions Grant Likely
2009-03-19  5:05   ` Grant Likely
2009-03-19  5:05     ` Grant Likely
2009-03-19  5:00 ` [PATCH 4/9] openfirmware: Add OF phylib support code Grant Likely
2009-03-19  5:06   ` Grant Likely
2009-03-19  5:06     ` Grant Likely
2009-03-19  5:00 ` [PATCH 5/9] net: make mpc5200 fec driver use of_mdio infrastructure Grant Likely
2009-03-19  5:06   ` Grant Likely
2009-03-19  5:06     ` Grant Likely
2009-03-19  5:00 ` [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions Grant Likely
2009-03-19  5:07   ` Grant Likely
2009-03-19  5:07     ` Grant Likely
2009-03-19  5:00 ` [PATCH 7/9] net/ucc_geth: Rework ucc_geth " Grant Likely
2009-03-19  5:07   ` Grant Likely
2009-03-19  5:07     ` Grant Likely
2009-03-19  5:00 ` [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use of_mdio infrastructure Grant Likely
2009-03-19  5:07   ` Grant Likely
2009-03-19  5:07     ` Grant Likely
2009-03-19  5:01 ` [PATCH 9/9] net/fs_enet: Rework fs_enet " Grant Likely
2009-03-19  5:07   ` Grant Likely
2009-03-19  5:07     ` Grant Likely
2009-03-19  5:42     ` David Miller
2009-03-19  5:42       ` David Miller
2009-03-19  6:11       ` Grant Likely
2009-03-19  6:11         ` Grant Likely
2009-03-19  5:05 ` [PATCH 1/9] of: add of_parse_phandle() helper for parsing phandle properties Grant Likely
2009-03-19  5:05   ` Grant Likely
2009-03-19  5:07 ` Michael Ellerman
2009-03-19  5:07   ` Michael Ellerman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.