aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2017-02-02 14:36:50 +0100
committerFelix Fietkau <nbd@nbd.name>2017-02-03 12:35:44 +0100
commit1a52d11d38ddb3cb511a55d01ce4b497322eb1ed (patch)
tree64319d11170480011a50a18124eddcc81b85ba43
parent402193baa155255f08944a579f1f17e016d6cac2 (diff)
downloadupstream-1a52d11d38ddb3cb511a55d01ce4b497322eb1ed.tar.gz
upstream-1a52d11d38ddb3cb511a55d01ce4b497322eb1ed.tar.bz2
upstream-1a52d11d38ddb3cb511a55d01ce4b497322eb1ed.zip
kernel: update phy drivers for 4.9
add backport patches for older kernels Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--target/linux/generic/files/drivers/net/phy/adm6996.c23
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.c70
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8327.c8
-rw-r--r--target/linux/generic/files/drivers/net/phy/ip17xx.c69
-rw-r--r--target/linux/generic/files/drivers/net/phy/mvswitch.c16
-rw-r--r--target/linux/generic/files/drivers/net/phy/psb6970.c19
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8306.c19
-rw-r--r--target/linux/generic/patches-3.18/002-phy_drivers_backport.patch552
-rw-r--r--target/linux/generic/patches-4.4/002-phy_drivers_backport.patch552
9 files changed, 1194 insertions, 134 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/adm6996.c b/target/linux/generic/files/drivers/net/phy/adm6996.c
index 2fe2ee71bc..25776b8366 100644
--- a/target/linux/generic/files/drivers/net/phy/adm6996.c
+++ b/target/linux/generic/files/drivers/net/phy/adm6996.c
@@ -287,7 +287,7 @@ static u16
adm6996_read_mii_reg(struct adm6996_priv *priv, enum admreg reg)
{
struct phy_device *phydev = priv->priv;
- struct mii_bus *bus = phydev->bus;
+ struct mii_bus *bus = phydev->mdio.bus;
return bus->read(bus, PHYADDR(reg));
}
@@ -296,7 +296,7 @@ static void
adm6996_write_mii_reg(struct adm6996_priv *priv, enum admreg reg, u16 val)
{
struct phy_device *phydev = priv->priv;
- struct mii_bus *bus = phydev->bus;
+ struct mii_bus *bus = phydev->mdio.bus;
bus->write(bus, PHYADDR(reg), val);
}
@@ -1019,13 +1019,13 @@ static int adm6996_config_init(struct phy_device *pdev)
pdev->supported = ADVERTISED_100baseT_Full;
pdev->advertising = ADVERTISED_100baseT_Full;
- if (pdev->addr != 0) {
+ if (pdev->mdio.addr != 0) {
pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n"
- , pdev->attached_dev->name, pdev->addr);
+ , pdev->attached_dev->name, pdev->mdio.addr);
return 0;
}
- priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL);
+ priv = devm_kzalloc(&pdev->mdio.dev, sizeof(struct adm6996_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -1045,7 +1045,7 @@ static int adm6996_config_init(struct phy_device *pdev)
}
/*
- * Warning: phydev->priv is NULL if phydev->addr != 0
+ * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
*/
static int adm6996_read_status(struct phy_device *phydev)
{
@@ -1061,7 +1061,7 @@ static int adm6996_read_status(struct phy_device *phydev)
}
/*
- * Warning: phydev->priv is NULL if phydev->addr != 0
+ * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
*/
static int adm6996_config_aneg(struct phy_device *phydev)
{
@@ -1070,11 +1070,11 @@ static int adm6996_config_aneg(struct phy_device *phydev)
static int adm6996_fixup(struct phy_device *dev)
{
- struct mii_bus *bus = dev->bus;
+ struct mii_bus *bus = dev->mdio.bus;
u16 reg;
/* Our custom registers are at PHY addresses 0-10. Claim those. */
- if (dev->addr > 10)
+ if (dev->mdio.addr > 10)
return 0;
/* look for the switch on the bus */
@@ -1121,7 +1121,6 @@ static struct phy_driver adm6996_phy_driver = {
.config_aneg = &adm6996_config_aneg,
.read_status = &adm6996_read_status,
.soft_reset = adm6996_soft_reset,
- .driver = { .owner = THIS_MODULE,},
};
static int adm6996_gpio_probe(struct platform_device *pdev)
@@ -1132,7 +1131,7 @@ static int adm6996_gpio_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;
-
+
priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -1194,7 +1193,7 @@ static int __init adm6996_init(void)
int err;
phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup);
- err = phy_driver_register(&adm6996_phy_driver);
+ err = phy_driver_register(&adm6996_phy_driver, THIS_MODULE);
if (err)
return err;
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 27b062bc47..f3c953b808 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -177,7 +177,7 @@ ar8xxx_phy_check_aneg(struct phy_device *phydev)
if (ret & BMCR_ANENABLE)
return 0;
- dev_info(&phydev->dev, "ANEG disabled, re-enabling ...\n");
+ dev_info(&phydev->mdio.dev, "ANEG disabled, re-enabling ...\n");
ret |= BMCR_ANENABLE | BMCR_ANRESTART;
return phy_write(phydev, MII_BMCR, ret);
}
@@ -1996,7 +1996,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev)
priv->phy = phydev;
- if (phydev->addr != 0) {
+ if (phydev->mdio.addr != 0) {
if (chip_is_ar8316(priv)) {
/* switch device has been initialized, reinit */
priv->dev.ports = (AR8216_NUM_PORTS - 1);
@@ -2044,7 +2044,7 @@ ar8xxx_check_link_states(struct ar8xxx_priv *priv)
/* flush ARL entries for this port if it went down*/
if (!link_new)
priv->chip->atu_flush_port(priv, i);
- dev_info(&priv->phy->dev, "Port %d is %s\n",
+ dev_info(&priv->phy->mdio.dev, "Port %d is %s\n",
i, link_new ? "up" : "down");
}
@@ -2063,10 +2063,10 @@ ar8xxx_phy_read_status(struct phy_device *phydev)
if (phydev->state == PHY_CHANGELINK)
ar8xxx_check_link_states(priv);
- if (phydev->addr != 0)
+ if (phydev->mdio.addr != 0)
return genphy_read_status(phydev);
- ar8216_read_port_link(priv, phydev->addr, &link);
+ ar8216_read_port_link(priv, phydev->mdio.addr, &link);
phydev->link = !!link.link;
if (!phydev->link)
return 0;
@@ -2096,7 +2096,7 @@ ar8xxx_phy_read_status(struct phy_device *phydev)
static int
ar8xxx_phy_config_aneg(struct phy_device *phydev)
{
- if (phydev->addr == 0)
+ if (phydev->mdio.addr == 0)
return 0;
return genphy_config_aneg(phydev);
@@ -2151,15 +2151,15 @@ ar8xxx_phy_probe(struct phy_device *phydev)
int ret;
/* skip PHYs at unused adresses */
- if (phydev->addr != 0 && phydev->addr != 4)
+ if (phydev->mdio.addr != 0 && phydev->mdio.addr != 4)
return -ENODEV;
- if (!ar8xxx_is_possible(phydev->bus))
+ if (!ar8xxx_is_possible(phydev->mdio.bus))
return -ENODEV;
mutex_lock(&ar8xxx_dev_list_lock);
list_for_each_entry(priv, &ar8xxx_dev_list, list)
- if (priv->mii_bus == phydev->bus)
+ if (priv->mii_bus == phydev->mdio.bus)
goto found;
priv = ar8xxx_create();
@@ -2168,7 +2168,7 @@ ar8xxx_phy_probe(struct phy_device *phydev)
goto unlock;
}
- priv->mii_bus = phydev->bus;
+ priv->mii_bus = phydev->mdio.bus;
ret = ar8xxx_probe_switch(priv);
if (ret)
@@ -2189,7 +2189,7 @@ ar8xxx_phy_probe(struct phy_device *phydev)
found:
priv->use_count++;
- if (phydev->addr == 0) {
+ if (phydev->mdio.addr == 0) {
if (ar8xxx_has_gige(priv)) {
phydev->supported = SUPPORTED_1000baseT_Full;
phydev->advertising = ADVERTISED_1000baseT_Full;
@@ -2270,44 +2270,28 @@ ar8xxx_phy_remove(struct phy_device *phydev)
ar8xxx_free(priv);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
static int
ar8xxx_phy_soft_reset(struct phy_device *phydev)
{
/* we don't need an extra reset */
return 0;
}
-#endif
-
-static struct phy_driver ar8xxx_phy_driver = {
- .phy_id = 0x004d0000,
- .name = "Atheros AR8216/AR8236/AR8316",
- .phy_id_mask = 0xffff0000,
- .features = PHY_BASIC_FEATURES,
- .probe = ar8xxx_phy_probe,
- .remove = ar8xxx_phy_remove,
- .detach = ar8xxx_phy_detach,
- .config_init = ar8xxx_phy_config_init,
- .config_aneg = ar8xxx_phy_config_aneg,
- .read_status = ar8xxx_phy_read_status,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
- .soft_reset = ar8xxx_phy_soft_reset,
-#endif
- .driver = { .owner = THIS_MODULE },
-};
-int __init
-ar8xxx_init(void)
-{
- return phy_driver_register(&ar8xxx_phy_driver);
-}
-
-void __exit
-ar8xxx_exit(void)
-{
- phy_driver_unregister(&ar8xxx_phy_driver);
-}
+static struct phy_driver ar8xxx_phy_driver[] = {
+ {
+ .phy_id = 0x004d0000,
+ .name = "Atheros AR8216/AR8236/AR8316",
+ .phy_id_mask = 0xffff0000,
+ .features = PHY_BASIC_FEATURES,
+ .probe = ar8xxx_phy_probe,
+ .remove = ar8xxx_phy_remove,
+ .detach = ar8xxx_phy_detach,
+ .config_init = ar8xxx_phy_config_init,
+ .config_aneg = ar8xxx_phy_config_aneg,
+ .read_status = ar8xxx_phy_read_status,
+ .soft_reset = ar8xxx_phy_soft_reset,
+ }
+};
-module_init(ar8xxx_init);
-module_exit(ar8xxx_exit);
+module_phy_driver(ar8xxx_phy_driver);
MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c
index 72e0abc9d6..9b40cd7e42 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.c
@@ -619,11 +619,11 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
if (!priv->chip_data)
return -ENOMEM;
- if (priv->phy->dev.of_node)
- ret = ar8327_hw_config_of(priv, priv->phy->dev.of_node);
+ if (priv->phy->mdio.dev.of_node)
+ ret = ar8327_hw_config_of(priv, priv->phy->mdio.dev.of_node);
else
ret = ar8327_hw_config_pdata(priv,
- priv->phy->dev.platform_data);
+ priv->phy->mdio.dev.platform_data);
if (ret)
return ret;
@@ -1028,6 +1028,7 @@ ar8327_sw_get_eee(struct switch_dev *dev,
return 0;
}
+#if 0
static void
ar8327_wait_atu_ready(struct ar8xxx_priv *priv, u16 r2, u16 r1)
{
@@ -1040,7 +1041,6 @@ ar8327_wait_atu_ready(struct ar8xxx_priv *priv, u16 r2, u16 r1)
pr_err("ar8327: timeout waiting for atu to become ready\n");
}
-#if 0
static void ar8327_get_arl_entry(struct ar8xxx_priv *priv,
struct arl_entry *a, u32 *status, enum arl_op op)
{
diff --git a/target/linux/generic/files/drivers/net/phy/ip17xx.c b/target/linux/generic/files/drivers/net/phy/ip17xx.c
index a4fe53dc5b..9eedfd4d28 100644
--- a/target/linux/generic/files/drivers/net/phy/ip17xx.c
+++ b/target/linux/generic/files/drivers/net/phy/ip17xx.c
@@ -1273,7 +1273,7 @@ static int ip17xx_probe(struct phy_device *pdev)
int err;
/* We only attach to PHY 0, but use all available PHYs */
- if (pdev->addr != 0)
+ if (pdev->mdio.addr != 0)
return -ENODEV;
state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -1283,7 +1283,7 @@ static int ip17xx_probe(struct phy_device *pdev)
dev = &state->dev;
pdev->priv = state;
- state->mii_bus = pdev->bus;
+ state->mii_bus = pdev->mdio.bus;
err = get_model(state);
if (err < 0)
@@ -1295,7 +1295,7 @@ static int ip17xx_probe(struct phy_device *pdev)
dev->name = state->regs->NAME;
dev->ops = &ip17xx_ops;
- pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->dev));
+ pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->mdio.dev));
return 0;
error:
@@ -1353,58 +1353,25 @@ static int ip17xx_read_status(struct phy_device *pdev)
return 0;
}
-static struct phy_driver ip17xx_driver = {
- .name = "IC+ IP17xx",
- .phy_id = 0x02430c00,
- .phy_id_mask = 0x0ffffc00,
- .features = PHY_BASIC_FEATURES,
- .probe = ip17xx_probe,
- .remove = ip17xx_remove,
- .config_init = ip17xx_config_init,
- .config_aneg = ip17xx_config_aneg,
- .aneg_done = ip17xx_aneg_done,
- .update_link = ip17xx_update_link,
- .read_status = ip17xx_read_status,
- .driver = { .owner = THIS_MODULE },
-};
-
-static struct phy_driver ip175a_driver = {
- .name = "IC+ IP175A",
- .phy_id = 0x02430c50,
- .phy_id_mask = 0x0ffffff0,
- .features = PHY_BASIC_FEATURES,
- .probe = ip17xx_probe,
- .remove = ip17xx_remove,
- .config_init = ip17xx_config_init,
- .config_aneg = ip17xx_config_aneg,
- .aneg_done = ip17xx_aneg_done,
- .update_link = ip17xx_update_link,
- .read_status = ip17xx_read_status,
- .driver = { .owner = THIS_MODULE },
+static struct phy_driver ip17xx_driver[] = {
+ {
+ .name = "IC+ IP17xx",
+ .phy_id = 0x02430c00,
+ .phy_id_mask = 0x0ffffc00,
+ .features = PHY_BASIC_FEATURES,
+ .probe = ip17xx_probe,
+ .remove = ip17xx_remove,
+ .config_init = ip17xx_config_init,
+ .config_aneg = ip17xx_config_aneg,
+ .aneg_done = ip17xx_aneg_done,
+ .update_link = ip17xx_update_link,
+ .read_status = ip17xx_read_status,
+ }
};
-
-int __init ip17xx_init(void)
-{
- int ret;
-
- ret = phy_driver_register(&ip175a_driver);
- if (ret < 0)
- return ret;
-
- return phy_driver_register(&ip17xx_driver);
-}
-
-void __exit ip17xx_exit(void)
-{
- phy_driver_unregister(&ip17xx_driver);
- phy_driver_unregister(&ip175a_driver);
-}
+module_phy_driver(ip17xx_driver);
MODULE_AUTHOR("Patrick Horn <patrick.horn@gmail.com>");
MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>");
MODULE_AUTHOR("Martin Mares <mj@ucw.cz>");
MODULE_LICENSE("GPL");
-
-module_init(ip17xx_init);
-module_exit(ip17xx_exit);
diff --git a/target/linux/generic/files/drivers/net/phy/mvswitch.c b/target/linux/generic/files/drivers/net/phy/mvswitch.c
index af31d0b5ac..a20fce342e 100644
--- a/target/linux/generic/files/drivers/net/phy/mvswitch.c
+++ b/target/linux/generic/files/drivers/net/phy/mvswitch.c
@@ -50,13 +50,17 @@ struct mvswitch_priv {
static inline u16
r16(struct phy_device *phydev, int addr, int reg)
{
- return phydev->bus->read(phydev->bus, addr, reg);
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ return bus->read(bus, addr, reg);
}
static inline void
w16(struct phy_device *phydev, int addr, int reg, u16 val)
{
- phydev->bus->write(phydev->bus, addr, reg, val);
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ bus->write(bus, addr, reg, val);
}
@@ -388,12 +392,13 @@ mvswitch_probe(struct phy_device *pdev)
static int
mvswitch_fixup(struct phy_device *dev)
{
+ struct mii_bus *bus = dev->mdio.bus;
u16 reg;
- if (dev->addr != 0x10)
+ if (dev->mdio.addr != 0x10)
return 0;
- reg = dev->bus->read(dev->bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
+ reg = bus->read(bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
if (reg != MV_IDENT_VALUE)
return 0;
@@ -413,14 +418,13 @@ static struct phy_driver mvswitch_driver = {
.config_init = &mvswitch_config_init,
.config_aneg = &mvswitch_config_aneg,
.read_status = &mvswitch_read_status,
- .driver = { .owner = THIS_MODULE,},
};
static int __init
mvswitch_init(void)
{
phy_register_fixup_for_id(PHY_ANY_ID, mvswitch_fixup);
- return phy_driver_register(&mvswitch_driver);
+ return phy_driver_register(&mvswitch_driver, THIS_MODULE);
}
static void __exit
diff --git a/target/linux/generic/files/drivers/net/phy/psb6970.c b/target/linux/generic/files/drivers/net/phy/psb6970.c
index 2fcd299013..c1a381c052 100644
--- a/target/linux/generic/files/drivers/net/phy/psb6970.c
+++ b/target/linux/generic/files/drivers/net/phy/psb6970.c
@@ -70,12 +70,16 @@ struct psb6970_priv {
static u16 psb6970_mii_read(struct phy_device *phydev, int reg)
{
- return phydev->bus->read(phydev->bus, PHYADDR(reg));
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ return bus->read(bus, PHYADDR(reg));
}
static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val)
{
- phydev->bus->write(phydev->bus, PHYADDR(reg), val);
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ bus->write(bus, PHYADDR(reg), val);
}
static int
@@ -312,11 +316,11 @@ static int psb6970_config_init(struct phy_device *pdev)
priv->phy = pdev;
- if (pdev->addr == 0)
+ if (pdev->mdio.addr == 0)
printk(KERN_INFO "%s: psb6970 switch driver attached.\n",
pdev->attached_dev->name);
- if (pdev->addr != 0) {
+ if (pdev->mdio.addr != 0) {
kfree(priv);
return 0;
}
@@ -384,14 +388,14 @@ static void psb6970_remove(struct phy_device *pdev)
if (!priv)
return;
- if (pdev->addr == 0)
+ if (pdev->mdio.addr == 0)
unregister_switch(&priv->dev);
kfree(priv);
}
static int psb6970_fixup(struct phy_device *dev)
{
- struct mii_bus *bus = dev->bus;
+ struct mii_bus *bus = dev->mdio.bus;
u16 reg;
/* look for the switch on the bus */
@@ -415,13 +419,12 @@ static struct phy_driver psb6970_driver = {
.config_init = &psb6970_config_init,
.config_aneg = &psb6970_config_aneg,
.read_status = &psb6970_read_status,
- .driver = {.owner = THIS_MODULE},
};
int __init psb6970_init(void)
{
phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup);
- return phy_driver_register(&psb6970_driver);
+ return phy_driver_register(&psb6970_driver, THIS_MODULE);
}
module_init(psb6970_init);
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8306.c b/target/linux/generic/files/drivers/net/phy/rtl8306.c
index 5206509c42..7c70109e63 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8306.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8306.c
@@ -872,7 +872,7 @@ rtl8306_config_init(struct phy_device *pdev)
int err;
/* Only init the switch for the primary PHY */
- if (pdev->addr != 0)
+ if (pdev->mdio.addr != 0)
return 0;
val.value.i = 1;
@@ -882,7 +882,7 @@ rtl8306_config_init(struct phy_device *pdev)
priv->dev.ops = &rtl8306_ops;
priv->do_cpu = 0;
priv->page = -1;
- priv->bus = pdev->bus;
+ priv->bus = pdev->mdio.bus;
chipid = rtl_get(dev, RTL_REG_CHIPID);
chipver = rtl_get(dev, RTL_REG_CHIPVER);
@@ -928,13 +928,13 @@ rtl8306_fixup(struct phy_device *pdev)
u16 chipid;
/* Attach to primary LAN port and WAN port */
- if (pdev->addr != 0 && pdev->addr != 4)
+ if (pdev->mdio.addr != 0 && pdev->mdio.addr != 4)
return 0;
memset(&priv, 0, sizeof(priv));
priv.fixup = true;
priv.page = -1;
- priv.bus = pdev->bus;
+ priv.bus = pdev->mdio.bus;
chipid = rtl_get(&priv.dev, RTL_REG_CHIPID);
if (chipid == 0x5988)
pdev->phy_id = RTL8306_MAGIC;
@@ -952,14 +952,14 @@ rtl8306_probe(struct phy_device *pdev)
* share one rtl_priv instance between virtual phy
* devices on the same bus
*/
- if (priv->bus == pdev->bus)
+ if (priv->bus == pdev->mdio.bus)
goto found;
}
priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->bus = pdev->bus;
+ priv->bus = pdev->mdio.bus;
found:
pdev->priv = priv;
@@ -980,7 +980,7 @@ rtl8306_config_aneg(struct phy_device *pdev)
struct rtl_priv *priv = pdev->priv;
/* Only for WAN */
- if (pdev->addr == 0)
+ if (pdev->mdio.addr == 0)
return 0;
/* Restart autonegotiation */
@@ -996,7 +996,7 @@ rtl8306_read_status(struct phy_device *pdev)
struct rtl_priv *priv = pdev->priv;
struct switch_dev *dev = &priv->dev;
- if (pdev->addr == 4) {
+ if (pdev->mdio.addr == 4) {
/* WAN */
pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10;
pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF;
@@ -1037,7 +1037,6 @@ static struct phy_driver rtl8306_driver = {
.config_init = &rtl8306_config_init,
.config_aneg = &rtl8306_config_aneg,
.read_status = &rtl8306_read_status,
- .driver = { .owner = THIS_MODULE,},
};
@@ -1045,7 +1044,7 @@ static int __init
rtl_init(void)
{
phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup);
- return phy_driver_register(&rtl8306_driver);
+ return phy_driver_register(&rtl8306_driver, THIS_MODULE);
}
static void __exit
diff --git a/target/linux/generic/patches-3.18/002-phy_drivers_backport.patch b/target/linux/generic/patches-3.18/002-phy_drivers_backport.patch
new file mode 100644
index 0000000000..c97c759e7e
--- /dev/null
+++ b/target/linux/generic/patches-3.18/002-phy_drivers_backport.patch
@@ -0,0 +1,552 @@
+--- a/drivers/net/phy/adm6996.c
++++ b/drivers/net/phy/adm6996.c
+@@ -287,7 +287,7 @@ static u16
+ adm6996_read_mii_reg(struct adm6996_priv *priv, enum admreg reg)
+ {
+ struct phy_device *phydev = priv->priv;
+- struct mii_bus *bus = phydev->mdio.bus;
++ struct mii_bus *bus = phydev->bus;
+
+ return bus->read(bus, PHYADDR(reg));
+ }
+@@ -296,7 +296,7 @@ static void
+ adm6996_write_mii_reg(struct adm6996_priv *priv, enum admreg reg, u16 val)
+ {
+ struct phy_device *phydev = priv->priv;
+- struct mii_bus *bus = phydev->mdio.bus;
++ struct mii_bus *bus = phydev->bus;
+
+ bus->write(bus, PHYADDR(reg), val);
+ }
+@@ -1019,13 +1019,13 @@ static int adm6996_config_init(struct ph
+ pdev->supported = ADVERTISED_100baseT_Full;
+ pdev->advertising = ADVERTISED_100baseT_Full;
+
+- if (pdev->mdio.addr != 0) {
++ if (pdev->addr != 0) {
+ pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n"
+- , pdev->attached_dev->name, pdev->mdio.addr);
++ , pdev->attached_dev->name, pdev->addr);
+ return 0;
+ }
+
+- priv = devm_kzalloc(&pdev->mdio.dev, sizeof(struct adm6996_priv), GFP_KERNEL);
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+@@ -1045,7 +1045,7 @@ static int adm6996_config_init(struct ph
+ }
+
+ /*
+- * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
++ * Warning: phydev->priv is NULL if phydev->addr != 0
+ */
+ static int adm6996_read_status(struct phy_device *phydev)
+ {
+@@ -1061,7 +1061,7 @@ static int adm6996_read_status(struct ph
+ }
+
+ /*
+- * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
++ * Warning: phydev->priv is NULL if phydev->addr != 0
+ */
+ static int adm6996_config_aneg(struct phy_device *phydev)
+ {
+@@ -1070,11 +1070,11 @@ static int adm6996_config_aneg(struct ph
+
+ static int adm6996_fixup(struct phy_device *dev)
+ {
+- struct mii_bus *bus = dev->mdio.bus;
++ struct mii_bus *bus = dev->bus;
+ u16 reg;
+
+ /* Our custom registers are at PHY addresses 0-10. Claim those. */
+- if (dev->mdio.addr > 10)
++ if (dev->addr > 10)
+ return 0;
+
+ /* look for the switch on the bus */
+@@ -1121,6 +1121,7 @@ static struct phy_driver adm6996_phy_dri
+ .config_aneg = &adm6996_config_aneg,
+ .read_status = &adm6996_read_status,
+ .soft_reset = adm6996_soft_reset,
++ .driver = { .owner = THIS_MODULE,},
+ };
+
+ static int adm6996_gpio_probe(struct platform_device *pdev)
+@@ -1193,7 +1194,7 @@ static int __init adm6996_init(void)
+ int err;
+
+ phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup);
+- err = phy_driver_register(&adm6996_phy_driver, THIS_MODULE);
++ err = phy_driver_register(&adm6996_phy_driver);
+ if (err)
+ return err;
+
+--- a/drivers/net/phy/ar8216.c
++++ b/drivers/net/phy/ar8216.c
+@@ -177,7 +177,7 @@ ar8xxx_phy_check_aneg(struct phy_device
+ if (ret & BMCR_ANENABLE)
+ return 0;
+
+- dev_info(&phydev->mdio.dev, "ANEG disabled, re-enabling ...\n");
++ dev_info(&phydev->dev, "ANEG disabled, re-enabling ...\n");
+ ret |= BMCR_ANENABLE | BMCR_ANRESTART;
+ return phy_write(phydev, MII_BMCR, ret);
+ }
+@@ -1996,7 +1996,7 @@ ar8xxx_phy_config_init(struct phy_device
+
+ priv->phy = phydev;
+
+- if (phydev->mdio.addr != 0) {
++ if (phydev->addr != 0) {
+ if (chip_is_ar8316(priv)) {
+ /* switch device has been initialized, reinit */
+ priv->dev.ports = (AR8216_NUM_PORTS - 1);
+@@ -2044,7 +2044,7 @@ ar8xxx_check_link_states(struct ar8xxx_p
+ /* flush ARL entries for this port if it went down*/
+ if (!link_new)
+ priv->chip->atu_flush_port(priv, i);
+- dev_info(&priv->phy->mdio.dev, "Port %d is %s\n",
++ dev_info(&priv->phy->dev, "Port %d is %s\n",
+ i, link_new ? "up" : "down");
+ }
+
+@@ -2063,10 +2063,10 @@ ar8xxx_phy_read_status(struct phy_device
+ if (phydev->state == PHY_CHANGELINK)
+ ar8xxx_check_link_states(priv);
+
+- if (phydev->mdio.addr != 0)
++ if (phydev->addr != 0)
+ return genphy_read_status(phydev);
+
+- ar8216_read_port_link(priv, phydev->mdio.addr, &link);
++ ar8216_read_port_link(priv, phydev->addr, &link);
+ phydev->link = !!link.link;
+ if (!phydev->link)
+ return 0;
+@@ -2096,7 +2096,7 @@ ar8xxx_phy_read_status(struct phy_device
+ static int
+ ar8xxx_phy_config_aneg(struct phy_device *phydev)
+ {
+- if (phydev->mdio.addr == 0)
++ if (phydev->addr == 0)
+ return 0;
+
+ return genphy_config_aneg(phydev);
+@@ -2151,15 +2151,15 @@ ar8xxx_phy_probe(struct phy_device *phyd
+ int ret;
+
+ /* skip PHYs at unused adresses */
+- if (phydev->mdio.addr != 0 && phydev->mdio.addr != 4)
++ if (phydev->addr != 0 && phydev->addr != 4)
+ return -ENODEV;
+
+- if (!ar8xxx_is_possible(phydev->mdio.bus))
++ if (!ar8xxx_is_possible(phydev->bus))
+ return -ENODEV;
+
+ mutex_lock(&ar8xxx_dev_list_lock);
+ list_for_each_entry(priv, &ar8xxx_dev_list, list)
+- if (priv->mii_bus == phydev->mdio.bus)
++ if (priv->mii_bus == phydev->bus)
+ goto found;
+
+ priv = ar8xxx_create();
+@@ -2168,7 +2168,7 @@ ar8xxx_phy_probe(struct phy_device *phyd
+ goto unlock;
+ }
+
+- priv->mii_bus = phydev->mdio.bus;
++ priv->mii_bus = phydev->bus;
+
+ ret = ar8xxx_probe_switch(priv);
+ if (ret)
+@@ -2189,7 +2189,7 @@ ar8xxx_phy_probe(struct phy_device *phyd
+ found:
+ priv->use_count++;
+
+- if (phydev->mdio.addr == 0) {
++ if (phydev->addr == 0) {
+ if (ar8xxx_has_gige(priv)) {
+ phydev->supported = SUPPORTED_1000baseT_Full;
+ phydev->advertising = ADVERTISED_1000baseT_Full;
+@@ -2277,21 +2277,33 @@ ar8xxx_phy_soft_reset(struct phy_device
+ return 0;
+ }
+
+-static struct phy_driver ar8xxx_phy_driver[] = {
+- {
+- .phy_id = 0x004d0000,
+- .name = "Atheros AR8216/AR8236/AR8316",
+- .phy_id_mask = 0xffff0000,
+- .features = PHY_BASIC_FEATURES,
+- .probe = ar8xxx_phy_probe,
+- .remove = ar8xxx_phy_remove,
+- .detach = ar8xxx_phy_detach,
+- .config_init = ar8xxx_phy_config_init,
+- .config_aneg = ar8xxx_phy_config_aneg,
+- .read_status = ar8xxx_phy_read_status,
+- .soft_reset = ar8xxx_phy_soft_reset,
+- }
++static struct phy_driver ar8xxx_phy_driver = {
++ .phy_id = 0x004d0000,
++ .name = "Atheros AR8216/AR8236/AR8316",
++ .phy_id_mask = 0xffff0000,
++ .features = PHY_BASIC_FEATURES,
++ .probe = ar8xxx_phy_probe,
++ .remove = ar8xxx_phy_remove,
++ .detach = ar8xxx_phy_detach,
++ .config_init = ar8xxx_phy_config_init,
++ .config_aneg = ar8xxx_phy_config_aneg,
++ .read_status = ar8xxx_phy_read_status,
++ .soft_reset = ar8xxx_phy_soft_reset,
++ .driver = { .owner = THIS_MODULE },
+ };
+
+-module_phy_driver(ar8xxx_phy_driver);
++int __init
++ar8xxx_init(void)
++{
++ return phy_driver_register(&ar8xxx_phy_driver);
++}
++
++void __exit
++ar8xxx_exit(void)
++{
++ phy_driver_unregister(&ar8xxx_phy_driver);
++}
++
++module_init(ar8xxx_init);
++module_exit(ar8xxx_exit);
+ MODULE_LICENSE("GPL");
+--- a/drivers/net/phy/ar8327.c
++++ b/drivers/net/phy/ar8327.c
+@@ -619,11 +619,11 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
+ if (!priv->chip_data)
+ return -ENOMEM;
+
+- if (priv->phy->mdio.dev.of_node)
+- ret = ar8327_hw_config_of(priv, priv->phy->mdio.dev.of_node);
++ if (priv->phy->dev.of_node)
++ ret = ar8327_hw_config_of(priv, priv->phy->dev.of_node);
+ else
+ ret = ar8327_hw_config_pdata(priv,
+- priv->phy->mdio.dev.platform_data);
++ priv->phy->dev.platform_data);
+
+ if (ret)
+ return ret;
+--- a/drivers/net/phy/ip17xx.c
++++ b/drivers/net/phy/ip17xx.c
+@@ -1273,7 +1273,7 @@ static int ip17xx_probe(struct phy_devic
+ int err;
+
+ /* We only attach to PHY 0, but use all available PHYs */
+- if (pdev->mdio.addr != 0)
++ if (pdev->addr != 0)
+ return -ENODEV;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+@@ -1283,7 +1283,7 @@ static int ip17xx_probe(struct phy_devic
+ dev = &state->dev;
+
+ pdev->priv = state;
+- state->mii_bus = pdev->mdio.bus;
++ state->mii_bus = pdev->bus;
+
+ err = get_model(state);
+ if (err < 0)
+@@ -1295,7 +1295,7 @@ static int ip17xx_probe(struct phy_devic
+ dev->name = state->regs->NAME;
+ dev->ops = &ip17xx_ops;
+
+- pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->mdio.dev));
++ pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->dev));
+ return 0;
+
+ error:
+@@ -1353,25 +1353,58 @@ static int ip17xx_read_status(struct phy
+ return 0;
+ }
+
+-static struct phy_driver ip17xx_driver[] = {
+- {
+- .name = "IC+ IP17xx",
+- .phy_id = 0x02430c00,
+- .phy_id_mask = 0x0ffffc00,
+- .features = PHY_BASIC_FEATURES,
+- .probe = ip17xx_probe,
+- .remove = ip17xx_remove,
+- .config_init = ip17xx_config_init,
+- .config_aneg = ip17xx_config_aneg,
+- .aneg_done = ip17xx_aneg_done,
+- .update_link = ip17xx_update_link,
+- .read_status = ip17xx_read_status,
+- }
++static struct phy_driver ip17xx_driver = {
++ .name = "IC+ IP17xx",
++ .phy_id = 0x02430c00,
++ .phy_id_mask = 0x0ffffc00,
++ .features = PHY_BASIC_FEATURES,
++ .probe = ip17xx_probe,
++ .remove = ip17xx_remove,
++ .config_init = ip17xx_config_init,
++ .config_aneg = ip17xx_config_aneg,
++ .aneg_done = ip17xx_aneg_done,
++ .update_link = ip17xx_update_link,
++ .read_status = ip17xx_read_status,
++ .driver = { .owner = THIS_MODULE },
+ };
+
+-module_phy_driver(ip17xx_driver);
++static struct phy_driver ip175a_driver = {
++ .name = "IC+ IP175A",
++ .phy_id = 0x02430c50,
++ .phy_id_mask = 0x0ffffff0,
++ .features = PHY_BASIC_FEATURES,
++ .probe = ip17xx_probe,
++ .remove = ip17xx_remove,
++ .config_init = ip17xx_config_init,
++ .config_aneg = ip17xx_config_aneg,
++ .aneg_done = ip17xx_aneg_done,
++ .update_link = ip17xx_update_link,
++ .read_status = ip17xx_read_status,
++ .driver = { .owner = THIS_MODULE },
++};
++
++
++int __init ip17xx_init(void)
++{
++ int ret;
++
++ ret = phy_driver_register(&ip175a_driver);
++ if (ret < 0)
++ return ret;
++
++ return phy_driver_register(&ip17xx_driver);
++}
++
++void __exit ip17xx_exit(void)
++{
++ phy_driver_unregister(&ip17xx_driver);
++ phy_driver_unregister(&ip175a_driver);
++}
+
+ MODULE_AUTHOR("Patrick Horn <patrick.horn@gmail.com>");
+ MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>");
+ MODULE_AUTHOR("Martin Mares <mj@ucw.cz>");
+ MODULE_LICENSE("GPL");
++
++module_init(ip17xx_init);
++module_exit(ip17xx_exit);
+--- a/drivers/net/phy/mvswitch.c
++++ b/drivers/net/phy/mvswitch.c
+@@ -50,17 +50,13 @@ struct mvswitch_priv {
+ static inline u16
+ r16(struct phy_device *phydev, int addr, int reg)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- return bus->read(bus, addr, reg);
++ return phydev->bus->read(phydev->bus, addr, reg);
+ }
+
+ static inline void
+ w16(struct phy_device *phydev, int addr, int reg, u16 val)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- bus->write(bus, addr, reg, val);
++ phydev->bus->write(phydev->bus, addr, reg, val);
+ }
+
+
+@@ -392,13 +388,12 @@ mvswitch_probe(struct phy_device *pdev)
+ static int
+ mvswitch_fixup(struct phy_device *dev)
+ {
+- struct mii_bus *bus = dev->mdio.bus;
+ u16 reg;
+
+- if (dev->mdio.addr != 0x10)
++ if (dev->addr != 0x10)
+ return 0;
+
+- reg = bus->read(bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
++ reg = dev->bus->read(dev->bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
+ if (reg != MV_IDENT_VALUE)
+ return 0;
+
+@@ -418,13 +413,14 @@ static struct phy_driver mvswitch_driver
+ .config_init = &mvswitch_config_init,
+ .config_aneg = &mvswitch_config_aneg,
+ .read_status = &mvswitch_read_status,
++ .driver = { .owner = THIS_MODULE,},
+ };
+
+ static int __init
+ mvswitch_init(void)
+ {
+ phy_register_fixup_for_id(PHY_ANY_ID, mvswitch_fixup);
+- return phy_driver_register(&mvswitch_driver, THIS_MODULE);
++ return phy_driver_register(&mvswitch_driver);
+ }
+
+ static void __exit
+--- a/drivers/net/phy/psb6970.c
++++ b/drivers/net/phy/psb6970.c
+@@ -70,16 +70,12 @@ struct psb6970_priv {
+
+ static u16 psb6970_mii_read(struct phy_device *phydev, int reg)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- return bus->read(bus, PHYADDR(reg));
++ return phydev->bus->read(phydev->bus, PHYADDR(reg));
+ }
+
+ static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- bus->write(bus, PHYADDR(reg), val);
++ phydev->bus->write(phydev->bus, PHYADDR(reg), val);
+ }
+
+ static int
+@@ -316,11 +312,11 @@ static int psb6970_config_init(struct ph
+
+ priv->phy = pdev;
+
+- if (pdev->mdio.addr == 0)
++ if (pdev->addr == 0)
+ printk(KERN_INFO "%s: psb6970 switch driver attached.\n",
+ pdev->attached_dev->name);
+
+- if (pdev->mdio.addr != 0) {
++ if (pdev->addr != 0) {
+ kfree(priv);
+ return 0;
+ }
+@@ -388,14 +384,14 @@ static void psb6970_remove(struct phy_de
+ if (!priv)
+ return;
+
+- if (pdev->mdio.addr == 0)
++ if (pdev->addr == 0)
+ unregister_switch(&priv->dev);
+ kfree(priv);
+ }
+
+ static int psb6970_fixup(struct phy_device *dev)
+ {
+- struct mii_bus *bus = dev->mdio.bus;
++ struct mii_bus *bus = dev->bus;
+ u16 reg;
+
+ /* look for the switch on the bus */
+@@ -419,12 +415,13 @@ static struct phy_driver psb6970_driver
+ .config_init = &psb6970_config_init,
+ .config_aneg = &psb6970_config_aneg,
+ .read_status = &psb6970_read_status,
++ .driver = {.owner = THIS_MODULE},
+ };
+
+ int __init psb6970_init(void)
+ {
+ phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup);
+- return phy_driver_register(&psb6970_driver, THIS_MODULE);
++ return phy_driver_register(&psb6970_driver);
+ }
+
+ module_init(psb6970_init);
+--- a/drivers/net/phy/rtl8306.c
++++ b/drivers/net/phy/rtl8306.c
+@@ -872,7 +872,7 @@ rtl8306_config_init(struct phy_device *p
+ int err;
+
+ /* Only init the switch for the primary PHY */
+- if (pdev->mdio.addr != 0)
++ if (pdev->addr != 0)
+ return 0;
+
+ val.value.i = 1;
+@@ -882,7 +882,7 @@ rtl8306_config_init(struct phy_device *p
+ priv->dev.ops = &rtl8306_ops;
+ priv->do_cpu = 0;
+ priv->page = -1;
+- priv->bus = pdev->mdio.bus;
++ priv->bus = pdev->bus;
+
+ chipid = rtl_get(dev, RTL_REG_CHIPID);
+ chipver = rtl_get(dev, RTL_REG_CHIPVER);
+@@ -928,13 +928,13 @@ rtl8306_fixup(struct phy_device *pdev)
+ u16 chipid;
+
+ /* Attach to primary LAN port and WAN port */
+- if (pdev->mdio.addr != 0 && pdev->mdio.addr != 4)
++ if (pdev->addr != 0 && pdev->addr != 4)
+ return 0;
+
+ memset(&priv, 0, sizeof(priv));
+ priv.fixup = true;
+ priv.page = -1;
+- priv.bus = pdev->mdio.bus;
++ priv.bus = pdev->bus;
+ chipid = rtl_get(&priv.dev, RTL_REG_CHIPID);
+ if (chipid == 0x5988)
+ pdev->phy_id = RTL8306_MAGIC;
+@@ -952,14 +952,14 @@ rtl8306_probe(struct phy_device *pdev)
+ * share one rtl_priv instance between virtual phy
+ * devices on the same bus
+ */
+- if (priv->bus == pdev->mdio.bus)
++ if (priv->bus == pdev->bus)
+ goto found;
+ }
+ priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+- priv->bus = pdev->mdio.bus;
++ priv->bus = pdev->bus;
+
+ found:
+ pdev->priv = priv;
+@@ -980,7 +980,7 @@ rtl8306_config_aneg(struct phy_device *p
+ struct rtl_priv *priv = pdev->priv;
+
+ /* Only for WAN */
+- if (pdev->mdio.addr == 0)
++ if (pdev->addr == 0)
+ return 0;
+
+ /* Restart autonegotiation */
+@@ -996,7 +996,7 @@ rtl8306_read_status(struct phy_device *p
+ struct rtl_priv *priv = pdev->priv;
+ struct switch_dev *dev = &priv->dev;
+
+- if (pdev->mdio.addr == 4) {
++ if (pdev->addr == 4) {
+ /* WAN */
+ pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10;
+ pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF;
+@@ -1037,6 +1037,7 @@ static struct phy_driver rtl8306_driver
+ .config_init = &rtl8306_config_init,
+ .config_aneg = &rtl8306_config_aneg,
+ .read_status = &rtl8306_read_status,
++ .driver = { .owner = THIS_MODULE,},
+ };
+
+
+@@ -1044,7 +1045,7 @@ static int __init
+ rtl_init(void)
+ {
+ phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup);
+- return phy_driver_register(&rtl8306_driver, THIS_MODULE);
++ return phy_driver_register(&rtl8306_driver);
+ }
+
+ static void __exit
diff --git a/target/linux/generic/patches-4.4/002-phy_drivers_backport.patch b/target/linux/generic/patches-4.4/002-phy_drivers_backport.patch
new file mode 100644
index 0000000000..c97c759e7e
--- /dev/null
+++ b/target/linux/generic/patches-4.4/002-phy_drivers_backport.patch
@@ -0,0 +1,552 @@
+--- a/drivers/net/phy/adm6996.c
++++ b/drivers/net/phy/adm6996.c
+@@ -287,7 +287,7 @@ static u16
+ adm6996_read_mii_reg(struct adm6996_priv *priv, enum admreg reg)
+ {
+ struct phy_device *phydev = priv->priv;
+- struct mii_bus *bus = phydev->mdio.bus;
++ struct mii_bus *bus = phydev->bus;
+
+ return bus->read(bus, PHYADDR(reg));
+ }
+@@ -296,7 +296,7 @@ static void
+ adm6996_write_mii_reg(struct adm6996_priv *priv, enum admreg reg, u16 val)
+ {
+ struct phy_device *phydev = priv->priv;
+- struct mii_bus *bus = phydev->mdio.bus;
++ struct mii_bus *bus = phydev->bus;
+
+ bus->write(bus, PHYADDR(reg), val);
+ }
+@@ -1019,13 +1019,13 @@ static int adm6996_config_init(struct ph
+ pdev->supported = ADVERTISED_100baseT_Full;
+ pdev->advertising = ADVERTISED_100baseT_Full;
+
+- if (pdev->mdio.addr != 0) {
++ if (pdev->addr != 0) {
+ pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n"
+- , pdev->attached_dev->name, pdev->mdio.addr);
++ , pdev->attached_dev->name, pdev->addr);
+ return 0;
+ }
+
+- priv = devm_kzalloc(&pdev->mdio.dev, sizeof(struct adm6996_priv), GFP_KERNEL);
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+@@ -1045,7 +1045,7 @@ static int adm6996_config_init(struct ph
+ }
+
+ /*
+- * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
++ * Warning: phydev->priv is NULL if phydev->addr != 0
+ */
+ static int adm6996_read_status(struct phy_device *phydev)
+ {
+@@ -1061,7 +1061,7 @@ static int adm6996_read_status(struct ph
+ }
+
+ /*
+- * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
++ * Warning: phydev->priv is NULL if phydev->addr != 0
+ */
+ static int adm6996_config_aneg(struct phy_device *phydev)
+ {
+@@ -1070,11 +1070,11 @@ static int adm6996_config_aneg(struct ph
+
+ static int adm6996_fixup(struct phy_device *dev)
+ {
+- struct mii_bus *bus = dev->mdio.bus;
++ struct mii_bus *bus = dev->bus;
+ u16 reg;
+
+ /* Our custom registers are at PHY addresses 0-10. Claim those. */
+- if (dev->mdio.addr > 10)
++ if (dev->addr > 10)
+ return 0;
+
+ /* look for the switch on the bus */
+@@ -1121,6 +1121,7 @@ static struct phy_driver adm6996_phy_dri
+ .config_aneg = &adm6996_config_aneg,
+ .read_status = &adm6996_read_status,
+ .soft_reset = adm6996_soft_reset,
++ .driver = { .owner = THIS_MODULE,},
+ };
+
+ static int adm6996_gpio_probe(struct platform_device *pdev)
+@@ -1193,7 +1194,7 @@ static int __init adm6996_init(void)
+ int err;
+
+ phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup);
+- err = phy_driver_register(&adm6996_phy_driver, THIS_MODULE);
++ err = phy_driver_register(&adm6996_phy_driver);
+ if (err)
+ return err;
+
+--- a/drivers/net/phy/ar8216.c
++++ b/drivers/net/phy/ar8216.c
+@@ -177,7 +177,7 @@ ar8xxx_phy_check_aneg(struct phy_device
+ if (ret & BMCR_ANENABLE)
+ return 0;
+
+- dev_info(&phydev->mdio.dev, "ANEG disabled, re-enabling ...\n");
++ dev_info(&phydev->dev, "ANEG disabled, re-enabling ...\n");
+ ret |= BMCR_ANENABLE | BMCR_ANRESTART;
+ return phy_write(phydev, MII_BMCR, ret);
+ }
+@@ -1996,7 +1996,7 @@ ar8xxx_phy_config_init(struct phy_device
+
+ priv->phy = phydev;
+
+- if (phydev->mdio.addr != 0) {
++ if (phydev->addr != 0) {
+ if (chip_is_ar8316(priv)) {
+ /* switch device has been initialized, reinit */
+ priv->dev.ports = (AR8216_NUM_PORTS - 1);
+@@ -2044,7 +2044,7 @@ ar8xxx_check_link_states(struct ar8xxx_p
+ /* flush ARL entries for this port if it went down*/
+ if (!link_new)
+ priv->chip->atu_flush_port(priv, i);
+- dev_info(&priv->phy->mdio.dev, "Port %d is %s\n",
++ dev_info(&priv->phy->dev, "Port %d is %s\n",
+ i, link_new ? "up" : "down");
+ }
+
+@@ -2063,10 +2063,10 @@ ar8xxx_phy_read_status(struct phy_device
+ if (phydev->state == PHY_CHANGELINK)
+ ar8xxx_check_link_states(priv);
+
+- if (phydev->mdio.addr != 0)
++ if (phydev->addr != 0)
+ return genphy_read_status(phydev);
+
+- ar8216_read_port_link(priv, phydev->mdio.addr, &link);
++ ar8216_read_port_link(priv, phydev->addr, &link);
+ phydev->link = !!link.link;
+ if (!phydev->link)
+ return 0;
+@@ -2096,7 +2096,7 @@ ar8xxx_phy_read_status(struct phy_device
+ static int
+ ar8xxx_phy_config_aneg(struct phy_device *phydev)
+ {
+- if (phydev->mdio.addr == 0)
++ if (phydev->addr == 0)
+ return 0;
+
+ return genphy_config_aneg(phydev);
+@@ -2151,15 +2151,15 @@ ar8xxx_phy_probe(struct phy_device *phyd
+ int ret;
+
+ /* skip PHYs at unused adresses */
+- if (phydev->mdio.addr != 0 && phydev->mdio.addr != 4)
++ if (phydev->addr != 0 && phydev->addr != 4)
+ return -ENODEV;
+
+- if (!ar8xxx_is_possible(phydev->mdio.bus))
++ if (!ar8xxx_is_possible(phydev->bus))
+ return -ENODEV;
+
+ mutex_lock(&ar8xxx_dev_list_lock);
+ list_for_each_entry(priv, &ar8xxx_dev_list, list)
+- if (priv->mii_bus == phydev->mdio.bus)
++ if (priv->mii_bus == phydev->bus)
+ goto found;
+
+ priv = ar8xxx_create();
+@@ -2168,7 +2168,7 @@ ar8xxx_phy_probe(struct phy_device *phyd
+ goto unlock;
+ }
+
+- priv->mii_bus = phydev->mdio.bus;
++ priv->mii_bus = phydev->bus;
+
+ ret = ar8xxx_probe_switch(priv);
+ if (ret)
+@@ -2189,7 +2189,7 @@ ar8xxx_phy_probe(struct phy_device *phyd
+ found:
+ priv->use_count++;
+
+- if (phydev->mdio.addr == 0) {
++ if (phydev->addr == 0) {
+ if (ar8xxx_has_gige(priv)) {
+ phydev->supported = SUPPORTED_1000baseT_Full;
+ phydev->advertising = ADVERTISED_1000baseT_Full;
+@@ -2277,21 +2277,33 @@ ar8xxx_phy_soft_reset(struct phy_device
+ return 0;
+ }
+
+-static struct phy_driver ar8xxx_phy_driver[] = {
+- {
+- .phy_id = 0x004d0000,
+- .name = "Atheros AR8216/AR8236/AR8316",
+- .phy_id_mask = 0xffff0000,
+- .features = PHY_BASIC_FEATURES,
+- .probe = ar8xxx_phy_probe,
+- .remove = ar8xxx_phy_remove,
+- .detach = ar8xxx_phy_detach,
+- .config_init = ar8xxx_phy_config_init,
+- .config_aneg = ar8xxx_phy_config_aneg,
+- .read_status = ar8xxx_phy_read_status,
+- .soft_reset = ar8xxx_phy_soft_reset,
+- }
++static struct phy_driver ar8xxx_phy_driver = {
++ .phy_id = 0x004d0000,
++ .name = "Atheros AR8216/AR8236/AR8316",
++ .phy_id_mask = 0xffff0000,
++ .features = PHY_BASIC_FEATURES,
++ .probe = ar8xxx_phy_probe,
++ .remove = ar8xxx_phy_remove,
++ .detach = ar8xxx_phy_detach,
++ .config_init = ar8xxx_phy_config_init,
++ .config_aneg = ar8xxx_phy_config_aneg,
++ .read_status = ar8xxx_phy_read_status,
++ .soft_reset = ar8xxx_phy_soft_reset,
++ .driver = { .owner = THIS_MODULE },
+ };
+
+-module_phy_driver(ar8xxx_phy_driver);
++int __init
++ar8xxx_init(void)
++{
++ return phy_driver_register(&ar8xxx_phy_driver);
++}
++
++void __exit
++ar8xxx_exit(void)
++{
++ phy_driver_unregister(&ar8xxx_phy_driver);
++}
++
++module_init(ar8xxx_init);
++module_exit(ar8xxx_exit);
+ MODULE_LICENSE("GPL");
+--- a/drivers/net/phy/ar8327.c
++++ b/drivers/net/phy/ar8327.c
+@@ -619,11 +619,11 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
+ if (!priv->chip_data)
+ return -ENOMEM;
+
+- if (priv->phy->mdio.dev.of_node)
+- ret = ar8327_hw_config_of(priv, priv->phy->mdio.dev.of_node);
++ if (priv->phy->dev.of_node)
++ ret = ar8327_hw_config_of(priv, priv->phy->dev.of_node);
+ else
+ ret = ar8327_hw_config_pdata(priv,
+- priv->phy->mdio.dev.platform_data);
++ priv->phy->dev.platform_data);
+
+ if (ret)
+ return ret;
+--- a/drivers/net/phy/ip17xx.c
++++ b/drivers/net/phy/ip17xx.c
+@@ -1273,7 +1273,7 @@ static int ip17xx_probe(struct phy_devic
+ int err;
+
+ /* We only attach to PHY 0, but use all available PHYs */
+- if (pdev->mdio.addr != 0)
++ if (pdev->addr != 0)
+ return -ENODEV;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+@@ -1283,7 +1283,7 @@ static int ip17xx_probe(struct phy_devic
+ dev = &state->dev;
+
+ pdev->priv = state;
+- state->mii_bus = pdev->mdio.bus;
++ state->mii_bus = pdev->bus;
+
+ err = get_model(state);
+ if (err < 0)
+@@ -1295,7 +1295,7 @@ static int ip17xx_probe(struct phy_devic
+ dev->name = state->regs->NAME;
+ dev->ops = &ip17xx_ops;
+
+- pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->mdio.dev));
++ pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->dev));
+ return 0;
+
+ error:
+@@ -1353,25 +1353,58 @@ static int ip17xx_read_status(struct phy
+ return 0;
+ }
+
+-static struct phy_driver ip17xx_driver[] = {
+- {
+- .name = "IC+ IP17xx",
+- .phy_id = 0x02430c00,
+- .phy_id_mask = 0x0ffffc00,
+- .features = PHY_BASIC_FEATURES,
+- .probe = ip17xx_probe,
+- .remove = ip17xx_remove,
+- .config_init = ip17xx_config_init,
+- .config_aneg = ip17xx_config_aneg,
+- .aneg_done = ip17xx_aneg_done,
+- .update_link = ip17xx_update_link,
+- .read_status = ip17xx_read_status,
+- }
++static struct phy_driver ip17xx_driver = {
++ .name = "IC+ IP17xx",
++ .phy_id = 0x02430c00,
++ .phy_id_mask = 0x0ffffc00,
++ .features = PHY_BASIC_FEATURES,
++ .probe = ip17xx_probe,
++ .remove = ip17xx_remove,
++ .config_init = ip17xx_config_init,
++ .config_aneg = ip17xx_config_aneg,
++ .aneg_done = ip17xx_aneg_done,
++ .update_link = ip17xx_update_link,
++ .read_status = ip17xx_read_status,
++ .driver = { .owner = THIS_MODULE },
+ };
+
+-module_phy_driver(ip17xx_driver);
++static struct phy_driver ip175a_driver = {
++ .name = "IC+ IP175A",
++ .phy_id = 0x02430c50,
++ .phy_id_mask = 0x0ffffff0,
++ .features = PHY_BASIC_FEATURES,
++ .probe = ip17xx_probe,
++ .remove = ip17xx_remove,
++ .config_init = ip17xx_config_init,
++ .config_aneg = ip17xx_config_aneg,
++ .aneg_done = ip17xx_aneg_done,
++ .update_link = ip17xx_update_link,
++ .read_status = ip17xx_read_status,
++ .driver = { .owner = THIS_MODULE },
++};
++
++
++int __init ip17xx_init(void)
++{
++ int ret;
++
++ ret = phy_driver_register(&ip175a_driver);
++ if (ret < 0)
++ return ret;
++
++ return phy_driver_register(&ip17xx_driver);
++}
++
++void __exit ip17xx_exit(void)
++{
++ phy_driver_unregister(&ip17xx_driver);
++ phy_driver_unregister(&ip175a_driver);
++}
+
+ MODULE_AUTHOR("Patrick Horn <patrick.horn@gmail.com>");
+ MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>");
+ MODULE_AUTHOR("Martin Mares <mj@ucw.cz>");
+ MODULE_LICENSE("GPL");
++
++module_init(ip17xx_init);
++module_exit(ip17xx_exit);
+--- a/drivers/net/phy/mvswitch.c
++++ b/drivers/net/phy/mvswitch.c
+@@ -50,17 +50,13 @@ struct mvswitch_priv {
+ static inline u16
+ r16(struct phy_device *phydev, int addr, int reg)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- return bus->read(bus, addr, reg);
++ return phydev->bus->read(phydev->bus, addr, reg);
+ }
+
+ static inline void
+ w16(struct phy_device *phydev, int addr, int reg, u16 val)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- bus->write(bus, addr, reg, val);
++ phydev->bus->write(phydev->bus, addr, reg, val);
+ }
+
+
+@@ -392,13 +388,12 @@ mvswitch_probe(struct phy_device *pdev)
+ static int
+ mvswitch_fixup(struct phy_device *dev)
+ {
+- struct mii_bus *bus = dev->mdio.bus;
+ u16 reg;
+
+- if (dev->mdio.addr != 0x10)
++ if (dev->addr != 0x10)
+ return 0;
+
+- reg = bus->read(bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
++ reg = dev->bus->read(dev->bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
+ if (reg != MV_IDENT_VALUE)
+ return 0;
+
+@@ -418,13 +413,14 @@ static struct phy_driver mvswitch_driver
+ .config_init = &mvswitch_config_init,
+ .config_aneg = &mvswitch_config_aneg,
+ .read_status = &mvswitch_read_status,
++ .driver = { .owner = THIS_MODULE,},
+ };
+
+ static int __init
+ mvswitch_init(void)
+ {
+ phy_register_fixup_for_id(PHY_ANY_ID, mvswitch_fixup);
+- return phy_driver_register(&mvswitch_driver, THIS_MODULE);
++ return phy_driver_register(&mvswitch_driver);
+ }
+
+ static void __exit
+--- a/drivers/net/phy/psb6970.c
++++ b/drivers/net/phy/psb6970.c
+@@ -70,16 +70,12 @@ struct psb6970_priv {
+
+ static u16 psb6970_mii_read(struct phy_device *phydev, int reg)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- return bus->read(bus, PHYADDR(reg));
++ return phydev->bus->read(phydev->bus, PHYADDR(reg));
+ }
+
+ static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val)
+ {
+- struct mii_bus *bus = phydev->mdio.bus;
+-
+- bus->write(bus, PHYADDR(reg), val);
++ phydev->bus->write(phydev->bus, PHYADDR(reg), val);
+ }
+
+ static int
+@@ -316,11 +312,11 @@ static int psb6970_config_init(struct ph
+
+ priv->phy = pdev;
+
+- if (pdev->mdio.addr == 0)
++ if (pdev->addr == 0)
+ printk(KERN_INFO "%s: psb6970 switch driver attached.\n",
+ pdev->attached_dev->name);
+
+- if (pdev->mdio.addr != 0) {
++ if (pdev->addr != 0) {
+ kfree(priv);
+ return 0;
+ }
+@@ -388,14 +384,14 @@ static void psb6970_remove(struct phy_de
+ if (!priv)
+ return;
+
+- if (pdev->mdio.addr == 0)
++ if (pdev->addr == 0)
+ unregister_switch(&priv->dev);
+ kfree(priv);
+ }
+
+ static int psb6970_fixup(struct phy_device *dev)
+ {
+- struct mii_bus *bus = dev->mdio.bus;
++ struct mii_bus *bus = dev->bus;
+ u16 reg;
+
+ /* look for the switch on the bus */
+@@ -419,12 +415,13 @@ static struct phy_driver psb6970_driver
+ .config_init = &psb6970_config_init,
+ .config_aneg = &psb6970_config_aneg,
+ .read_status = &psb6970_read_status,
++ .driver = {.owner = THIS_MODULE},
+ };
+
+ int __init psb6970_init(void)
+ {
+ phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup);
+- return phy_driver_register(&psb6970_driver, THIS_MODULE);
++ return phy_driver_register(&psb6970_driver);
+ }
+
+ module_init(psb6970_init);
+--- a/drivers/net/phy/rtl8306.c
++++ b/drivers/net/phy/rtl8306.c
+@@ -872,7 +872,7 @@ rtl8306_config_init(struct phy_device *p
+ int err;
+
+ /* Only init the switch for the primary PHY */
+- if (pdev->mdio.addr != 0)
++ if (pdev->addr != 0)
+ return 0;
+
+ val.value.i = 1;
+@@ -882,7 +882,7 @@ rtl8306_config_init(struct phy_device *p
+ priv->dev.ops = &rtl8306_ops;
+ priv->do_cpu = 0;
+ priv->page = -1;
+- priv->bus = pdev->mdio.bus;
++ priv->bus = pdev->bus;
+
+ chipid = rtl_get(dev, RTL_REG_CHIPID);
+ chipver = rtl_get(dev, RTL_REG_CHIPVER);
+@@ -928,13 +928,13 @@ rtl8306_fixup(struct phy_device *pdev)
+ u16 chipid;
+
+ /* Attach to primary LAN port and WAN port */
+- if (pdev->mdio.addr != 0 && pdev->mdio.addr != 4)
++ if (pdev->addr != 0 && pdev->addr != 4)
+ return 0;
+
+ memset(&priv, 0, sizeof(priv));
+ priv.fixup = true;
+ priv.page = -1;
+- priv.bus = pdev->mdio.bus;
++ priv.bus = pdev->bus;
+ chipid = rtl_get(&priv.dev, RTL_REG_CHIPID);
+ if (chipid == 0x5988)
+ pdev->phy_id = RTL8306_MAGIC;
+@@ -952,14 +952,14 @@ rtl8306_probe(struct phy_device *pdev)
+ * share one rtl_priv instance between virtual phy
+ * devices on the same bus
+ */
+- if (priv->bus == pdev->mdio.bus)
++ if (priv->bus == pdev->bus)
+ goto found;
+ }
+ priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+- priv->bus = pdev->mdio.bus;
++ priv->bus = pdev->bus;
+
+ found:
+ pdev->priv = priv;
+@@ -980,7 +980,7 @@ rtl8306_config_aneg(struct phy_device *p
+ struct rtl_priv *priv = pdev->priv;
+
+ /* Only for WAN */
+- if (pdev->mdio.addr == 0)
++ if (pdev->addr == 0)
+ return 0;
+
+ /* Restart autonegotiation */
+@@ -996,7 +996,7 @@ rtl8306_read_status(struct phy_device *p
+ struct rtl_priv *priv = pdev->priv;
+ struct switch_dev *dev = &priv->dev;
+
+- if (pdev->mdio.addr == 4) {
++ if (pdev->addr == 4) {
+ /* WAN */
+ pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10;
+ pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF;
+@@ -1037,6 +1037,7 @@ static struct phy_driver rtl8306_driver
+ .config_init = &rtl8306_config_init,
+ .config_aneg = &rtl8306_config_aneg,
+ .read_status = &rtl8306_read_status,
++ .driver = { .owner = THIS_MODULE,},
+ };
+
+
+@@ -1044,7 +1045,7 @@ static int __init
+ rtl_init(void)
+ {
+ phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup);
+- return phy_driver_register(&rtl8306_driver, THIS_MODULE);
++ return phy_driver_register(&rtl8306_driver);
+ }
+
+ static void __exit