From patchwork Wed Jul 6 16:22:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 2482 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 2F63B2413B for ; Wed, 6 Jul 2011 16:16:28 +0000 (UTC) Received: from mail-qy0-f173.google.com (mail-qy0-f173.google.com [209.85.216.173]) by fiordland.canonical.com (Postfix) with ESMTP id D333EA18ABE for ; Wed, 6 Jul 2011 16:16:27 +0000 (UTC) Received: by qyk10 with SMTP id 10so2573465qyk.11 for ; Wed, 06 Jul 2011 09:16:27 -0700 (PDT) Received: by 10.229.62.194 with SMTP id y2mr6721332qch.4.1309968987278; Wed, 06 Jul 2011 09:16:27 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.48.135 with SMTP id r7cs83526qcf; Wed, 6 Jul 2011 09:16:26 -0700 (PDT) Received: by 10.224.32.96 with SMTP id b32mr6843999qad.244.1309968985434; Wed, 06 Jul 2011 09:16:25 -0700 (PDT) Received: from TX2EHSOBE009.bigfish.com (tx2ehsobe004.messaging.microsoft.com [65.55.88.14]) by mx.google.com with ESMTPS id fx9si7115168vdc.19.2011.07.06.09.16.24 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 06 Jul 2011 09:16:25 -0700 (PDT) Received-SPF: neutral (google.com: 65.55.88.14 is neither permitted nor denied by best guess record for domain of shawn.guo@linaro.org) client-ip=65.55.88.14; Authentication-Results: mx.google.com; spf=neutral (google.com: 65.55.88.14 is neither permitted nor denied by best guess record for domain of shawn.guo@linaro.org) smtp.mail=shawn.guo@linaro.org Received: from mail193-tx2-R.bigfish.com (10.9.14.244) by TX2EHSOBE009.bigfish.com (10.9.40.29) with Microsoft SMTP Server id 14.1.225.22; Wed, 6 Jul 2011 16:16:24 +0000 Received: from mail193-tx2 (localhost.localdomain [127.0.0.1]) by mail193-tx2-R.bigfish.com (Postfix) with ESMTP id 4BB1A1B5825A; Wed, 6 Jul 2011 16:16:24 +0000 (UTC) X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275ch8275dhz2dh87h2a8h668h839h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPVD:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-FB-DOMAIN-IP-MATCH: fail Received: from mail193-tx2 (localhost.localdomain [127.0.0.1]) by mail193-tx2 (MessageSwitch) id 1309968982687391_3935; Wed, 6 Jul 2011 16:16:22 +0000 (UTC) Received: from TX2EHSMHS010.bigfish.com (unknown [10.9.14.253]) by mail193-tx2.bigfish.com (Postfix) with ESMTP id A079CBA804B; Wed, 6 Jul 2011 16:16:22 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS010.bigfish.com (10.9.99.110) with Microsoft SMTP Server (TLS) id 14.1.225.22; Wed, 6 Jul 2011 16:16:17 +0000 Received: from az33smr02.freescale.net (10.64.34.200) by 039-SN1MMR1-002.039d.mgd.msft.net (10.84.1.15) with Microsoft SMTP Server id 14.1.289.8; Wed, 6 Jul 2011 11:16:16 -0500 Received: from S2100-06.ap.freescale.net (S2100-06.ap.freescale.net [10.192.242.125]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id p66GGCx0016860; Wed, 6 Jul 2011 11:16:13 -0500 (CDT) From: Shawn Guo To: CC: , , , Shawn Guo , Jason Liu , "David S. Miller" , Grant Likely Subject: [PATCH RESEND v2 3/3] net/fec: add device tree probe support Date: Thu, 7 Jul 2011 00:22:33 +0800 Message-ID: <1309969353-13128-1-git-send-email-shawn.guo@linaro.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1309878839-25743-4-git-send-email-shawn.guo@linaro.org> References: <1309878839-25743-4-git-send-email-shawn.guo@linaro.org> MIME-Version: 1.0 X-OriginatorOrg: sigmatel.com It adds device tree probe support for fec driver. Signed-off-by: Jason Liu Signed-off-by: Shawn Guo Cc: David S. Miller Cc: Grant Likely Acked-by: Grant Likely --- Resend with changes: * use of_get_named_gpio for phy-reset-gpios Documentation/devicetree/bindings/net/fsl-fec.txt | 24 +++++ drivers/net/fec.c | 98 +++++++++++++++++++- 2 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/fsl-fec.txt diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt new file mode 100644 index 0000000..de43951 --- /dev/null +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -0,0 +1,24 @@ +* Freescale Fast Ethernet Controller (FEC) + +Required properties: +- compatible : Should be "fsl,-fec" +- reg : Address and length of the register set for the device +- interrupts : Should contain fec interrupt +- phy-mode : String, operation mode of the PHY interface. + Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii", + "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii". +- phy-reset-gpios : Should specify the gpio for phy reset + +Optional properties: +- local-mac-address : 6 bytes, mac address + +Example: + +fec@83fec000 { + compatible = "fsl,imx51-fec", "fsl,imx27-fec"; + reg = <0x83fec000 0x4000>; + interrupts = <87>; + phy-mode = "mii"; + phy-reset-gpios = <&gpio1 14 0>; /* GPIO2_14 */ + local-mac-address = [00 04 9F 01 1B B9]; +}; diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 7ae3f28..720aa63 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -44,6 +44,10 @@ #include #include #include +#include +#include +#include +#include #include @@ -78,6 +82,17 @@ static struct platform_device_id fec_devtype[] = { { } }; +enum fec_type { + IMX27_FEC, + IMX28_FEC, +}; + +static const struct of_device_id fec_dt_ids[] = { + { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, + { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, + { /* sentinel */ } +}; + static unsigned char macaddr[ETH_ALEN]; module_param_array(macaddr, byte, NULL, 0); MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); @@ -734,8 +749,22 @@ static void __inline__ fec_get_mac(struct net_device *ndev) */ iap = macaddr; +#ifdef CONFIG_OF + /* + * 2) from device tree data + */ + if (!is_valid_ether_addr(iap)) { + struct device_node *np = fep->pdev->dev.of_node; + if (np) { + const char *mac = of_get_mac_address(np); + if (mac) + iap = (unsigned char *) mac; + } + } +#endif + /* - * 2) from flash or fuse (via platform data) + * 3) from flash or fuse (via platform data) */ if (!is_valid_ether_addr(iap)) { #ifdef CONFIG_M5272 @@ -748,7 +777,7 @@ static void __inline__ fec_get_mac(struct net_device *ndev) } /* - * 3) FEC mac registers set by bootloader + * 4) FEC mac registers set by bootloader */ if (!is_valid_ether_addr(iap)) { *((unsigned long *) &tmpaddr[0]) = @@ -1358,6 +1387,52 @@ static int fec_enet_init(struct net_device *ndev) return 0; } +#ifdef CONFIG_OF +static int __devinit fec_get_phy_mode_dt(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + + if (np) + return of_get_phy_mode(np); + + return -ENODEV; +} + +static int __devinit fec_reset_phy(struct platform_device *pdev) +{ + int err, phy_reset; + struct device_node *np = pdev->dev.of_node; + + if (!np) + return -ENODEV; + + phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); + err = gpio_request_one(phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset"); + if (err) { + pr_warn("FEC: failed to get gpio phy-reset: %d\n", err); + return err; + } + + gpio_set_value(phy_reset, 1); + + return 0; +} +#else /* CONFIG_OF */ +static inline int fec_get_phy_mode_dt(struct platform_device *pdev) +{ + return -ENODEV; +} + +static inline int fec_reset_phy(struct platform_device *pdev) +{ + /* + * In case of platform probe, the reset has been done + * by machine code. + */ + return 0; +} +#endif /* CONFIG_OF */ + static int __devinit fec_probe(struct platform_device *pdev) { @@ -1366,6 +1441,11 @@ fec_probe(struct platform_device *pdev) struct net_device *ndev; int i, irq, ret = 0; struct resource *r; + const struct of_device_id *of_id; + + of_id = of_match_device(fec_dt_ids, &pdev->dev); + if (of_id) + pdev->id_entry = of_id->data; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) @@ -1397,9 +1477,16 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); - pdata = pdev->dev.platform_data; - if (pdata) - fep->phy_interface = pdata->phy; + fep->phy_interface = fec_get_phy_mode_dt(pdev); + if (fep->phy_interface < 0) { + pdata = pdev->dev.platform_data; + if (pdata) + fep->phy_interface = pdata->phy; + else + fep->phy_interface = PHY_INTERFACE_MODE_MII; + } + + fec_reset_phy(pdev); /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { @@ -1534,6 +1621,7 @@ static struct platform_driver fec_driver = { #ifdef CONFIG_PM .pm = &fec_pm_ops, #endif + .of_match_table = fec_dt_ids, }, .id_table = fec_devtype, .probe = fec_probe,