]> xenbits.xensource.com Git - people/julieng/linux-arm.git/commitdiff
net, phy, apci: Allow to initialize Marvell phy in the ACPI way.
authorTomasz Nowicki <tomasz.nowicki@linaro.org>
Tue, 16 Dec 2014 17:02:39 +0000 (18:02 +0100)
committerJulien Grall <julien.grall@citrix.com>
Mon, 28 Sep 2015 11:05:21 +0000 (12:05 +0100)
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
drivers/net/phy/marvell.c

index f721444c2b0a9413dd0bac8c7e61099cf6d3789b..c07a5fc2967dde0f7c249fbbb542b8792ae44452 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/phy.h>
 #include <linux/marvell_phy.h>
 #include <linux/of.h>
+#include <linux/acpi.h>
 
 #include <linux/io.h>
 #include <asm/irq.h>
@@ -226,20 +227,6 @@ static int marvell_config_aneg(struct phy_device *phydev)
 }
 
 #ifdef CONFIG_OF_MDIO
-/*
- * Set and/or override some configuration registers based on the
- * marvell,reg-init property stored in the of_node for the phydev.
- *
- * marvell,reg-init = <reg-page reg mask value>,...;
- *
- * There may be one or more sets of <reg-page reg mask value>:
- *
- * reg-page: which register bank to use.
- * reg: the register.
- * mask: if non-zero, ANDed with existing register value.
- * value: ORed with the masked value and written to the regiser.
- *
- */
 static int marvell_of_reg_init(struct phy_device *phydev)
 {
        const __be32 *paddr;
@@ -306,6 +293,99 @@ static int marvell_of_reg_init(struct phy_device *phydev)
 }
 #endif /* CONFIG_OF_MDIO */
 
+#ifdef CONFIG_ACPI
+static int marvell_acpi_reg_init(struct phy_device *phydev)
+{
+       const union acpi_object *items;
+       const union acpi_object *obj;
+       int len, i, saved_page, current_page, page_changed, ret;
+
+       ret = acpi_dev_get_property_array(ACPI_COMPANION(&phydev->dev),
+                       "marvell,reg-init", ACPI_TYPE_ANY, &obj);
+       if (ret)
+               return 0;
+
+       saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE);
+       if (saved_page < 0)
+               return saved_page;
+       page_changed = 0;
+       current_page = saved_page;
+
+       items = obj->package.elements;
+       len = obj->package.count;
+       ret = 0;
+       for (i = 0; i < len - 3; i += 4) {
+               u16 reg_page = items[i].integer.value;
+               u16 reg = items[i + 1].integer.value;
+               u16 mask = items[i + 2].integer.value;
+               u16 val_bits = items[i + 3].integer.value;
+               int val;
+
+               if (reg_page != current_page) {
+                       current_page = reg_page;
+                       page_changed = 1;
+                       ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page);
+                       if (ret < 0)
+                               goto err;
+               }
+
+               val = 0;
+               if (mask) {
+                       val = phy_read(phydev, reg);
+                       if (val < 0) {
+                               ret = val;
+                               goto err;
+                       }
+                       val &= mask;
+               }
+               val |= val_bits;
+
+               ret = phy_write(phydev, reg, val);
+               if (ret < 0)
+                       goto err;
+
+       }
+err:
+       if (page_changed) {
+               i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page);
+               if (ret == 0)
+                       ret = i;
+       }
+       return ret;
+}
+#else
+static int marvell_acpi_reg_init(struct phy_device *phydev)
+{
+       return 0;
+}
+#endif /* CONFIG_ACPI */
+
+/*
+ * Set and/or override some configuration registers based on the
+ * marvell,reg-init property stored in the of_node for the phydev.
+ *
+ * marvell,reg-init = <reg-page reg mask value>,...;
+ *
+ * There may be one or more sets of <reg-page reg mask value>:
+ *
+ * reg-page: which register bank to use.
+ * reg: the register.
+ * mask: if non-zero, ANDed with existing register value.
+ * value: ORed with the masked value and written to the regiser.
+ *
+ */
+static int marvell_reg_init(struct phy_device *phydev)
+{
+       int ret;
+
+       if (phydev->dev.of_node)
+               ret = marvell_of_reg_init(phydev);
+       else
+               ret = marvell_acpi_reg_init(phydev);
+
+       return ret;
+}
+
 static int m88e1121_config_aneg(struct phy_device *phydev)
 {
        int err, oldpage, mscr;
@@ -390,7 +470,7 @@ static int m88e1510_config_aneg(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       return marvell_of_reg_init(phydev);
+       return marvell_reg_init(phydev);
 }
 
 static int m88e1116r_config_init(struct phy_device *phydev)
@@ -552,7 +632,7 @@ static int m88e1111_config_init(struct phy_device *phydev)
                        return err;
        }
 
-       err = marvell_of_reg_init(phydev);
+       err = marvell_reg_init(phydev);
        if (err < 0)
                return err;
 
@@ -603,7 +683,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       err = marvell_of_reg_init(phydev);
+       err = marvell_reg_init(phydev);
        if (err < 0)
                return err;
 
@@ -629,7 +709,7 @@ static int m88e1149_config_init(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       err = marvell_of_reg_init(phydev);
+       err = marvell_reg_init(phydev);
        if (err < 0)
                return err;
 
@@ -715,7 +795,7 @@ static int m88e1145_config_init(struct phy_device *phydev)
                        return err;
        }
 
-       err = marvell_of_reg_init(phydev);
+       err = marvell_reg_init(phydev);
        if (err < 0)
                return err;