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; int mib_next_port;
u64 *mib_stats; u64 *mib_stats;
struct list_head list;
unsigned int use_count;
/* all fields below are cleared on reset */ /* all fields below are cleared on reset */
bool vlan; bool vlan;
u16 vlan_id[AR8X16_MAX_VLANS]; 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"), 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 * static inline struct ar8216_priv *
swdev_to_ar8216(struct switch_dev *swdev) swdev_to_ar8216(struct switch_dev *swdev)
{ {
@ -1848,15 +1854,8 @@ ar8216_config_init(struct phy_device *phydev)
struct switch_dev *swdev; struct switch_dev *swdev;
int ret; int ret;
if (!priv) { if (WARN_ON(!priv))
priv = ar8xxx_create_mii(phydev->bus); return -ENODEV;
if (priv == NULL)
return -ENOMEM;
ret = ar8xxx_probe_switch(priv);
if (ret)
goto err_free_priv;
}
priv->phy = phydev; priv->phy = phydev;
@ -1864,23 +1863,17 @@ ar8216_config_init(struct phy_device *phydev)
if (chip_is_ar8316(priv)) { if (chip_is_ar8316(priv)) {
/* check if we're attaching to the switch twice */ /* check if we're attaching to the switch twice */
phydev = phydev->bus->phy_map[0]; phydev = phydev->bus->phy_map[0];
if (!phydev) { if (!phydev)
ar8xxx_free(priv);
return 0; return 0;
}
/* switch device has not been initialized, reuse priv */ /* switch device has not been initialized, reuse priv */
if (!phydev->priv) { if (!phydev->priv) {
priv->port4_phy = true; priv->port4_phy = true;
priv->dev.ports = (AR8216_NUM_PORTS - 1); priv->dev.ports = (AR8216_NUM_PORTS - 1);
phydev->priv = priv;
return 0; return 0;
} }
ar8xxx_free(priv);
/* switch device has been initialized, reinit */ /* switch device has been initialized, reinit */
priv = phydev->priv;
priv->dev.ports = (AR8216_NUM_PORTS - 1); priv->dev.ports = (AR8216_NUM_PORTS - 1);
priv->initialized = false; priv->initialized = false;
priv->port4_phy = true; priv->port4_phy = true;
@ -1888,16 +1881,13 @@ ar8216_config_init(struct phy_device *phydev)
return 0; return 0;
} }
ar8xxx_free(priv);
return 0; return 0;
} }
phydev->priv = priv;
swdev = &priv->dev; swdev = &priv->dev;
ret = register_switch(swdev, phydev->attached_dev); ret = register_switch(swdev, phydev->attached_dev);
if (ret) if (ret)
goto err_free_priv; goto err;
pr_info("%s: %s switch driver attached.\n", pr_info("%s: %s switch driver attached.\n",
phydev->attached_dev->name, swdev->name); phydev->attached_dev->name, swdev->name);
@ -1928,9 +1918,7 @@ ar8216_config_init(struct phy_device *phydev)
err_unregister_switch: err_unregister_switch:
unregister_switch(&priv->dev); unregister_switch(&priv->dev);
err_free_priv: err:
ar8xxx_free(priv);
phydev->priv = NULL;
return ret; return ret;
} }
@ -2036,16 +2024,22 @@ ar8216_probe(struct phy_device *phydev)
if (!ar8xxx_is_possible(phydev->bus)) if (!ar8xxx_is_possible(phydev->bus))
return -ENODEV; return -ENODEV;
priv = ar8xxx_create_mii(phydev->bus); mutex_lock(&ar8xxx_dev_list_lock);
if (priv == NULL) list_for_each_entry(priv, &ar8xxx_dev_list, list)
return -ENOMEM; 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); ret = ar8xxx_probe_switch(priv);
if (ret) if (ret)
goto out; goto free_priv;
found:
if (phydev->addr == 0) { if (phydev->addr == 0) {
if (ar8xxx_has_gige(priv)) { if (ar8xxx_has_gige(priv)) {
phydev->supported = SUPPORTED_1000baseT_Full; 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); ar8xxx_free(priv);
unlock:
mutex_unlock(&ar8xxx_dev_list_lock);
return ret; return ret;
} }
@ -2087,14 +2090,18 @@ ar8216_remove(struct phy_device *phydev)
{ {
struct ar8216_priv *priv = phydev->priv; struct ar8216_priv *priv = phydev->priv;
if (!priv) if (WARN_ON(!priv))
return; return;
phydev->priv = NULL; phydev->priv = NULL;
if (--priv->use_count > 0)
return;
mutex_lock(&ar8xxx_dev_list_lock);
list_del(&priv->list);
mutex_unlock(&ar8xxx_dev_list_lock);
if (phydev->addr == 0)
unregister_switch(&priv->dev); unregister_switch(&priv->dev);
ar8xxx_mib_stop(priv); ar8xxx_mib_stop(priv);
ar8xxx_free(priv); ar8xxx_free(priv);
} }