diff options
author | Gabor Juhos <juhosg@openwrt.org> | 2013-02-11 16:11:30 +0000 |
---|---|---|
committer | Gabor Juhos <juhosg@openwrt.org> | 2013-02-11 16:11:30 +0000 |
commit | 3f3eba88f61b7384e5308e6af07820a7650257c3 (patch) | |
tree | 171c427438f24aed803c85c58c373bc4bd908f7f /target/linux/generic/files/drivers/net/phy/ar8216.c | |
parent | 1afb759b35e07b791e0fa772037b911d20851e0f (diff) | |
download | master-31e0f0ae-3f3eba88f61b7384e5308e6af07820a7650257c3.tar.gz master-31e0f0ae-3f3eba88f61b7384e5308e6af07820a7650257c3.tar.bz2 master-31e0f0ae-3f3eba88f61b7384e5308e6af07820a7650257c3.zip |
generic: ar8216: reuse the private data from ar8216_probe
The private data of the switch is already
allocated in ar8216_priv, assign that to
each PHY on the same MDIO bus. Also remove
the redundant code from ar8216_config_init.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
SVN-Revision: 35559
Diffstat (limited to 'target/linux/generic/files/drivers/net/phy/ar8216.c')
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 7fbc531242..baf752bf11 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -101,6 +101,9 @@ struct ar8216_priv { int mib_next_port; u64 *mib_stats; + struct list_head list; + unsigned int use_count; + /* all fields below are cleared on reset */ bool vlan; u16 vlan_id[AR8X16_MAX_VLANS]; @@ -198,6 +201,9 @@ static const struct ar8xxx_mib_desc ar8236_mibs[] = { MIB_DESC(1, AR8236_STATS_TXLATECOL, "TxLateCol"), }; +static DEFINE_MUTEX(ar8xxx_dev_list_lock); +static LIST_HEAD(ar8xxx_dev_list); + static inline struct ar8216_priv * swdev_to_ar8216(struct switch_dev *swdev) { @@ -1848,15 +1854,8 @@ ar8216_config_init(struct phy_device *phydev) struct switch_dev *swdev; int ret; - if (!priv) { - priv = ar8xxx_create_mii(phydev->bus); - if (priv == NULL) - return -ENOMEM; - - ret = ar8xxx_probe_switch(priv); - if (ret) - goto err_free_priv; - } + if (WARN_ON(!priv)) + return -ENODEV; priv->phy = phydev; @@ -1864,23 +1863,17 @@ ar8216_config_init(struct phy_device *phydev) if (chip_is_ar8316(priv)) { /* check if we're attaching to the switch twice */ phydev = phydev->bus->phy_map[0]; - if (!phydev) { - ar8xxx_free(priv); + if (!phydev) return 0; - } /* switch device has not been initialized, reuse priv */ if (!phydev->priv) { priv->port4_phy = true; priv->dev.ports = (AR8216_NUM_PORTS - 1); - phydev->priv = priv; return 0; } - ar8xxx_free(priv); - /* switch device has been initialized, reinit */ - priv = phydev->priv; priv->dev.ports = (AR8216_NUM_PORTS - 1); priv->initialized = false; priv->port4_phy = true; @@ -1888,16 +1881,13 @@ ar8216_config_init(struct phy_device *phydev) return 0; } - ar8xxx_free(priv); return 0; } - phydev->priv = priv; - swdev = &priv->dev; ret = register_switch(swdev, phydev->attached_dev); if (ret) - goto err_free_priv; + goto err; pr_info("%s: %s switch driver attached.\n", phydev->attached_dev->name, swdev->name); @@ -1928,9 +1918,7 @@ ar8216_config_init(struct phy_device *phydev) err_unregister_switch: unregister_switch(&priv->dev); -err_free_priv: - ar8xxx_free(priv); - phydev->priv = NULL; +err: return ret; } @@ -2036,16 +2024,22 @@ ar8216_probe(struct phy_device *phydev) if (!ar8xxx_is_possible(phydev->bus)) return -ENODEV; - priv = ar8xxx_create_mii(phydev->bus); - if (priv == NULL) - return -ENOMEM; + mutex_lock(&ar8xxx_dev_list_lock); + list_for_each_entry(priv, &ar8xxx_dev_list, list) + if (priv->mii_bus == phydev->bus) + goto found; - priv->phy = phydev; + priv = ar8xxx_create_mii(phydev->bus); + if (priv == NULL) { + ret = -ENOMEM; + goto unlock; + } ret = ar8xxx_probe_switch(priv); if (ret) - goto out; + goto free_priv; +found: if (phydev->addr == 0) { if (ar8xxx_has_gige(priv)) { phydev->supported = SUPPORTED_1000baseT_Full; @@ -2061,10 +2055,19 @@ ar8216_probe(struct phy_device *phydev) } } - ret = 0; + phydev->priv = priv; + priv->use_count++; -out: + list_add(&priv->list, &ar8xxx_dev_list); + + mutex_unlock(&ar8xxx_dev_list_lock); + + return 0; + +free_priv: ar8xxx_free(priv); +unlock: + mutex_unlock(&ar8xxx_dev_list_lock); return ret; } @@ -2087,14 +2090,18 @@ ar8216_remove(struct phy_device *phydev) { struct ar8216_priv *priv = phydev->priv; - if (!priv) + if (WARN_ON(!priv)) return; phydev->priv = NULL; + if (--priv->use_count > 0) + return; - if (phydev->addr == 0) - unregister_switch(&priv->dev); + mutex_lock(&ar8xxx_dev_list_lock); + list_del(&priv->list); + mutex_unlock(&ar8xxx_dev_list_lock); + unregister_switch(&priv->dev); ar8xxx_mib_stop(priv); ar8xxx_free(priv); } |