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
lede-17.01
Gabor Juhos 2013-02-11 16:11:30 +00:00
parent 1afb759b35
commit 3f3eba88f6
1 changed files with 40 additions and 33 deletions

View File

@ -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);
}