[PATCH 1/9] of: add of_parse_phandle() helper for parsing

sunder ramani sunder.svit at gmail.com
Thu Mar 19 16:37:26 EST 2009


Hi Grant,

I have here one query though. I found out that there are various
configurations of the PHY device that my be connected to the eTSEC on
the 8548. I am talking only about this because I faced some issues.

My HW had RGMII, SGMII configurations for the different ports to the
PHYs. And the kernel doesnt know about how the interface from the
eTSEC to the physical PHY is. I do acknowledge the ignorance of the
MII layer, but I had to fix up some dirty patches in the phy code to
let me kernel do auto-neg, phy_init for a RGMII, SGMII, interface
differentaiting on the basis of the Phy-IDs. As a result, the PHY
layer would generalize the auto-neg and init functions for the copper
interface.

To Summarize, should not we have a phy_type flag in the OF tree which
will let the PHY layer do the various PHY tasks based on if it is a
copper/fiber interface. I really dont like my fix in my kernel and am
new to open source. Do you think it is a valid argument? If it so, I
would like to plan to introduce those changes and post to the
community.

Please let me know your comments!

Thanx!
Sundar

On Thu, Mar 19, 2009 at 10:35 AM,  <linuxppc-dev-request at ozlabs.org> wrote:
> Send Linuxppc-dev mailing list submissions to
>        linuxppc-dev at ozlabs.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>        https://ozlabs.org/mailman/listinfo/linuxppc-dev
> or, via email, send a message with subject or body 'help' to
>        linuxppc-dev-request at ozlabs.org
>
> You can reach the person managing the list at
>        linuxppc-dev-owner at ozlabs.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Linuxppc-dev digest..."
>
>
> Today's Topics:
>
>   1. [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF
>      PHY/MDIO  helper functions (Grant Likely)
>   2. [PATCH 7/9] net/ucc_geth: Rework ucc_geth driver to use OF
>      PHY/MDIO  helper functions (Grant Likely)
>   3. [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use
>      of_mdio   infrastructure (Grant Likely)
>   4. [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio
>      infrastructure (Grant Likely)
>   5. Re: [PATCH 1/9] of: add of_parse_phandle() helper for parsing
>      phandle   properties (Grant Likely)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Wed, 18 Mar 2009 23:00:44 -0600
> From: Grant Likely <grant.likely at secretlab.ca>
> Subject: [PATCH 6/9] net/gianfar: Rework gianfar driver to use OF
>        PHY/MDIO        helper functions
> To: linuxppc-dev at ozlabs.org, netdev at vger.kernel.org,
>        afleming at freescale.com, avorontsov at ru.mvista.com, davem at davemloft.net,
>        galak at kernel.crashing.org
> Message-ID: <20090319050043.11320.96160.stgit at localhost.localdomain>
> Content-Type: text/plain; charset="utf-8"
>
> From: Grant Likely <grant.likely at secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely at 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);
>
>
>
> ------------------------------
>
> Message: 2
> Date: Wed, 18 Mar 2009 23:00:50 -0600
> From: Grant Likely <grant.likely at secretlab.ca>
> Subject: [PATCH 7/9] net/ucc_geth: Rework ucc_geth driver to use OF
>        PHY/MDIO        helper functions
> To: linuxppc-dev at ozlabs.org, netdev at vger.kernel.org,
>        afleming at freescale.com, avorontsov at ru.mvista.com, davem at davemloft.net,
>        galak at kernel.crashing.org
> Message-ID: <20090319050049.11320.98769.stgit at localhost.localdomain>
> Content-Type: text/plain; charset="utf-8"
>
> From: Grant Likely <grant.likely at secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely at 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);
>
>
>
> ------------------------------
>
> Message: 3
> Date: Wed, 18 Mar 2009 23:00:55 -0600
> From: Grant Likely <grant.likely at secretlab.ca>
> Subject: [PATCH 8/9] net/pasemi_mac: Rework pasemi_mac driver to use
>        of_mdio infrastructure
> To: linuxppc-dev at ozlabs.org, netdev at vger.kernel.org,
>        afleming at freescale.com, avorontsov at ru.mvista.com, davem at davemloft.net,
>        galak at kernel.crashing.org
> Message-ID: <20090319050055.11320.62033.stgit at localhost.localdomain>
> Content-Type: text/plain; charset="utf-8"
>
> From: Grant Likely <grant.likely at secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely at 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) */
>
>
>
> ------------------------------
>
> Message: 4
> Date: Wed, 18 Mar 2009 23:01:01 -0600
> From: Grant Likely <grant.likely at secretlab.ca>
> Subject: [PATCH 9/9] net/fs_enet: Rework fs_enet driver to use of_mdio
>        infrastructure
> To: linuxppc-dev at ozlabs.org, netdev at vger.kernel.org,
>        afleming at freescale.com, avorontsov at ru.mvista.com, davem at davemloft.net,
>        galak at kernel.crashing.org
> Message-ID: <20090319050100.11320.64495.stgit at localhost.localdomain>
> Content-Type: text/plain; charset="utf-8"
>
> From: Grant Likely <grant.likely at secretlab.ca>
>
> This patch simplifies the driver by making use of more common code.
>
> Signed-off-by: Grant Likely <grant.likely at 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     */
>
>
>
> ------------------------------
>
> Message: 5
> Date: Wed, 18 Mar 2009 23:05:21 -0600
> From: Grant Likely <grant.likely at secretlab.ca>
> Subject: Re: [PATCH 1/9] of: add of_parse_phandle() helper for parsing
>        phandle properties
> To: linuxppc-dev at ozlabs.org, netdev at vger.kernel.org,
>        afleming at freescale.com,         avorontsov at ru.mvista.com,
>        davem at davemloft.net, galak at kernel.crashing.org
> Message-ID:
>        <fa686aa40903182205w231e17e9wbd0dcc05d994d46e at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> 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 at secretlab.ca> wrote:
>> From: Grant Likely <grant.likely at 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 at 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.
>
>
> ------------------------------
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
> End of Linuxppc-dev Digest, Vol 55, Issue 122
> *********************************************
>



More information about the Linuxppc-dev mailing list