ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch
1 From 8848f975ce42674b8bc8dedb5c7b326a42088e99 Mon Sep 17 00:00:00 2001
2 From: Calvin Johnson <calvin.johnson@nxp.com>
3 Date: Mon, 10 Dec 2018 10:22:33 +0530
4 Subject: [PATCH] staging: fsl_ppfe/eth: separate mdio init from mac init
5
6 - separate mdio initialization from mac initialization
7 - Define pfe_mdio_priv_s structure to hold mii_bus structure and other
8   related data.
9 - Modify functions to work with the separted mdio init model.
10
11 Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
12 ---
13  drivers/staging/fsl_ppfe/pfe_eth.c              | 232 ++++++++++--------------
14  drivers/staging/fsl_ppfe/pfe_eth.h              |  17 +-
15  drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c |  50 ++---
16  drivers/staging/fsl_ppfe/pfe_mod.h              |   1 +
17  4 files changed, 126 insertions(+), 174 deletions(-)
18
19 --- a/drivers/staging/fsl_ppfe/pfe_eth.c
20 +++ b/drivers/staging/fsl_ppfe/pfe_eth.c
21 @@ -790,10 +790,9 @@ const struct ethtool_ops pfe_ethtool_ops
22   */
23  int pfe_eth_mdio_reset(struct mii_bus *bus)
24  {
25 -       struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
26 +       struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
27         u32 phy_speed;
28  
29 -       netif_info(priv, hw, priv->ndev, "%s\n", __func__);
30  
31         mutex_lock(&bus->mdio_lock);
32  
33 @@ -806,25 +805,25 @@ int pfe_eth_mdio_reset(struct mii_bus *b
34         phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000)
35                      << EMAC_MII_SPEED_SHIFT);
36         phy_speed |= EMAC_HOLDTIME(0x5);
37 -       __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG);
38 +       __raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG);
39  
40         mutex_unlock(&bus->mdio_lock);
41  
42         return 0;
43  }
44  
45 -/* pfe_eth_gemac_phy_timeout
46 +/* pfe_eth_mdio_timeout
47   *
48   */
49 -static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout)
50 +static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout)
51  {
52 -       while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) &
53 +       while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) &
54                         EMAC_IEVENT_MII)) {
55                 if (timeout-- <= 0)
56                         return -1;
57                 usleep_range(10, 20);
58         }
59 -       __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG);
60 +       __raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG);
61         return 0;
62  }
63  
64 @@ -856,16 +855,15 @@ static int pfe_eth_mdio_mux(u8 muxval)
65  static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id,
66                                    int dev_addr, int regnum)
67  {
68 -       struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
69 +       struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
70  
71         __raw_writel(EMAC_MII_DATA_PA(mii_id) |
72                      EMAC_MII_DATA_RA(dev_addr) |
73                      EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum),
74 -                    priv->PHY_baseaddr + EMAC_MII_DATA_REG);
75 +                    priv->mdio_base + EMAC_MII_DATA_REG);
76  
77 -       if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
78 -               netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n",
79 -                          __func__);
80 +       if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
81 +               dev_err(&bus->dev, "phy MDIO address write timeout\n");
82                 return -1;
83         }
84  
85 @@ -875,7 +873,7 @@ static int pfe_eth_mdio_write_addr(struc
86  static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
87                               u16 value)
88  {
89 -       struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
90 +       struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
91  
92         /*To access external PHYs on QDS board mux needs to be configured*/
93         if ((mii_id) && (pfe->mdio_muxval[mii_id]))
94 @@ -888,30 +886,26 @@ static int pfe_eth_mdio_write(struct mii
95                              EMAC_MII_DATA_PA(mii_id) |
96                              EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
97                              EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
98 -                            priv->PHY_baseaddr + EMAC_MII_DATA_REG);
99 +                            priv->mdio_base + EMAC_MII_DATA_REG);
100         } else {
101                 /* start a write op */
102                 __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
103                              EMAC_MII_DATA_PA(mii_id) |
104                              EMAC_MII_DATA_RA(regnum) |
105                              EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
106 -                            priv->PHY_baseaddr + EMAC_MII_DATA_REG);
107 +                            priv->mdio_base + EMAC_MII_DATA_REG);
108         }
109  
110 -       if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
111 -               netdev_err(priv->ndev, "%s: phy MDIO write timeout\n",
112 -                          __func__);
113 +       if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
114 +               dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__);
115                 return -1;
116         }
117 -       netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
118 -                  mii_id, regnum, value);
119 -
120         return 0;
121  }
122  
123  static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
124  {
125 -       struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
126 +       struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
127         u16 value = 0;
128  
129         /*To access external PHYs on QDS board mux needs to be configured*/
130 @@ -925,65 +919,67 @@ static int pfe_eth_mdio_read(struct mii_
131                              EMAC_MII_DATA_PA(mii_id) |
132                              EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
133                              EMAC_MII_DATA_TA,
134 -                            priv->PHY_baseaddr + EMAC_MII_DATA_REG);
135 +                            priv->mdio_base + EMAC_MII_DATA_REG);
136         } else {
137                 /* start a read op */
138                 __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
139                              EMAC_MII_DATA_PA(mii_id) |
140                              EMAC_MII_DATA_RA(regnum) |
141 -                            EMAC_MII_DATA_TA, priv->PHY_baseaddr +
142 +                            EMAC_MII_DATA_TA, priv->mdio_base +
143                              EMAC_MII_DATA_REG);
144         }
145  
146 -       if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
147 -               netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__);
148 +       if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
149 +               dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__);
150                 return -1;
151         }
152  
153 -       value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr +
154 +       value = EMAC_MII_DATA(__raw_readl(priv->mdio_base +
155                                                 EMAC_MII_DATA_REG));
156 -       netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
157 -                  mii_id, regnum, value);
158         return value;
159  }
160  
161 -static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
162 -                            struct ls1012a_mdio_platform_data *minfo)
163 +static int pfe_eth_mdio_init(struct pfe *pfe,
164 +                            struct ls1012a_pfe_platform_data *pfe_info,
165 +                            int ii)
166  {
167 +       struct pfe_mdio_priv_s *priv = NULL;
168 +       struct ls1012a_mdio_platform_data *mdio_info;
169         struct mii_bus *bus;
170         struct device_node *mdio_node;
171 -       int rc = 0, ii;
172 -       struct phy_device *phydev;
173 +       int rc = 0;
174  
175 -       netif_info(priv, drv, priv->ndev, "%s\n", __func__);
176 -       pr_info("%s\n", __func__);
177 +       mdio_info = (struct ls1012a_mdio_platform_data *)
178 +                                       pfe_info->ls1012a_mdio_pdata;
179 +       mdio_info->id = ii;
180  
181 -       bus = mdiobus_alloc();
182 +       bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s));
183         if (!bus) {
184 -               netdev_err(priv->ndev, "mdiobus_alloc() failed\n");
185 +               pr_err("mdiobus_alloc() failed\n");
186                 rc = -ENOMEM;
187 -               goto err0;
188 +               goto err_mdioalloc;
189         }
190  
191         bus->name = "ls1012a MDIO Bus";
192 -       snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id);
193 +       snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id);
194  
195 -       bus->priv = priv;
196         bus->read = &pfe_eth_mdio_read;
197         bus->write = &pfe_eth_mdio_write;
198         bus->reset = &pfe_eth_mdio_reset;
199 -       bus->parent = priv->pfe->dev;
200 -       bus->phy_mask = minfo->phy_mask;
201 -       bus->irq[0] = minfo->irq[0];
202 +       bus->parent = pfe->dev;
203 +       bus->phy_mask = mdio_info->phy_mask;
204 +       bus->irq[0] = mdio_info->irq[0];
205 +       priv = bus->priv;
206 +       priv->mdio_base = cbus_emac_base[ii];
207  
208 -       priv->mdc_div = minfo->mdc_div;
209 +       priv->mdc_div = mdio_info->mdc_div;
210         if (!priv->mdc_div)
211                 priv->mdc_div = 64;
212 -       netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n",
213 -                  __func__, priv->mdc_div, bus->phy_mask);
214 +               dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n",
215 +                        __func__, priv->mdc_div, bus->phy_mask);
216  
217 -       mdio_node = of_get_child_by_name(priv->pfe->dev->of_node, "mdio");
218 -       if (mdio_node) {
219 +       mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio");
220 +       if ((mdio_info->id == 0) && mdio_node) {
221                 rc = of_mdiobus_register(bus, mdio_node);
222                 of_node_put(mdio_node);
223         } else {
224 @@ -991,56 +987,34 @@ static int pfe_eth_mdio_init(struct pfe_
225         }
226  
227         if (rc) {
228 -               netdev_err(priv->ndev, "mdiobus_register(%s) failed\n",
229 -                          bus->name);
230 -               goto err1;
231 +               dev_err(bus->parent, "mdiobus_register(%s) failed\n",
232 +                       bus->name);
233 +               goto err_mdioregister;
234         }
235  
236         priv->mii_bus = bus;
237 -
238 -       /* For clause 45 we need to call get_phy_device() with it's
239 -        * 3rd argument as true and then register the phy device
240 -        * via phy_device_register()
241 -        */
242 -       if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
243 -               for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
244 -                       phydev = get_phy_device(priv->mii_bus,
245 -                                       priv->einfo->phy_id + ii, true);
246 -                       if (!phydev || IS_ERR(phydev)) {
247 -                               rc = -EIO;
248 -                               netdev_err(priv->ndev, "fail to get device\n");
249 -                               goto err1;
250 -                       }
251 -                       rc = phy_device_register(phydev);
252 -                       if (rc) {
253 -                               phy_device_free(phydev);
254 -                               netdev_err(priv->ndev,
255 -                                       "phy_device_register() failed\n");
256 -                               goto err1;
257 -                       }
258 -               }
259 -       }
260 +       pfe->mdio.mdio_priv[ii] = priv;
261  
262         pfe_eth_mdio_reset(bus);
263  
264         return 0;
265  
266 -err1:
267 +err_mdioregister:
268         mdiobus_free(bus);
269 -err0:
270 +err_mdioalloc:
271         return rc;
272  }
273  
274  /* pfe_eth_mdio_exit
275   */
276 -static void pfe_eth_mdio_exit(struct mii_bus *bus)
277 +static void pfe_eth_mdio_exit(struct pfe *pfe,
278 +                             int ii)
279  {
280 +       struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii];
281 +       struct mii_bus *bus = mdio_priv->mii_bus;
282 +
283         if (!bus)
284                 return;
285 -
286 -       netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct
287 -                       pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__);
288 -
289         mdiobus_unregister(bus);
290         mdiobus_free(bus);
291  }
292 @@ -1221,15 +1195,16 @@ static int pfe_eth_start(struct pfe_eth_
293   */
294  static void ls1012a_configure_serdes(struct net_device *ndev)
295  {
296 -       struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0];
297 +       struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev);
298 +       struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id];
299         int sgmii_2500 = 0;
300 -       struct mii_bus *bus = priv->mii_bus;
301 +       struct mii_bus *bus = mdio_priv->mii_bus;
302         u16 value = 0;
303  
304 -       if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
305 +       if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
306                 sgmii_2500 = 1;
307  
308 -       netif_info(priv, drv, ndev, "%s\n", __func__);
309 +       netif_info(eth_priv, drv, ndev, "%s\n", __func__);
310         /* PCS configuration done with corresponding GEMAC */
311  
312         pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR);
313 @@ -2333,26 +2308,15 @@ static const struct net_device_ops pfe_n
314  
315  /* pfe_eth_init_one
316   */
317 -static int pfe_eth_init_one(struct pfe *pfe, int id)
318 +static int pfe_eth_init_one(struct pfe *pfe,
319 +                           struct ls1012a_pfe_platform_data *pfe_info,
320 +                           int id)
321  {
322         struct net_device *ndev = NULL;
323         struct pfe_eth_priv_s *priv = NULL;
324         struct ls1012a_eth_platform_data *einfo;
325 -       struct ls1012a_mdio_platform_data *minfo;
326 -       struct ls1012a_pfe_platform_data *pfe_info;
327         int err;
328  
329 -       /* Extract pltform data */
330 -       pfe_info = (struct ls1012a_pfe_platform_data *)
331 -                                       pfe->dev->platform_data;
332 -       if (!pfe_info) {
333 -               pr_err(
334 -                       "%s: pfe missing additional platform data\n"
335 -                       , __func__);
336 -               err = -ENODEV;
337 -               goto err0;
338 -       }
339 -
340         einfo = (struct ls1012a_eth_platform_data *)
341                                 pfe_info->ls1012a_eth_pdata;
342  
343 @@ -2365,18 +2329,6 @@ static int pfe_eth_init_one(struct pfe *
344                 goto err0;
345         }
346  
347 -       minfo = (struct ls1012a_mdio_platform_data *)
348 -                               pfe_info->ls1012a_mdio_pdata;
349 -
350 -       /* einfo never be NULL, but no harm in having this check */
351 -       if (!minfo) {
352 -               pr_err(
353 -                       "%s: pfe missing additional mdios platform data\n",
354 -                        __func__);
355 -               err = -ENODEV;
356 -               goto err0;
357 -       }
358 -
359         if (us)
360                 emac_txq_cnt = EMAC_TXQ_CNT;
361         /* Create an ethernet device instance */
362 @@ -2402,7 +2354,6 @@ static int pfe_eth_init_one(struct pfe *
363         /* Set the info in the priv to the current info */
364         priv->einfo = &einfo[id];
365         priv->EMAC_baseaddr = cbus_emac_base[id];
366 -       priv->PHY_baseaddr = cbus_emac_base[0];
367         priv->GPI_baseaddr = cbus_gpi_base[id];
368  
369         spin_lock_init(&priv->lock);
370 @@ -2412,13 +2363,6 @@ static int pfe_eth_init_one(struct pfe *
371         /* Copy the station address into the dev structure, */
372         memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN);
373  
374 -       /* Initialize mdio */
375 -       err = pfe_eth_mdio_init(priv, &minfo[id]);
376 -       if (err) {
377 -               netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", __func__);
378 -               goto err1;
379 -       }
380 -
381         if (us)
382                 goto phy_init;
383  
384 @@ -2463,7 +2407,7 @@ static int pfe_eth_init_one(struct pfe *
385         err = register_netdev(ndev);
386         if (err) {
387                 netdev_err(ndev, "register_netdev() failed\n");
388 -               goto err2;
389 +               goto err1;
390         }
391  
392         if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
393 @@ -2480,7 +2424,7 @@ phy_init:
394         if (err) {
395                 netdev_err(ndev, "%s: pfe_phy_init() failed\n",
396                            __func__);
397 -               goto err3;
398 +               goto err2;
399         }
400  
401         if (us) {
402 @@ -2494,21 +2438,19 @@ phy_init:
403  skip_phy_init:
404         /* Create all the sysfs files */
405         if (pfe_eth_sysfs_init(ndev))
406 -               goto err4;
407 +               goto err3;
408  
409         netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n",
410                    __func__, priv->EMAC_baseaddr);
411  
412         return 0;
413  
414 -err4:
415 -       pfe_phy_exit(priv->ndev);
416  err3:
417 +       pfe_phy_exit(priv->ndev);
418 +err2:
419         if (us)
420 -               goto err2;
421 +               goto err1;
422         unregister_netdev(ndev);
423 -err2:
424 -       pfe_eth_mdio_exit(priv->mii_bus);
425  err1:
426         free_netdev(priv->ndev);
427  err0:
428 @@ -2521,6 +2463,7 @@ int pfe_eth_init(struct pfe *pfe)
429  {
430         int ii = 0;
431         int err;
432 +       struct ls1012a_pfe_platform_data *pfe_info;
433  
434         pr_info("%s\n", __func__);
435  
436 @@ -2530,24 +2473,43 @@ int pfe_eth_init(struct pfe *pfe)
437         cbus_gpi_base[0] = EGPI1_BASE_ADDR;
438         cbus_gpi_base[1] = EGPI2_BASE_ADDR;
439  
440 +       pfe_info = (struct ls1012a_pfe_platform_data *)
441 +                                       pfe->dev->platform_data;
442 +       if (!pfe_info) {
443 +               pr_err("%s: pfe missing additional platform data\n", __func__);
444 +               err = -ENODEV;
445 +               goto err_pdata;
446 +       }
447 +
448 +       for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
449 +               err = pfe_eth_mdio_init(pfe, pfe_info, ii);
450 +               if (err) {
451 +                       pr_err("%s: pfe_eth_mdio_init() failed\n", __func__);
452 +                       goto err_mdio_init;
453 +               }
454 +       }
455 +
456         if (fsl_guts_get_svr() == LS1012A_REV_1_0)
457                 pfe_errata_a010897 = true;
458         else
459                 pfe_errata_a010897 = false;
460  
461         for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
462 -               err = pfe_eth_init_one(pfe, ii);
463 +               err = pfe_eth_init_one(pfe, pfe_info, ii);
464                 if (err)
465 -                       goto err0;
466 +                       goto err_eth_init;
467         }
468  
469         return 0;
470  
471 -err0:
472 -       while (ii--)
473 +err_eth_init:
474 +       while (ii--) {
475                 pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
476 +               pfe_eth_mdio_exit(pfe, ii);
477 +       }
478  
479 -       /* Register three network devices in the kernel */
480 +err_mdio_init:
481 +err_pdata:
482         return err;
483  }
484  
485 @@ -2573,9 +2535,6 @@ skip_phy_exit:
486         if (!us)
487                 unregister_netdev(priv->ndev);
488  
489 -       if (priv->mii_bus)
490 -               pfe_eth_mdio_exit(priv->mii_bus);
491 -
492         free_netdev(priv->ndev);
493  }
494  
495 @@ -2589,4 +2548,7 @@ void pfe_eth_exit(struct pfe *pfe)
496  
497         for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
498                 pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
499 +
500 +       for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
501 +               pfe_eth_mdio_exit(pfe, ii);
502  }
503 --- a/drivers/staging/fsl_ppfe/pfe_eth.h
504 +++ b/drivers/staging/fsl_ppfe/pfe_eth.h
505 @@ -48,7 +48,7 @@ struct ls1012a_eth_platform_data {
506  };
507  
508  struct ls1012a_mdio_platform_data {
509 -       int enabled;
510 +       int id;
511         int irq[32];
512         u32 phy_mask;
513         int mdc_div;
514 @@ -120,8 +120,6 @@ struct  pfe_eth_priv_s {
515         unsigned int            event_status;
516         int                     irq;
517         void                    *EMAC_baseaddr;
518 -       /* This points to the EMAC base from where we access PHY */
519 -       void                    *PHY_baseaddr;
520         void                    *GPI_baseaddr;
521         /* PHY stuff */
522         struct phy_device       *phydev;
523 @@ -129,9 +127,6 @@ struct  pfe_eth_priv_s {
524         int                     oldduplex;
525         int                     oldlink;
526         struct device_node      *phy_node;
527 -       /* mdio info */
528 -       int                     mdc_div;
529 -       struct mii_bus          *mii_bus;
530         struct clk              *gemtx_clk;
531         int                     wol;
532         int                     pause_flag;
533 @@ -161,6 +156,16 @@ struct pfe_eth {
534         struct pfe_eth_priv_s *eth_priv[3];
535  };
536  
537 +struct pfe_mdio_priv_s {
538 +       void __iomem *mdio_base;
539 +       int                     mdc_div;
540 +       struct mii_bus          *mii_bus;
541 +};
542 +
543 +struct pfe_mdio {
544 +       struct pfe_mdio_priv_s *mdio_priv[3];
545 +};
546 +
547  int pfe_eth_init(struct pfe *pfe);
548  void pfe_eth_exit(struct pfe *pfe);
549  int pfe_eth_suspend(struct net_device *dev);
550 --- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
551 +++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
552 @@ -21,31 +21,18 @@
553  extern bool pfe_use_old_dts_phy;
554  struct ls1012a_pfe_platform_data pfe_platform_data;
555  
556 -static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int
557 -                                       if_cnt,
558 -                                       struct ls1012a_pfe_platform_data
559 -                                       *pdata)
560 +static int pfe_get_gemac_if_properties(struct device_node *gem,
561 +                                      int port,
562 +                                      struct ls1012a_pfe_platform_data *pdata)
563  {
564 -       struct device_node *gem = NULL, *phy = NULL, *phy_node = NULL;
565 +       struct device_node *phy_node = NULL;
566         int size;
567 -       int ii = 0, phy_id = 0;
568 +       int phy_id = 0;
569         const u32 *addr;
570         const void *mac_addr;
571  
572 -       for (ii = 0; ii < if_cnt; ii++) {
573 -               gem = of_get_next_child(parent, gem);
574 -               if (!gem)
575 -                       goto err;
576 -               addr = of_get_property(gem, "reg", &size);
577 -               if (addr && (be32_to_cpup(addr) == port))
578 -                       break;
579 -       }
580 -
581 -       if (ii >= if_cnt) {
582 -               pr_err("%s:%d Failed to find interface = %d\n",
583 -                      __func__, __LINE__, if_cnt);
584 -               goto err;
585 -       }
586 +       addr = of_get_property(gem, "reg", &size);
587 +       port = be32_to_cpup(addr);
588  
589         pdata->ls1012a_eth_pdata[port].gem_id = port;
590  
591 @@ -88,14 +75,6 @@ static int pfe_get_gemac_if_properties(s
592                 if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
593                         goto done;
594  
595 -               phy = of_get_next_child(gem, NULL);
596 -               addr = of_get_property(phy, "reg", &size);
597 -               if (!addr)
598 -                       pr_err("%s:%d Invalid phy enable flag....\n",
599 -                              __func__, __LINE__);
600 -               else
601 -                       pdata->ls1012a_mdio_pdata[port].enabled =
602 -                                                       be32_to_cpup(addr);
603         } else {
604                 pr_info("%s: No PHY or fixed-link\n", __func__);
605                 return 0;
606 @@ -140,7 +119,7 @@ static int pfe_platform_probe(struct pla
607         struct resource res;
608         int ii, rc, interface_count = 0, size = 0;
609         const u32 *prop;
610 -       struct device_node  *np;
611 +       struct device_node *np, *gem = NULL;
612         struct clk *pfe_clk;
613  
614         np = pdev->dev.of_node;
615 @@ -224,8 +203,13 @@ static int pfe_platform_probe(struct pla
616         pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
617  
618         for (ii = 0; ii < interface_count; ii++) {
619 -               pfe_get_gemac_if_properties(np, ii, interface_count,
620 -                                           &pfe_platform_data);
621 +               gem = of_get_next_child(np, gem);
622 +               if (gem)
623 +                       pfe_get_gemac_if_properties(gem, ii,
624 +                                                   &pfe_platform_data);
625 +               else
626 +                       pr_err("Unable to find interface %d\n", ii);
627 +
628         }
629  
630         pfe->dev = &pdev->dev;
631 @@ -347,8 +331,8 @@ static int pfe_platform_resume(struct de
632         for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
633                 netdev = pfe->eth.eth_priv[i]->ndev;
634  
635 -               if (pfe->eth.eth_priv[i]->mii_bus)
636 -                       pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus);
637 +               if (pfe->mdio.mdio_priv[i]->mii_bus)
638 +                       pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus);
639  
640                 if (netif_running(netdev))
641                         pfe_eth_resume(netdev);
642 --- a/drivers/staging/fsl_ppfe/pfe_mod.h
643 +++ b/drivers/staging/fsl_ppfe/pfe_mod.h
644 @@ -52,6 +52,7 @@ struct pfe {
645         struct pfe_ctrl ctrl;
646         struct pfe_hif hif;
647         struct pfe_eth eth;
648 +       struct pfe_mdio mdio;
649         struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
650  #if defined(CFG_DIAGS)
651         struct pfe_diags diags;