From patchwork Fri Feb 1 07:52:10 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hauer X-Patchwork-Id: 2077311 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 1997940106 for ; Fri, 1 Feb 2013 07:55:18 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1U1BQT-0005nX-CU; Fri, 01 Feb 2013 07:52:45 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1U1BQO-0005jW-Fd for linux-arm-kernel@lists.infradead.org; Fri, 01 Feb 2013 07:52:41 +0000 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1U1BQI-0001Ow-Vk; Fri, 01 Feb 2013 08:52:35 +0100 Received: from sha by dude.hi.pengutronix.de with local (Exim 4.80) (envelope-from ) id 1U1BQI-0002U1-BD; Fri, 01 Feb 2013 08:52:34 +0100 From: Sascha Hauer To: linux-usb@vger.kernel.org Subject: [PATCH 7/9] como fec wip Date: Fri, 1 Feb 2013 08:52:10 +0100 Message-Id: <1359705132-9434-8-git-send-email-s.hauer@pengutronix.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1359705132-9434-1-git-send-email-s.hauer@pengutronix.de> References: <1359705132-9434-1-git-send-email-s.hauer@pengutronix.de> X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: sha@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130201_025240_881800_086C72BE X-CRM114-Status: GOOD ( 23.70 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: alexander.shishkin@linux.intel.com, Greg KH , Sascha Hauer , Matthieu CASTET , kishon , Peter Chen , kernel@pengutronix.de, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Signed-off-by: Sascha Hauer --- Documentation/devicetree/bindings/net/fsl-fec.txt | 20 ++++++ drivers/net/ethernet/freescale/fec.c | 77 ++++++++++++--------- drivers/net/ethernet/freescale/fec.h | 1 + 3 files changed, 67 insertions(+), 31 deletions(-) diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt index d536392..ec7060b 100644 --- a/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -15,6 +15,9 @@ Optional properties: only if property "phy-reset-gpios" is available. Missing the property will have the duration be 1 millisecond. Numbers greater than 1000 are invalid and 1 millisecond will be used instead. +- phy : a phandle for the PHY device used for the fec. Used to specify an + external phy or to specify a particular address if the mdio bus has multiple + phys on it. Example: @@ -26,3 +29,20 @@ ethernet@83fec000 { phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */ local-mac-address = [00 04 9F 01 1B B9]; }; + +Example with specific phy address: + +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 = &phy3; + + phy3: ethernet-phy@3 { + reg = <3>; + device_type = "ethernet-phy"; + }; +}; diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 0704bca..54a8506 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -950,31 +951,38 @@ static int fec_enet_mii_probe(struct net_device *ndev) fep->phy_dev = NULL; - /* check for attached phy */ - for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) { - if ((fep->mii_bus->phy_mask & (1 << phy_id))) - continue; - if (fep->mii_bus->phy_map[phy_id] == NULL) - continue; - if (fep->mii_bus->phy_map[phy_id]->phy_id == 0) - continue; - if (dev_id--) - continue; - strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); - break; - } + 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))) + continue; + if (fep->mii_bus->phy_map[phy_id] == NULL) + continue; + if (fep->mii_bus->phy_map[phy_id]->phy_id == 0) + continue; + if (dev_id--) + continue; + strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); + break; + } - if (phy_id >= PHY_MAX_ADDR) { - printk(KERN_INFO - "%s: no PHY, assuming direct connection to switch\n", - ndev->name); - strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); - phy_id = 0; + if (phy_id >= PHY_MAX_ADDR) { + printk(KERN_INFO + "%s: no PHY, assuming direct connection to switch\n", + ndev->name); + strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); + phy_id = 0; + } + + 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, 0, + fep->phy_interface); } - 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, 0, - fep->phy_interface); if (IS_ERR(phy_dev)) { printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name); return PTR_ERR(phy_dev); @@ -1076,7 +1084,12 @@ 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)) + if (fep->phy_node) + err = of_mdiobus_register(fep->mii_bus, pdev->dev.of_node); + else + err = mdiobus_register(fep->mii_bus); + + if (err) goto err_out_free_mdio_irq; mii_cnt++; @@ -1484,12 +1497,16 @@ static int fec_enet_init(struct net_device *ndev) } #ifdef CONFIG_OF -static int fec_get_phy_mode_dt(struct platform_device *pdev) +static int fec_probe_dt(struct fec_enet_private *fep) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = fep->pdev->dev.of_node; + + if (!np) + return -ENODEV; - if (np) - return of_get_phy_mode(np); + fep->phy_interface = of_get_phy_mode(np); + + fep->phy_node = of_parse_phandle(np, "phy", 0); return -ENODEV; } @@ -1519,7 +1536,7 @@ static void fec_reset_phy(struct platform_device *pdev) gpio_set_value(phy_reset, 1); } #else /* CONFIG_OF */ -static inline int fec_get_phy_mode_dt(struct platform_device *pdev) +static inline int fec_probe_dt(struct fec_enet_private *fep) { return -ENODEV; } @@ -1581,15 +1598,13 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); - ret = fec_get_phy_mode_dt(pdev); + ret = fec_probe_dt(fep); if (ret < 0) { pdata = pdev->dev.platform_data; if (pdata) fep->phy_interface = pdata->phy; else fep->phy_interface = PHY_INTERFACE_MODE_MII; - } else { - fep->phy_interface = ret; } for (i = 0; i < FEC_IRQ_NUM; i++) { diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index c5a3bc1..0120ea6 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -236,6 +236,7 @@ struct fec_enet_private { /* Phylib and MDIO interface */ struct mii_bus *mii_bus; struct phy_device *phy_dev; + struct device_node *phy_node; int mii_timeout; uint phy_speed; phy_interface_t phy_interface;