Thread (21 messages) flat view 21 messages, 3 authors, 2009-03-19

Re: [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF PHY/MDIO helper functions

From: Grant Likely <hidden>
Date: 2009-03-19 05:07:01
Also in: netdev

RFC, please don't apply yet.

On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
[off-list ref] wrote:
From: Grant Likely <redacted>

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

Signed-off-by: Grant Likely <redacted>
---

=A0drivers/net/gianfar.c =A0 =A0 | =A0 94 ++++++++++++++-----------------=
--------------
quoted hunk ↗ jump to hunk
=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)
quoted hunk ↗ jump to hunk
=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);
quoted hunk ↗ jump to hunk
@@ -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);
quoted hunk ↗ jump to hunk
- =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 ?
quoted hunk ↗ jump to hunk
=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);
quoted hunk ↗ jump to hunk
+ =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);
quoted hunk ↗ jump to hunk
- =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);
quoted hunk ↗ jump to hunk
=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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help