[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fa686aa40903182205o34e6e32cq4441db2bd369f14@mail.gmail.com>
Date: Wed, 18 Mar 2009 23:05:58 -0600
From: Grant Likely <grant.likely@...retlab.ca>
To: linuxppc-dev@...abs.org, netdev@...r.kernel.org,
afleming@...escale.com, avorontsov@...mvista.com,
davem@...emloft.net, galak@...nel.crashing.org
Subject: Re: [PATCH 3/9] phylib: add *_direct() variants of phy_connect and
phy_attach functions
RFC, please don't apply yet.
On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely
<grant.likely@...retlab.ca> wrote:
> From: Grant Likely <grant.likely@...retlab.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@...retlab.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.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists