diff options
author | Luwei Zhou <b45643@freescale.com> | 2014-02-21 03:08:44 -0500 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:57:40 -0400 |
commit | 6b51e7cc7a70aab1def2b7872e5bf8d005179919 (patch) | |
tree | e8e9acf25df55f13a6d1769fb1ba795cddc19cd5 /drivers | |
parent | e68b52c759f6f82bfc03e76aa9f00881facc89e8 (diff) |
ENGR00299593-4 net:fec: return -EPROBE_DEFER when phy regulator isn't initialized
On i.mx6sx-17x17-arm2 board, fec needs to supply phy via max7322 extention gpio.
When fec probe, the phy regulator doesn't complete initilization. The fec_probe
needs to return -EPROBE_DEFER and kernel will retry fec_probe after a delay.
Signed-off-by: Luwei Zhou <b45643@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index cb3e5fec4897..e71e5cf1838c 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -2582,6 +2582,7 @@ fec_probe(struct platform_device *pdev) | |||
2582 | static int dev_id; | 2582 | static int dev_id; |
2583 | int num_tx_qs = 1; | 2583 | int num_tx_qs = 1; |
2584 | int num_rx_qs = 1; | 2584 | int num_rx_qs = 1; |
2585 | struct regulator *phy_reg = NULL; | ||
2585 | 2586 | ||
2586 | of_id = of_match_device(fec_dt_ids, &pdev->dev); | 2587 | of_id = of_match_device(fec_dt_ids, &pdev->dev); |
2587 | if (of_id) | 2588 | if (of_id) |
@@ -2591,6 +2592,26 @@ fec_probe(struct platform_device *pdev) | |||
2591 | if (!r) | 2592 | if (!r) |
2592 | return -ENXIO; | 2593 | return -ENXIO; |
2593 | 2594 | ||
2595 | phy_reg = devm_regulator_get(&pdev->dev, "phy"); | ||
2596 | |||
2597 | if (!IS_ERR(phy_reg)) { | ||
2598 | ret = regulator_enable(phy_reg); | ||
2599 | if (ret) { | ||
2600 | dev_err(&pdev->dev, | ||
2601 | "Failed to enable phy regulator: %d\n", ret); | ||
2602 | return ret; | ||
2603 | } | ||
2604 | } else if (phy_reg == ERR_PTR(-EPROBE_DEFER)) { | ||
2605 | /* Return -EPROBE_DEFER when the regulator is not | ||
2606 | * sufficient initialized. When -EPROBE_DEFER is | ||
2607 | * returned in fec_probe, the kernel will retry | ||
2608 | * fec_probe after suitalbe delay. | ||
2609 | */ | ||
2610 | return -EPROBE_DEFER; | ||
2611 | } else { | ||
2612 | phy_reg = NULL; | ||
2613 | } | ||
2614 | |||
2594 | if (pdev->id_entry && | 2615 | if (pdev->id_entry && |
2595 | (pdev->id_entry->driver_data & FEC_QUIRK_HAS_AVB)) { | 2616 | (pdev->id_entry->driver_data & FEC_QUIRK_HAS_AVB)) { |
2596 | ret = fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); | 2617 | ret = fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); |
@@ -2608,6 +2629,7 @@ fec_probe(struct platform_device *pdev) | |||
2608 | /* setup board info structure */ | 2629 | /* setup board info structure */ |
2609 | fep = netdev_priv(ndev); | 2630 | fep = netdev_priv(ndev); |
2610 | 2631 | ||
2632 | fep->reg_phy = phy_reg; | ||
2611 | fep->num_rx_queues = num_rx_qs; | 2633 | fep->num_rx_queues = num_rx_qs; |
2612 | fep->num_tx_queues = num_tx_qs; | 2634 | fep->num_tx_queues = num_tx_qs; |
2613 | netif_set_real_num_rx_queues(ndev, num_rx_qs); | 2635 | netif_set_real_num_rx_queues(ndev, num_rx_qs); |
@@ -2681,18 +2703,6 @@ fec_probe(struct platform_device *pdev) | |||
2681 | 2703 | ||
2682 | fec_enet_clk_enable(ndev, true); | 2704 | fec_enet_clk_enable(ndev, true); |
2683 | 2705 | ||
2684 | fep->reg_phy = devm_regulator_get(&pdev->dev, "phy"); | ||
2685 | if (!IS_ERR(fep->reg_phy)) { | ||
2686 | ret = regulator_enable(fep->reg_phy); | ||
2687 | if (ret) { | ||
2688 | dev_err(&pdev->dev, | ||
2689 | "Failed to enable phy regulator: %d\n", ret); | ||
2690 | goto failed_regulator; | ||
2691 | } | ||
2692 | } else { | ||
2693 | fep->reg_phy = NULL; | ||
2694 | } | ||
2695 | |||
2696 | if (fep->bufdesc_ex) | 2706 | if (fep->bufdesc_ex) |
2697 | fec_ptp_init(pdev); | 2707 | fec_ptp_init(pdev); |
2698 | 2708 | ||
@@ -2750,13 +2760,12 @@ failed_irq: | |||
2750 | free_irq(irq, ndev); | 2760 | free_irq(irq, ndev); |
2751 | } | 2761 | } |
2752 | failed_init: | 2762 | failed_init: |
2753 | if (fep->reg_phy) | ||
2754 | regulator_disable(fep->reg_phy); | ||
2755 | failed_regulator: | ||
2756 | fec_enet_clk_enable(ndev, false); | 2763 | fec_enet_clk_enable(ndev, false); |
2757 | failed_clk: | 2764 | failed_clk: |
2758 | failed_ioremap: | 2765 | failed_ioremap: |
2759 | free_netdev(ndev); | 2766 | free_netdev(ndev); |
2767 | if (fep->reg_phy) | ||
2768 | regulator_disable(fep->reg_phy); | ||
2760 | 2769 | ||
2761 | return ret; | 2770 | return ret; |
2762 | } | 2771 | } |