generic: ar8216: use dynamically allocated private data in ar8216_probe
[librecmc/librecmc.git] / target / linux / generic / files / drivers / net / phy / ar8216.c
index 97ce04720c0b4b2e775b286c66a289b85dc0bf50..5a8a9381891cca96dba398adcf3f2d968c4ad9a5 100644 (file)
@@ -733,6 +733,9 @@ static int
 ar8327_hw_init(struct ar8216_priv *priv)
 {
        struct ar8327_platform_data *pdata;
+       struct ar8327_led_cfg *led_cfg;
+       struct mii_bus *bus;
+       u32 pos, new_pos;
        u32 t;
        int i;
 
@@ -747,11 +750,41 @@ ar8327_hw_init(struct ar8216_priv *priv)
        t = ar8327_get_pad_cfg(pdata->pad6_cfg);
        priv->write(priv, AR8327_REG_PAD6_MODE, t);
 
-       priv->write(priv, AR8327_REG_POWER_ON_STRIP, 0x40000000);
+       pos = priv->read(priv, AR8327_REG_POWER_ON_STRIP);
+       new_pos = pos;
+
+       led_cfg = pdata->led_cfg;
+       if (led_cfg) {
+               if (led_cfg->open_drain)
+                       new_pos |= AR8327_POWER_ON_STRIP_LED_OPEN_EN;
+               else
+                       new_pos &= ~AR8327_POWER_ON_STRIP_LED_OPEN_EN;
+
+               priv->write(priv, AR8327_REG_LED_CTRL0, led_cfg->led_ctrl0);
+               priv->write(priv, AR8327_REG_LED_CTRL1, led_cfg->led_ctrl1);
+               priv->write(priv, AR8327_REG_LED_CTRL2, led_cfg->led_ctrl2);
+               priv->write(priv, AR8327_REG_LED_CTRL3, led_cfg->led_ctrl3);
+       }
+
+       if (new_pos != pos) {
+               new_pos |= AR8327_POWER_ON_STRIP_POWER_ON_SEL;
+               priv->write(priv, AR8327_REG_POWER_ON_STRIP, new_pos);
+       }
 
-       for (i = 0; i < AR8327_NUM_PHYS; i++)
+       bus = priv->phy->bus;
+       for (i = 0; i < AR8327_NUM_PHYS; i++) {
                ar8327_phy_fixup(priv, i);
 
+               /* start aneg on the PHY */
+               mdiobus_write(bus, i, MII_ADVERTISE, ADVERTISE_ALL |
+                                                    ADVERTISE_PAUSE_CAP |
+                                                    ADVERTISE_PAUSE_ASYM);
+               mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL);
+               mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
+       }
+
+       msleep(1000);
+
        return 0;
 }
 
@@ -1448,10 +1481,19 @@ ar8216_config_aneg(struct phy_device *phydev)
 static int
 ar8216_probe(struct phy_device *pdev)
 {
-       struct ar8216_priv priv;
+       struct ar8216_priv *priv;
+       int ret;
+
+       priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return -ENOMEM;
 
-       priv.phy = pdev;
-       return ar8216_id_chip(&priv);
+       priv->phy = pdev;
+
+       ret = ar8216_id_chip(priv);
+       kfree(priv);
+
+       return ret;
 }
 
 static void