diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/fec.c')
-rw-r--r-- | drivers/net/ethernet/freescale/fec.c | 28 |
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) | |||
1506 | static void __devinit fec_reset_phy(struct platform_device *pdev) | 1507 | static 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); |
1656 | failed_mii_init: | 1675 | failed_mii_init: |
1657 | failed_init: | 1676 | failed_init: |
1677 | failed_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); |
1660 | failed_pin: | 1680 | failed_pin: |