diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch | 651 |
1 files changed, 651 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch b/target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch new file mode 100644 index 0000000000..fbf13c8ffc --- /dev/null +++ b/target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch @@ -0,0 +1,651 @@ +From 8848f975ce42674b8bc8dedb5c7b326a42088e99 Mon Sep 17 00:00:00 2001 +From: Calvin Johnson <calvin.johnson@nxp.com> +Date: Mon, 10 Dec 2018 10:22:33 +0530 +Subject: [PATCH] staging: fsl_ppfe/eth: separate mdio init from mac init + +- separate mdio initialization from mac initialization +- Define pfe_mdio_priv_s structure to hold mii_bus structure and other + related data. +- Modify functions to work with the separted mdio init model. + +Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com> +--- + drivers/staging/fsl_ppfe/pfe_eth.c | 232 ++++++++++-------------- + drivers/staging/fsl_ppfe/pfe_eth.h | 17 +- + drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 50 ++--- + drivers/staging/fsl_ppfe/pfe_mod.h | 1 + + 4 files changed, 126 insertions(+), 174 deletions(-) + +--- a/drivers/staging/fsl_ppfe/pfe_eth.c ++++ b/drivers/staging/fsl_ppfe/pfe_eth.c +@@ -790,10 +790,9 @@ const struct ethtool_ops pfe_ethtool_ops + */ + int pfe_eth_mdio_reset(struct mii_bus *bus) + { +- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; + u32 phy_speed; + +- netif_info(priv, hw, priv->ndev, "%s\n", __func__); + + mutex_lock(&bus->mdio_lock); + +@@ -806,25 +805,25 @@ int pfe_eth_mdio_reset(struct mii_bus *b + phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000) + << EMAC_MII_SPEED_SHIFT); + phy_speed |= EMAC_HOLDTIME(0x5); +- __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG); ++ __raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG); + + mutex_unlock(&bus->mdio_lock); + + return 0; + } + +-/* pfe_eth_gemac_phy_timeout ++/* pfe_eth_mdio_timeout + * + */ +-static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout) ++static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout) + { +- while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) & ++ while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) & + EMAC_IEVENT_MII)) { + if (timeout-- <= 0) + return -1; + usleep_range(10, 20); + } +- __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG); ++ __raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG); + return 0; + } + +@@ -856,16 +855,15 @@ static int pfe_eth_mdio_mux(u8 muxval) + static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id, + int dev_addr, int regnum) + { +- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; + + __raw_writel(EMAC_MII_DATA_PA(mii_id) | + EMAC_MII_DATA_RA(dev_addr) | + EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum), +- priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ priv->mdio_base + EMAC_MII_DATA_REG); + +- if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { +- netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n", +- __func__); ++ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) { ++ dev_err(&bus->dev, "phy MDIO address write timeout\n"); + return -1; + } + +@@ -875,7 +873,7 @@ static int pfe_eth_mdio_write_addr(struc + static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum, + u16 value) + { +- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; + + /*To access external PHYs on QDS board mux needs to be configured*/ + if ((mii_id) && (pfe->mdio_muxval[mii_id])) +@@ -888,30 +886,26 @@ static int pfe_eth_mdio_write(struct mii + EMAC_MII_DATA_PA(mii_id) | + EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | + EMAC_MII_DATA_TA | EMAC_MII_DATA(value), +- priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ priv->mdio_base + EMAC_MII_DATA_REG); + } else { + /* start a write op */ + __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR | + EMAC_MII_DATA_PA(mii_id) | + EMAC_MII_DATA_RA(regnum) | + EMAC_MII_DATA_TA | EMAC_MII_DATA(value), +- priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ priv->mdio_base + EMAC_MII_DATA_REG); + } + +- if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { +- netdev_err(priv->ndev, "%s: phy MDIO write timeout\n", +- __func__); ++ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) { ++ dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__); + return -1; + } +- netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, +- mii_id, regnum, value); +- + return 0; + } + + static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum) + { +- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; + u16 value = 0; + + /*To access external PHYs on QDS board mux needs to be configured*/ +@@ -925,65 +919,67 @@ static int pfe_eth_mdio_read(struct mii_ + EMAC_MII_DATA_PA(mii_id) | + EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | + EMAC_MII_DATA_TA, +- priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ priv->mdio_base + EMAC_MII_DATA_REG); + } else { + /* start a read op */ + __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD | + EMAC_MII_DATA_PA(mii_id) | + EMAC_MII_DATA_RA(regnum) | +- EMAC_MII_DATA_TA, priv->PHY_baseaddr + ++ EMAC_MII_DATA_TA, priv->mdio_base + + EMAC_MII_DATA_REG); + } + +- if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { +- netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__); ++ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) { ++ dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__); + return -1; + } + +- value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr + ++ value = EMAC_MII_DATA(__raw_readl(priv->mdio_base + + EMAC_MII_DATA_REG)); +- netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, +- mii_id, regnum, value); + return value; + } + +-static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv, +- struct ls1012a_mdio_platform_data *minfo) ++static int pfe_eth_mdio_init(struct pfe *pfe, ++ struct ls1012a_pfe_platform_data *pfe_info, ++ int ii) + { ++ struct pfe_mdio_priv_s *priv = NULL; ++ struct ls1012a_mdio_platform_data *mdio_info; + struct mii_bus *bus; + struct device_node *mdio_node; +- int rc = 0, ii; +- struct phy_device *phydev; ++ int rc = 0; + +- netif_info(priv, drv, priv->ndev, "%s\n", __func__); +- pr_info("%s\n", __func__); ++ mdio_info = (struct ls1012a_mdio_platform_data *) ++ pfe_info->ls1012a_mdio_pdata; ++ mdio_info->id = ii; + +- bus = mdiobus_alloc(); ++ bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s)); + if (!bus) { +- netdev_err(priv->ndev, "mdiobus_alloc() failed\n"); ++ pr_err("mdiobus_alloc() failed\n"); + rc = -ENOMEM; +- goto err0; ++ goto err_mdioalloc; + } + + bus->name = "ls1012a MDIO Bus"; +- snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id); ++ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id); + +- bus->priv = priv; + bus->read = &pfe_eth_mdio_read; + bus->write = &pfe_eth_mdio_write; + bus->reset = &pfe_eth_mdio_reset; +- bus->parent = priv->pfe->dev; +- bus->phy_mask = minfo->phy_mask; +- bus->irq[0] = minfo->irq[0]; ++ bus->parent = pfe->dev; ++ bus->phy_mask = mdio_info->phy_mask; ++ bus->irq[0] = mdio_info->irq[0]; ++ priv = bus->priv; ++ priv->mdio_base = cbus_emac_base[ii]; + +- priv->mdc_div = minfo->mdc_div; ++ priv->mdc_div = mdio_info->mdc_div; + if (!priv->mdc_div) + priv->mdc_div = 64; +- netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n", +- __func__, priv->mdc_div, bus->phy_mask); ++ dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n", ++ __func__, priv->mdc_div, bus->phy_mask); + +- mdio_node = of_get_child_by_name(priv->pfe->dev->of_node, "mdio"); +- if (mdio_node) { ++ mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio"); ++ if ((mdio_info->id == 0) && mdio_node) { + rc = of_mdiobus_register(bus, mdio_node); + of_node_put(mdio_node); + } else { +@@ -991,56 +987,34 @@ static int pfe_eth_mdio_init(struct pfe_ + } + + if (rc) { +- netdev_err(priv->ndev, "mdiobus_register(%s) failed\n", +- bus->name); +- goto err1; ++ dev_err(bus->parent, "mdiobus_register(%s) failed\n", ++ bus->name); ++ goto err_mdioregister; + } + + priv->mii_bus = bus; +- +- /* For clause 45 we need to call get_phy_device() with it's +- * 3rd argument as true and then register the phy device +- * via phy_device_register() +- */ +- if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) { +- for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { +- phydev = get_phy_device(priv->mii_bus, +- priv->einfo->phy_id + ii, true); +- if (!phydev || IS_ERR(phydev)) { +- rc = -EIO; +- netdev_err(priv->ndev, "fail to get device\n"); +- goto err1; +- } +- rc = phy_device_register(phydev); +- if (rc) { +- phy_device_free(phydev); +- netdev_err(priv->ndev, +- "phy_device_register() failed\n"); +- goto err1; +- } +- } +- } ++ pfe->mdio.mdio_priv[ii] = priv; + + pfe_eth_mdio_reset(bus); + + return 0; + +-err1: ++err_mdioregister: + mdiobus_free(bus); +-err0: ++err_mdioalloc: + return rc; + } + + /* pfe_eth_mdio_exit + */ +-static void pfe_eth_mdio_exit(struct mii_bus *bus) ++static void pfe_eth_mdio_exit(struct pfe *pfe, ++ int ii) + { ++ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii]; ++ struct mii_bus *bus = mdio_priv->mii_bus; ++ + if (!bus) + return; +- +- netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct +- pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__); +- + mdiobus_unregister(bus); + mdiobus_free(bus); + } +@@ -1221,15 +1195,16 @@ static int pfe_eth_start(struct pfe_eth_ + */ + static void ls1012a_configure_serdes(struct net_device *ndev) + { +- struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0]; ++ struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev); ++ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id]; + int sgmii_2500 = 0; +- struct mii_bus *bus = priv->mii_bus; ++ struct mii_bus *bus = mdio_priv->mii_bus; + u16 value = 0; + +- if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) ++ if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) + sgmii_2500 = 1; + +- netif_info(priv, drv, ndev, "%s\n", __func__); ++ netif_info(eth_priv, drv, ndev, "%s\n", __func__); + /* PCS configuration done with corresponding GEMAC */ + + pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR); +@@ -2333,26 +2308,15 @@ static const struct net_device_ops pfe_n + + /* pfe_eth_init_one + */ +-static int pfe_eth_init_one(struct pfe *pfe, int id) ++static int pfe_eth_init_one(struct pfe *pfe, ++ struct ls1012a_pfe_platform_data *pfe_info, ++ int id) + { + struct net_device *ndev = NULL; + struct pfe_eth_priv_s *priv = NULL; + struct ls1012a_eth_platform_data *einfo; +- struct ls1012a_mdio_platform_data *minfo; +- struct ls1012a_pfe_platform_data *pfe_info; + int err; + +- /* Extract pltform data */ +- pfe_info = (struct ls1012a_pfe_platform_data *) +- pfe->dev->platform_data; +- if (!pfe_info) { +- pr_err( +- "%s: pfe missing additional platform data\n" +- , __func__); +- err = -ENODEV; +- goto err0; +- } +- + einfo = (struct ls1012a_eth_platform_data *) + pfe_info->ls1012a_eth_pdata; + +@@ -2365,18 +2329,6 @@ static int pfe_eth_init_one(struct pfe * + goto err0; + } + +- minfo = (struct ls1012a_mdio_platform_data *) +- pfe_info->ls1012a_mdio_pdata; +- +- /* einfo never be NULL, but no harm in having this check */ +- if (!minfo) { +- pr_err( +- "%s: pfe missing additional mdios platform data\n", +- __func__); +- err = -ENODEV; +- goto err0; +- } +- + if (us) + emac_txq_cnt = EMAC_TXQ_CNT; + /* Create an ethernet device instance */ +@@ -2402,7 +2354,6 @@ static int pfe_eth_init_one(struct pfe * + /* Set the info in the priv to the current info */ + priv->einfo = &einfo[id]; + priv->EMAC_baseaddr = cbus_emac_base[id]; +- priv->PHY_baseaddr = cbus_emac_base[0]; + priv->GPI_baseaddr = cbus_gpi_base[id]; + + spin_lock_init(&priv->lock); +@@ -2412,13 +2363,6 @@ static int pfe_eth_init_one(struct pfe * + /* Copy the station address into the dev structure, */ + memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN); + +- /* Initialize mdio */ +- err = pfe_eth_mdio_init(priv, &minfo[id]); +- if (err) { +- netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", __func__); +- goto err1; +- } +- + if (us) + goto phy_init; + +@@ -2463,7 +2407,7 @@ static int pfe_eth_init_one(struct pfe * + err = register_netdev(ndev); + if (err) { + netdev_err(ndev, "register_netdev() failed\n"); +- goto err2; ++ goto err1; + } + + if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) || +@@ -2480,7 +2424,7 @@ phy_init: + if (err) { + netdev_err(ndev, "%s: pfe_phy_init() failed\n", + __func__); +- goto err3; ++ goto err2; + } + + if (us) { +@@ -2494,21 +2438,19 @@ phy_init: + skip_phy_init: + /* Create all the sysfs files */ + if (pfe_eth_sysfs_init(ndev)) +- goto err4; ++ goto err3; + + netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n", + __func__, priv->EMAC_baseaddr); + + return 0; + +-err4: +- pfe_phy_exit(priv->ndev); + err3: ++ pfe_phy_exit(priv->ndev); ++err2: + if (us) +- goto err2; ++ goto err1; + unregister_netdev(ndev); +-err2: +- pfe_eth_mdio_exit(priv->mii_bus); + err1: + free_netdev(priv->ndev); + err0: +@@ -2521,6 +2463,7 @@ int pfe_eth_init(struct pfe *pfe) + { + int ii = 0; + int err; ++ struct ls1012a_pfe_platform_data *pfe_info; + + pr_info("%s\n", __func__); + +@@ -2530,24 +2473,43 @@ int pfe_eth_init(struct pfe *pfe) + cbus_gpi_base[0] = EGPI1_BASE_ADDR; + cbus_gpi_base[1] = EGPI2_BASE_ADDR; + ++ pfe_info = (struct ls1012a_pfe_platform_data *) ++ pfe->dev->platform_data; ++ if (!pfe_info) { ++ pr_err("%s: pfe missing additional platform data\n", __func__); ++ err = -ENODEV; ++ goto err_pdata; ++ } ++ ++ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { ++ err = pfe_eth_mdio_init(pfe, pfe_info, ii); ++ if (err) { ++ pr_err("%s: pfe_eth_mdio_init() failed\n", __func__); ++ goto err_mdio_init; ++ } ++ } ++ + if (fsl_guts_get_svr() == LS1012A_REV_1_0) + pfe_errata_a010897 = true; + else + pfe_errata_a010897 = false; + + for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { +- err = pfe_eth_init_one(pfe, ii); ++ err = pfe_eth_init_one(pfe, pfe_info, ii); + if (err) +- goto err0; ++ goto err_eth_init; + } + + return 0; + +-err0: +- while (ii--) ++err_eth_init: ++ while (ii--) { + pfe_eth_exit_one(pfe->eth.eth_priv[ii]); ++ pfe_eth_mdio_exit(pfe, ii); ++ } + +- /* Register three network devices in the kernel */ ++err_mdio_init: ++err_pdata: + return err; + } + +@@ -2573,9 +2535,6 @@ skip_phy_exit: + if (!us) + unregister_netdev(priv->ndev); + +- if (priv->mii_bus) +- pfe_eth_mdio_exit(priv->mii_bus); +- + free_netdev(priv->ndev); + } + +@@ -2589,4 +2548,7 @@ void pfe_eth_exit(struct pfe *pfe) + + for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--) + pfe_eth_exit_one(pfe->eth.eth_priv[ii]); ++ ++ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--) ++ pfe_eth_mdio_exit(pfe, ii); + } +--- a/drivers/staging/fsl_ppfe/pfe_eth.h ++++ b/drivers/staging/fsl_ppfe/pfe_eth.h +@@ -48,7 +48,7 @@ struct ls1012a_eth_platform_data { + }; + + struct ls1012a_mdio_platform_data { +- int enabled; ++ int id; + int irq[32]; + u32 phy_mask; + int mdc_div; +@@ -120,8 +120,6 @@ struct pfe_eth_priv_s { + unsigned int event_status; + int irq; + void *EMAC_baseaddr; +- /* This points to the EMAC base from where we access PHY */ +- void *PHY_baseaddr; + void *GPI_baseaddr; + /* PHY stuff */ + struct phy_device *phydev; +@@ -129,9 +127,6 @@ struct pfe_eth_priv_s { + int oldduplex; + int oldlink; + struct device_node *phy_node; +- /* mdio info */ +- int mdc_div; +- struct mii_bus *mii_bus; + struct clk *gemtx_clk; + int wol; + int pause_flag; +@@ -161,6 +156,16 @@ struct pfe_eth { + struct pfe_eth_priv_s *eth_priv[3]; + }; + ++struct pfe_mdio_priv_s { ++ void __iomem *mdio_base; ++ int mdc_div; ++ struct mii_bus *mii_bus; ++}; ++ ++struct pfe_mdio { ++ struct pfe_mdio_priv_s *mdio_priv[3]; ++}; ++ + int pfe_eth_init(struct pfe *pfe); + void pfe_eth_exit(struct pfe *pfe); + int pfe_eth_suspend(struct net_device *dev); +--- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c ++++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c +@@ -21,31 +21,18 @@ + extern bool pfe_use_old_dts_phy; + struct ls1012a_pfe_platform_data pfe_platform_data; + +-static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int +- if_cnt, +- struct ls1012a_pfe_platform_data +- *pdata) ++static int pfe_get_gemac_if_properties(struct device_node *gem, ++ int port, ++ struct ls1012a_pfe_platform_data *pdata) + { +- struct device_node *gem = NULL, *phy = NULL, *phy_node = NULL; ++ struct device_node *phy_node = NULL; + int size; +- int ii = 0, phy_id = 0; ++ int phy_id = 0; + const u32 *addr; + const void *mac_addr; + +- for (ii = 0; ii < if_cnt; ii++) { +- gem = of_get_next_child(parent, gem); +- if (!gem) +- goto err; +- addr = of_get_property(gem, "reg", &size); +- if (addr && (be32_to_cpup(addr) == port)) +- break; +- } +- +- if (ii >= if_cnt) { +- pr_err("%s:%d Failed to find interface = %d\n", +- __func__, __LINE__, if_cnt); +- goto err; +- } ++ addr = of_get_property(gem, "reg", &size); ++ port = be32_to_cpup(addr); + + pdata->ls1012a_eth_pdata[port].gem_id = port; + +@@ -88,14 +75,6 @@ static int pfe_get_gemac_if_properties(s + if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY) + goto done; + +- phy = of_get_next_child(gem, NULL); +- addr = of_get_property(phy, "reg", &size); +- if (!addr) +- pr_err("%s:%d Invalid phy enable flag....\n", +- __func__, __LINE__); +- else +- pdata->ls1012a_mdio_pdata[port].enabled = +- be32_to_cpup(addr); + } else { + pr_info("%s: No PHY or fixed-link\n", __func__); + return 0; +@@ -140,7 +119,7 @@ static int pfe_platform_probe(struct pla + struct resource res; + int ii, rc, interface_count = 0, size = 0; + const u32 *prop; +- struct device_node *np; ++ struct device_node *np, *gem = NULL; + struct clk *pfe_clk; + + np = pdev->dev.of_node; +@@ -224,8 +203,13 @@ static int pfe_platform_probe(struct pla + pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; + + for (ii = 0; ii < interface_count; ii++) { +- pfe_get_gemac_if_properties(np, ii, interface_count, +- &pfe_platform_data); ++ gem = of_get_next_child(np, gem); ++ if (gem) ++ pfe_get_gemac_if_properties(gem, ii, ++ &pfe_platform_data); ++ else ++ pr_err("Unable to find interface %d\n", ii); ++ + } + + pfe->dev = &pdev->dev; +@@ -347,8 +331,8 @@ static int pfe_platform_resume(struct de + for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) { + netdev = pfe->eth.eth_priv[i]->ndev; + +- if (pfe->eth.eth_priv[i]->mii_bus) +- pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus); ++ if (pfe->mdio.mdio_priv[i]->mii_bus) ++ pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus); + + if (netif_running(netdev)) + pfe_eth_resume(netdev); +--- a/drivers/staging/fsl_ppfe/pfe_mod.h ++++ b/drivers/staging/fsl_ppfe/pfe_mod.h +@@ -52,6 +52,7 @@ struct pfe { + struct pfe_ctrl ctrl; + struct pfe_hif hif; + struct pfe_eth eth; ++ struct pfe_mdio mdio; + struct hif_client_s *hif_client[HIF_CLIENTS_MAX]; + #if defined(CFG_DIAGS) + struct pfe_diags diags; |