From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from yx-out-2324.google.com (yx-out-2324.google.com [74.125.44.28]) by ozlabs.org (Postfix) with ESMTP id 91EAADFB2E for ; Thu, 19 Mar 2009 16:05:59 +1100 (EST) Received: by yx-out-2324.google.com with SMTP id 8so251087yxg.39 for ; Wed, 18 Mar 2009 22:05:58 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <20090319050026.11320.23198.stgit@localhost.localdomain> References: <20090319050015.11320.61641.stgit@localhost.localdomain> <20090319050026.11320.23198.stgit@localhost.localdomain> Date: Wed, 18 Mar 2009 23:05:58 -0600 Message-ID: Subject: Re: [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions From: Grant Likely To: linuxppc-dev@ozlabs.org, netdev@vger.kernel.org, afleming@freescale.com, avorontsov@ru.mvista.com, davem@davemloft.net, galak@kernel.crashing.org Content-Type: text/plain; charset=ISO-8859-1 List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , RFC, please don't apply yet. On Wed, Mar 18, 2009 at 11:00 PM, Grant Likely wrote: > From: Grant Likely > > 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 > --- > > =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.