aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale/fec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/fec.c')
-rw-r--r--drivers/net/ethernet/freescale/fec.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index ff7f4c5115a1..dafd797a6069 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -49,6 +49,7 @@
49#include <linux/of_gpio.h> 49#include <linux/of_gpio.h>
50#include <linux/of_net.h> 50#include <linux/of_net.h>
51#include <linux/pinctrl/consumer.h> 51#include <linux/pinctrl/consumer.h>
52#include <linux/regulator/consumer.h>
52 53
53#include <asm/cacheflush.h> 54#include <asm/cacheflush.h>
54 55
@@ -1506,18 +1507,25 @@ static int __devinit fec_get_phy_mode_dt(struct platform_device *pdev)
1506static void __devinit fec_reset_phy(struct platform_device *pdev) 1507static void __devinit fec_reset_phy(struct platform_device *pdev)
1507{ 1508{
1508 int err, phy_reset; 1509 int err, phy_reset;
1510 int msec = 1;
1509 struct device_node *np = pdev->dev.of_node; 1511 struct device_node *np = pdev->dev.of_node;
1510 1512
1511 if (!np) 1513 if (!np)
1512 return; 1514 return;
1513 1515
1516 of_property_read_u32(np, "phy-reset-duration", &msec);
1517 /* A sane reset duration should not be longer than 1s */
1518 if (msec > 1000)
1519 msec = 1;
1520
1514 phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); 1521 phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
1515 err = gpio_request_one(phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset"); 1522 err = devm_gpio_request_one(&pdev->dev, phy_reset,
1523 GPIOF_OUT_INIT_LOW, "phy-reset");
1516 if (err) { 1524 if (err) {
1517 pr_debug("FEC: failed to get gpio phy-reset: %d\n", err); 1525 pr_debug("FEC: failed to get gpio phy-reset: %d\n", err);
1518 return; 1526 return;
1519 } 1527 }
1520 msleep(1); 1528 msleep(msec);
1521 gpio_set_value(phy_reset, 1); 1529 gpio_set_value(phy_reset, 1);
1522} 1530}
1523#else /* CONFIG_OF */ 1531#else /* CONFIG_OF */
@@ -1546,6 +1554,7 @@ fec_probe(struct platform_device *pdev)
1546 const struct of_device_id *of_id; 1554 const struct of_device_id *of_id;
1547 static int dev_id; 1555 static int dev_id;
1548 struct pinctrl *pinctrl; 1556 struct pinctrl *pinctrl;
1557 struct regulator *reg_phy;
1549 1558
1550 of_id = of_match_device(fec_dt_ids, &pdev->dev); 1559 of_id = of_match_device(fec_dt_ids, &pdev->dev);
1551 if (of_id) 1560 if (of_id)
@@ -1593,8 +1602,6 @@ fec_probe(struct platform_device *pdev)
1593 fep->phy_interface = ret; 1602 fep->phy_interface = ret;
1594 } 1603 }
1595 1604
1596 fec_reset_phy(pdev);
1597
1598 for (i = 0; i < FEC_IRQ_NUM; i++) { 1605 for (i = 0; i < FEC_IRQ_NUM; i++) {
1599 irq = platform_get_irq(pdev, i); 1606 irq = platform_get_irq(pdev, i);
1600 if (irq < 0) { 1607 if (irq < 0) {
@@ -1634,6 +1641,18 @@ fec_probe(struct platform_device *pdev)
1634 clk_prepare_enable(fep->clk_ahb); 1641 clk_prepare_enable(fep->clk_ahb);
1635 clk_prepare_enable(fep->clk_ipg); 1642 clk_prepare_enable(fep->clk_ipg);
1636 1643
1644 reg_phy = devm_regulator_get(&pdev->dev, "phy");
1645 if (!IS_ERR(reg_phy)) {
1646 ret = regulator_enable(reg_phy);
1647 if (ret) {
1648 dev_err(&pdev->dev,
1649 "Failed to enable phy regulator: %d\n", ret);
1650 goto failed_regulator;
1651 }
1652 }
1653
1654 fec_reset_phy(pdev);
1655
1637 ret = fec_enet_init(ndev); 1656 ret = fec_enet_init(ndev);
1638 if (ret) 1657 if (ret)
1639 goto failed_init; 1658 goto failed_init;
@@ -1655,6 +1674,7 @@ failed_register:
1655 fec_enet_mii_remove(fep); 1674 fec_enet_mii_remove(fep);
1656failed_mii_init: 1675failed_mii_init:
1657failed_init: 1676failed_init:
1677failed_regulator:
1658 clk_disable_unprepare(fep->clk_ahb); 1678 clk_disable_unprepare(fep->clk_ahb);
1659 clk_disable_unprepare(fep->clk_ipg); 1679 clk_disable_unprepare(fep->clk_ipg);
1660failed_pin: 1680failed_pin: