aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2014-08-11 11:35:33 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-11 17:41:06 -0400
commit407066f8f3716ca2880a08c48dbab507ae2ec8d9 (patch)
tree4465c0cb2fad695b086f41db1b211fd939bc79aa
parent200d7db76e589823c9dcbf6b88aee48cf2aaf195 (diff)
net: fec: Support phys probed from devicetree and fixed-link
This adds support for specifying the phy to be used with the fec in the devicetree using the standard phy-handle property and also supports fixed-link. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/fsl-fec.txt29
-rw-r--r--drivers/net/ethernet/freescale/fec.h1
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c76
3 files changed, 84 insertions, 22 deletions
diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
index 6bc84adb10c0..8a2c7b55ec16 100644
--- a/Documentation/devicetree/bindings/net/fsl-fec.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
@@ -12,7 +12,14 @@ Optional properties:
12 only if property "phy-reset-gpios" is available. Missing the property 12 only if property "phy-reset-gpios" is available. Missing the property
13 will have the duration be 1 millisecond. Numbers greater than 1000 are 13 will have the duration be 1 millisecond. Numbers greater than 1000 are
14 invalid and 1 millisecond will be used instead. 14 invalid and 1 millisecond will be used instead.
15- phy-supply: regulator that powers the Ethernet PHY. 15- phy-supply : regulator that powers the Ethernet PHY.
16- phy-handle : phandle to the PHY device connected to this device.
17- fixed-link : Assume a fixed link. See fixed-link.txt in the same directory.
18 Use instead of phy-handle.
19
20Optional subnodes:
21- mdio : specifies the mdio bus in the FEC, used as a container for phy nodes
22 according to phy.txt in the same directory
16 23
17Example: 24Example:
18 25
@@ -25,3 +32,23 @@ ethernet@83fec000 {
25 local-mac-address = [00 04 9F 01 1B B9]; 32 local-mac-address = [00 04 9F 01 1B B9];
26 phy-supply = <&reg_fec_supply>; 33 phy-supply = <&reg_fec_supply>;
27}; 34};
35
36Example with phy specified:
37
38ethernet@83fec000 {
39 compatible = "fsl,imx51-fec", "fsl,imx27-fec";
40 reg = <0x83fec000 0x4000>;
41 interrupts = <87>;
42 phy-mode = "mii";
43 phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
44 local-mac-address = [00 04 9F 01 1B B9];
45 phy-supply = <&reg_fec_supply>;
46 phy-handle = <&ethphy>;
47 mdio {
48 ethphy: ethernet-phy@6 {
49 compatible = "ethernet-phy-ieee802.3-c22";
50 reg = <6>;
51 max-speed = <100>;
52 };
53 };
54};
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index bd53caf1c1eb..9f7fa644a397 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -310,6 +310,7 @@ struct fec_enet_private {
310 int mii_timeout; 310 int mii_timeout;
311 uint phy_speed; 311 uint phy_speed;
312 phy_interface_t phy_interface; 312 phy_interface_t phy_interface;
313 struct device_node *phy_node;
313 int link; 314 int link;
314 int full_duplex; 315 int full_duplex;
315 int speed; 316 int speed;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 66fe1f672499..4f87dffcb9b2 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -52,6 +52,7 @@
52#include <linux/of.h> 52#include <linux/of.h>
53#include <linux/of_device.h> 53#include <linux/of_device.h>
54#include <linux/of_gpio.h> 54#include <linux/of_gpio.h>
55#include <linux/of_mdio.h>
55#include <linux/of_net.h> 56#include <linux/of_net.h>
56#include <linux/regulator/consumer.h> 57#include <linux/regulator/consumer.h>
57#include <linux/if_vlan.h> 58#include <linux/if_vlan.h>
@@ -1648,29 +1649,37 @@ static int fec_enet_mii_probe(struct net_device *ndev)
1648 1649
1649 fep->phy_dev = NULL; 1650 fep->phy_dev = NULL;
1650 1651
1651 /* check for attached phy */ 1652 if (fep->phy_node) {
1652 for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) { 1653 phy_dev = of_phy_connect(ndev, fep->phy_node,
1653 if ((fep->mii_bus->phy_mask & (1 << phy_id))) 1654 &fec_enet_adjust_link, 0,
1654 continue; 1655 fep->phy_interface);
1655 if (fep->mii_bus->phy_map[phy_id] == NULL) 1656 } else {
1656 continue; 1657 /* check for attached phy */
1657 if (fep->mii_bus->phy_map[phy_id]->phy_id == 0) 1658 for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
1658 continue; 1659 if ((fep->mii_bus->phy_mask & (1 << phy_id)))
1659 if (dev_id--) 1660 continue;
1660 continue; 1661 if (fep->mii_bus->phy_map[phy_id] == NULL)
1661 strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); 1662 continue;
1662 break; 1663 if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
1663 } 1664 continue;
1665 if (dev_id--)
1666 continue;
1667 strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
1668 break;
1669 }
1664 1670
1665 if (phy_id >= PHY_MAX_ADDR) { 1671 if (phy_id >= PHY_MAX_ADDR) {
1666 netdev_info(ndev, "no PHY, assuming direct connection to switch\n"); 1672 netdev_info(ndev, "no PHY, assuming direct connection to switch\n");
1667 strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); 1673 strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE);
1668 phy_id = 0; 1674 phy_id = 0;
1675 }
1676
1677 snprintf(phy_name, sizeof(phy_name),
1678 PHY_ID_FMT, mdio_bus_id, phy_id);
1679 phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link,
1680 fep->phy_interface);
1669 } 1681 }
1670 1682
1671 snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
1672 phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link,
1673 fep->phy_interface);
1674 if (IS_ERR(phy_dev)) { 1683 if (IS_ERR(phy_dev)) {
1675 netdev_err(ndev, "could not attach to PHY\n"); 1684 netdev_err(ndev, "could not attach to PHY\n");
1676 return PTR_ERR(phy_dev); 1685 return PTR_ERR(phy_dev);
@@ -1707,6 +1716,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
1707 struct fec_enet_private *fep = netdev_priv(ndev); 1716 struct fec_enet_private *fep = netdev_priv(ndev);
1708 const struct platform_device_id *id_entry = 1717 const struct platform_device_id *id_entry =
1709 platform_get_device_id(fep->pdev); 1718 platform_get_device_id(fep->pdev);
1719 struct device_node *node;
1710 int err = -ENXIO, i; 1720 int err = -ENXIO, i;
1711 1721
1712 /* 1722 /*
@@ -1774,7 +1784,15 @@ static int fec_enet_mii_init(struct platform_device *pdev)
1774 for (i = 0; i < PHY_MAX_ADDR; i++) 1784 for (i = 0; i < PHY_MAX_ADDR; i++)
1775 fep->mii_bus->irq[i] = PHY_POLL; 1785 fep->mii_bus->irq[i] = PHY_POLL;
1776 1786
1777 if (mdiobus_register(fep->mii_bus)) 1787 node = of_get_child_by_name(pdev->dev.of_node, "mdio");
1788 if (node) {
1789 err = of_mdiobus_register(fep->mii_bus, node);
1790 of_node_put(node);
1791 } else {
1792 err = mdiobus_register(fep->mii_bus);
1793 }
1794
1795 if (err)
1778 goto err_out_free_mdio_irq; 1796 goto err_out_free_mdio_irq;
1779 1797
1780 mii_cnt++; 1798 mii_cnt++;
@@ -2527,6 +2545,7 @@ fec_probe(struct platform_device *pdev)
2527 struct resource *r; 2545 struct resource *r;
2528 const struct of_device_id *of_id; 2546 const struct of_device_id *of_id;
2529 static int dev_id; 2547 static int dev_id;
2548 struct device_node *np = pdev->dev.of_node, *phy_node;
2530 2549
2531 of_id = of_match_device(fec_dt_ids, &pdev->dev); 2550 of_id = of_match_device(fec_dt_ids, &pdev->dev);
2532 if (of_id) 2551 if (of_id)
@@ -2566,6 +2585,18 @@ fec_probe(struct platform_device *pdev)
2566 2585
2567 platform_set_drvdata(pdev, ndev); 2586 platform_set_drvdata(pdev, ndev);
2568 2587
2588 phy_node = of_parse_phandle(np, "phy-handle", 0);
2589 if (!phy_node && of_phy_is_fixed_link(np)) {
2590 ret = of_phy_register_fixed_link(np);
2591 if (ret < 0) {
2592 dev_err(&pdev->dev,
2593 "broken fixed-link specification\n");
2594 goto failed_phy;
2595 }
2596 phy_node = of_node_get(np);
2597 }
2598 fep->phy_node = phy_node;
2599
2569 ret = of_get_phy_mode(pdev->dev.of_node); 2600 ret = of_get_phy_mode(pdev->dev.of_node);
2570 if (ret < 0) { 2601 if (ret < 0) {
2571 pdata = dev_get_platdata(&pdev->dev); 2602 pdata = dev_get_platdata(&pdev->dev);
@@ -2670,6 +2701,8 @@ failed_init:
2670failed_regulator: 2701failed_regulator:
2671 fec_enet_clk_enable(ndev, false); 2702 fec_enet_clk_enable(ndev, false);
2672failed_clk: 2703failed_clk:
2704failed_phy:
2705 of_node_put(phy_node);
2673failed_ioremap: 2706failed_ioremap:
2674 free_netdev(ndev); 2707 free_netdev(ndev);
2675 2708
@@ -2691,6 +2724,7 @@ fec_drv_remove(struct platform_device *pdev)
2691 if (fep->ptp_clock) 2724 if (fep->ptp_clock)
2692 ptp_clock_unregister(fep->ptp_clock); 2725 ptp_clock_unregister(fep->ptp_clock);
2693 fec_enet_clk_enable(ndev, false); 2726 fec_enet_clk_enable(ndev, false);
2727 of_node_put(fep->phy_node);
2694 free_netdev(ndev); 2728 free_netdev(ndev);
2695 2729
2696 return 0; 2730 return 0;