Commit 1dca22b1 authored by Richard Cochran's avatar Richard Cochran Committed by David S. Miller

net: mdio: of: Register discovered MII time stampers.

When parsing a PHY node, register its time stamper, if any, and attach
the instance to the PHY device.
Signed-off-by: default avatarRichard Cochran <richardcochran@gmail.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Reviewed-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 25d12e1d
...@@ -881,6 +881,9 @@ EXPORT_SYMBOL(phy_device_register); ...@@ -881,6 +881,9 @@ EXPORT_SYMBOL(phy_device_register);
*/ */
void phy_device_remove(struct phy_device *phydev) void phy_device_remove(struct phy_device *phydev)
{ {
if (phydev->mii_ts)
unregister_mii_timestamper(phydev->mii_ts);
device_del(&phydev->mdio.dev); device_del(&phydev->mdio.dev);
/* Assert the reset signal */ /* Assert the reset signal */
......
...@@ -42,14 +42,37 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id) ...@@ -42,14 +42,37 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id)
return -EINVAL; return -EINVAL;
} }
static struct mii_timestamper *of_find_mii_timestamper(struct device_node *node)
{
struct of_phandle_args arg;
int err;
err = of_parse_phandle_with_fixed_args(node, "timestamper", 1, 0, &arg);
if (err == -ENOENT)
return NULL;
else if (err)
return ERR_PTR(err);
if (arg.args_count != 1)
return ERR_PTR(-EINVAL);
return register_mii_timestamper(arg.np, arg.args[0]);
}
static int of_mdiobus_register_phy(struct mii_bus *mdio, static int of_mdiobus_register_phy(struct mii_bus *mdio,
struct device_node *child, u32 addr) struct device_node *child, u32 addr)
{ {
struct mii_timestamper *mii_ts;
struct phy_device *phy; struct phy_device *phy;
bool is_c45; bool is_c45;
int rc; int rc;
u32 phy_id; u32 phy_id;
mii_ts = of_find_mii_timestamper(child);
if (IS_ERR(mii_ts))
return PTR_ERR(mii_ts);
is_c45 = of_device_is_compatible(child, is_c45 = of_device_is_compatible(child,
"ethernet-phy-ieee802.3-c45"); "ethernet-phy-ieee802.3-c45");
...@@ -57,11 +80,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, ...@@ -57,11 +80,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
phy = phy_device_create(mdio, addr, phy_id, 0, NULL); phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
else else
phy = get_phy_device(mdio, addr, is_c45); phy = get_phy_device(mdio, addr, is_c45);
if (IS_ERR(phy)) if (IS_ERR(phy)) {
unregister_mii_timestamper(mii_ts);
return PTR_ERR(phy); return PTR_ERR(phy);
}
rc = of_irq_get(child, 0); rc = of_irq_get(child, 0);
if (rc == -EPROBE_DEFER) { if (rc == -EPROBE_DEFER) {
unregister_mii_timestamper(mii_ts);
phy_device_free(phy); phy_device_free(phy);
return rc; return rc;
} }
...@@ -90,10 +116,12 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, ...@@ -90,10 +116,12 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
* register it */ * register it */
rc = phy_device_register(phy); rc = phy_device_register(phy);
if (rc) { if (rc) {
unregister_mii_timestamper(mii_ts);
phy_device_free(phy); phy_device_free(phy);
of_node_put(child); of_node_put(child);
return rc; return rc;
} }
phy->mii_ts = mii_ts;
dev_dbg(&mdio->dev, "registered phy %pOFn at address %i\n", dev_dbg(&mdio->dev, "registered phy %pOFn at address %i\n",
child, addr); child, addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment