From patchwork Tue Jul 5 15:13:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 2463 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 CC58024130 for ; Tue, 5 Jul 2011 15:07:49 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id 817F7A186B5 for ; Tue, 5 Jul 2011 15:07:49 +0000 (UTC) Received: by mail-qw0-f52.google.com with SMTP id 8so4156366qwb.11 for ; Tue, 05 Jul 2011 08:07:49 -0700 (PDT) Received: by 10.229.1.140 with SMTP id 12mr5589059qcf.118.1309878468960; Tue, 05 Jul 2011 08:07:48 -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 r7cs53854qcf; Tue, 5 Jul 2011 08:07:48 -0700 (PDT) Received: by 10.52.113.194 with SMTP id ja2mr9795231vdb.300.1309878468394; Tue, 05 Jul 2011 08:07:48 -0700 (PDT) Received: from TX2EHSOBE001.bigfish.com (tx2ehsobe001.messaging.microsoft.com [65.55.88.11]) by mx.google.com with ESMTPS id bl11si6839765vdb.68.2011.07.05.08.07.47 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 05 Jul 2011 08:07:48 -0700 (PDT) Received-SPF: neutral (google.com: 65.55.88.11 is neither permitted nor denied by best guess record for domain of shawn.guo@linaro.org) client-ip=65.55.88.11; Authentication-Results: mx.google.com; spf=neutral (google.com: 65.55.88.11 is neither permitted nor denied by best guess record for domain of shawn.guo@linaro.org) smtp.mail=shawn.guo@linaro.org Received: from mail76-tx2-R.bigfish.com (10.9.14.247) by TX2EHSOBE001.bigfish.com (10.9.40.21) with Microsoft SMTP Server id 14.1.225.22; Tue, 5 Jul 2011 15:07:47 +0000 Received: from mail76-tx2 (localhost.localdomain [127.0.0.1]) by mail76-tx2-R.bigfish.com (Postfix) with ESMTP id 024F81118124; Tue, 5 Jul 2011 15:07:47 +0000 (UTC) X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275ch8275dhz2dh87h2a8h668h839h) 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 mail76-tx2 (localhost.localdomain [127.0.0.1]) by mail76-tx2 (MessageSwitch) id 1309878464795061_26861; Tue, 5 Jul 2011 15:07:44 +0000 (UTC) Received: from TX2EHSMHS034.bigfish.com (unknown [10.9.14.236]) by mail76-tx2.bigfish.com (Postfix) with ESMTP id BC3073D8050; Tue, 5 Jul 2011 15:07:44 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS034.bigfish.com (10.9.99.134) with Microsoft SMTP Server (TLS) id 14.1.225.22; Tue, 5 Jul 2011 15:07:44 +0000 Received: from az33smr02.freescale.net (10.64.34.200) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server id 14.1.289.8; Tue, 5 Jul 2011 10:07:44 -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 p65F7Y2s029575; Tue, 5 Jul 2011 10:07:41 -0500 (CDT) From: Shawn Guo To: CC: , , , Shawn Guo , Jason Liu , "David S. Miller" , Grant Likely Subject: [PATCH v2 3/3] net/fec: add device tree probe support Date: Tue, 5 Jul 2011 23:13:59 +0800 Message-ID: <1309878839-25743-4-git-send-email-shawn.guo@linaro.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1309878839-25743-1-git-send-email-shawn.guo@linaro.org> References: <1309878839-25743-1-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 --- Documentation/devicetree/bindings/net/fsl-fec.txt | 24 +++++ drivers/net/fec.c | 99 +++++++++++++++++++- 2 files changed, 118 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..1dad888 --- /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". +- 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"; + gpios = <&gpio1 14 0>; /* phy-reset, 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..dec94f4 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,53 @@ 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_gpio(np, 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; + } + + msleep(1); + 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 +1442,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 +1478,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 +1622,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,