Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 407066f8 authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by David S. Miller
Browse files

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: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 200d7db7
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -13,6 +13,13 @@ Optional properties:
  will have the duration be 1 millisecond.  Numbers greater than 1000 are
  invalid and 1 millisecond will be used instead.
- phy-supply : regulator that powers the Ethernet PHY.
- phy-handle : phandle to the PHY device connected to this device.
- fixed-link : Assume a fixed link. See fixed-link.txt in the same directory.
  Use instead of phy-handle.

Optional subnodes:
- mdio : specifies the mdio bus in the FEC, used as a container for phy nodes
  according to phy.txt in the same directory

Example:

@@ -25,3 +32,23 @@ ethernet@83fec000 {
	local-mac-address = [00 04 9F 01 1B B9];
	phy-supply = <&reg_fec_supply>;
};

Example with phy specified:

ethernet@83fec000 {
	compatible = "fsl,imx51-fec", "fsl,imx27-fec";
	reg = <0x83fec000 0x4000>;
	interrupts = <87>;
	phy-mode = "mii";
	phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
	local-mac-address = [00 04 9F 01 1B B9];
	phy-supply = <&reg_fec_supply>;
	phy-handle = <&ethphy>;
	mdio {
		ethphy: ethernet-phy@6 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <6>;
			max-speed = <100>;
		};
	};
};
+1 −0
Original line number Diff line number Diff line
@@ -310,6 +310,7 @@ struct fec_enet_private {
	int	mii_timeout;
	uint	phy_speed;
	phy_interface_t	phy_interface;
	struct device_node *phy_node;
	int	link;
	int	full_duplex;
	int	speed;
+55 −21
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/regulator/consumer.h>
#include <linux/if_vlan.h>
@@ -1648,6 +1649,11 @@ static int fec_enet_mii_probe(struct net_device *ndev)

	fep->phy_dev = NULL;

	if (fep->phy_node) {
		phy_dev = of_phy_connect(ndev, fep->phy_node,
					 &fec_enet_adjust_link, 0,
					 fep->phy_interface);
	} else {
		/* check for attached phy */
		for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
			if ((fep->mii_bus->phy_mask & (1 << phy_id)))
@@ -1668,9 +1674,12 @@ static int fec_enet_mii_probe(struct net_device *ndev)
			phy_id = 0;
		}

	snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
		snprintf(phy_name, sizeof(phy_name),
			 PHY_ID_FMT, mdio_bus_id, phy_id);
		phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link,
				      fep->phy_interface);
	}

	if (IS_ERR(phy_dev)) {
		netdev_err(ndev, "could not attach to PHY\n");
		return PTR_ERR(phy_dev);
@@ -1707,6 +1716,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
	struct fec_enet_private *fep = netdev_priv(ndev);
	const struct platform_device_id *id_entry =
				platform_get_device_id(fep->pdev);
	struct device_node *node;
	int err = -ENXIO, i;

	/*
@@ -1774,7 +1784,15 @@ static int fec_enet_mii_init(struct platform_device *pdev)
	for (i = 0; i < PHY_MAX_ADDR; i++)
		fep->mii_bus->irq[i] = PHY_POLL;

	if (mdiobus_register(fep->mii_bus))
	node = of_get_child_by_name(pdev->dev.of_node, "mdio");
	if (node) {
		err = of_mdiobus_register(fep->mii_bus, node);
		of_node_put(node);
	} else {
		err = mdiobus_register(fep->mii_bus);
	}

	if (err)
		goto err_out_free_mdio_irq;

	mii_cnt++;
@@ -2527,6 +2545,7 @@ fec_probe(struct platform_device *pdev)
	struct resource *r;
	const struct of_device_id *of_id;
	static int dev_id;
	struct device_node *np = pdev->dev.of_node, *phy_node;

	of_id = of_match_device(fec_dt_ids, &pdev->dev);
	if (of_id)
@@ -2566,6 +2585,18 @@ fec_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, ndev);

	phy_node = of_parse_phandle(np, "phy-handle", 0);
	if (!phy_node && of_phy_is_fixed_link(np)) {
		ret = of_phy_register_fixed_link(np);
		if (ret < 0) {
			dev_err(&pdev->dev,
				"broken fixed-link specification\n");
			goto failed_phy;
		}
		phy_node = of_node_get(np);
	}
	fep->phy_node = phy_node;

	ret = of_get_phy_mode(pdev->dev.of_node);
	if (ret < 0) {
		pdata = dev_get_platdata(&pdev->dev);
@@ -2670,6 +2701,8 @@ fec_probe(struct platform_device *pdev)
failed_regulator:
	fec_enet_clk_enable(ndev, false);
failed_clk:
failed_phy:
	of_node_put(phy_node);
failed_ioremap:
	free_netdev(ndev);

@@ -2691,6 +2724,7 @@ fec_drv_remove(struct platform_device *pdev)
	if (fep->ptp_clock)
		ptp_clock_unregister(fep->ptp_clock);
	fec_enet_clk_enable(ndev, false);
	of_node_put(fep->phy_node);
	free_netdev(ndev);

	return 0;