Re: [PATCH 3/9] phylib: add *_direct() variants of phy_connect and phy_attach functions
From: Grant Likely <hidden>
Date: 2009-03-19 05:05:59
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> 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 <redacted> --- =A0drivers/net/phy/phy_device.c | =A0118 ++++++++++++++++++++++++++++++--=
----------
quoted hunk ↗ jump to hunk
=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,
quoted hunk ↗ jump to hunk
+ =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)=;
quoted hunk ↗ jump to hunk
+ =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
quoted hunk ↗ jump to hunk
=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)
quoted hunk ↗ jump to hunk
=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"=
);
quoted hunk ↗ jump to hunk
+ =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)
quoted hunk ↗ jump to hunk
+{ + =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.