From patchwork Mon May 6 15:33:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Hesselbarth X-Patchwork-Id: 2524561 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork1.kernel.org (Postfix) with ESMTP id 3D56A3FD85 for ; Mon, 6 May 2013 15:35:08 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UZNR7-0006qs-JG; Mon, 06 May 2013 15:34:45 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UZNQx-0007Sk-63; Mon, 06 May 2013 15:34:35 +0000 Received: from mail-bk0-x22b.google.com ([2a00:1450:4008:c01::22b]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UZNQi-0007PO-UG for linux-arm-kernel@lists.infradead.org; Mon, 06 May 2013 15:34:23 +0000 Received: by mail-bk0-f43.google.com with SMTP id jm19so1646912bkc.2 for ; Mon, 06 May 2013 08:33:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=ghf4ZItI7h6IDHCIxrwVRS8KqagFlqTpNA6In1/BVsE=; b=0/LlezlsKKYiwgiyXjGBtJqjLUL3jxfOzLfkArAcgkSxEisrjvYeypdEvcKsdpAqDi jhV6M3gpd8oV3MxFnJXKD46SMn5PSQ/XkUfUUgefcYyQwcfEu8UZBF0/26HuZ/tiIpkm LTKfWnwCK5wyciHs/hr3XbtADA6TL8G4UZLVc4INf1tz4NDMBF2iOIAuLtltkBu1Qv4k 6jdbH1C2l2BCtYqbn74EMiSVX8XjEL4CqXmkkT9gHGmblUKYWk6ieVbBpJ8FTDQP9i0H Q5tqXyiyuSkvJcG9UsjkFy3QGXq0VcNtZs506PdUD9HNjoYLy8CK+azPeWlNYxK5dDbE tv9w== X-Received: by 10.204.174.193 with SMTP id u1mr8928769bkz.81.1367854438832; Mon, 06 May 2013 08:33:58 -0700 (PDT) Received: from topkick.lan (dslc-082-083-251-181.pools.arcor-ip.net. [82.83.251.181]) by mx.google.com with ESMTPSA id cn9sm4186006bkb.6.2013.05.06.08.33.56 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 06 May 2013 08:33:57 -0700 (PDT) Received: from edge.wm.mst.uni-hannover.de (phire.mst.uni-hannover.de [130.75.30.51]) by topkick.lan (Postfix) with ESMTPSA id 1F129605DC; Mon, 6 May 2013 17:33:26 +0200 (CEST) From: Sebastian Hesselbarth To: Sebastian Hesselbarth Subject: [PATCH v3 1/7] net: mv643xx_eth: add Device Tree bindings Date: Mon, 6 May 2013 17:33:34 +0200 Message-Id: <1367854420-8006-2-git-send-email-sebastian.hesselbarth@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1367854420-8006-1-git-send-email-sebastian.hesselbarth@gmail.com> References: <1365071235-11611-1-git-send-email-florian@openwrt.org> <1367854420-8006-1-git-send-email-sebastian.hesselbarth@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130506_113421_300218_993A2BBE X-CRM114-Status: GOOD ( 30.33 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (sebastian.hesselbarth[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Andrew Lunn , linux-doc@vger.kernel.org, Jamie Lentin , linux-kernel@vger.kernel.org, Nigel Roberts , Arnaud Patard , Valentin Longchamp , Russell King , Simon Guinot , Grant Likely , Lennert Buytenhek , Eric Hutter , Jason Cooper , Nobuhiro Iwamatsu , devicetree-discuss@lists.ozlabs.org, Arnaud Ebalard , Rob Herring , Joshua Coombs , Florian Fainelli , linux-arm-kernel@lists.infradead.org, Thomas Petazzoni , Jean-Francois Moine , Simon Baatz , netdev@vger.kernel.org, Alan M Butler , Willy Tarreau , Michael Walle , Rob Landley , David Miller , Stefan Peter X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Florian Fainelli This patch adds Device Tree bindings following the already defined bindings at Documentation/devicetree/bindings/marvell.txt. The binding documentation is also enhanced with new optionnal properties required for supporting certain devices (RX/TX queue and SRAM). Since we now have proper support for the orion MDIO bus driver, there is no need to fiddle around with device tree phandles. PHY-less (MAC connected to switch) configurations are supported by not specifying any phy phandle for an ethernet node. Signed-off-by: Florian Fainelli Signed-off-by: Sebastian Hesselbarth --- Changelog: v2->v3: - rebase on top of mv643xx_eth clean-ups - do not reparse existing platform_data - use managed devm_kzalloc for parsed platform_data - use of_property_read_u32 where applicable - add phy_node to platform_data - use of_connect_phy if DT phy node was found v1->v2: - properly ifdef of_platform_bus_probe with CONFIG_OF - handle of_platform_bus_probe errors and cleanup accordingly - use of_property_read_u32 where applicable - parse "duplex" and "speed" property in PHY-less configuration Cc: Grant Likely Cc: Rob Herring Cc: Rob Landley Cc: Lennert Buytenhek Cc: David Miller Cc: Florian Fainelli Cc: Arnaud Patard Cc: Russell King Cc: Jason Cooper Cc: Andrew Lunn Cc: Jean-Francois Moine Cc: Thomas Petazzoni Cc: Simon Guinot Cc: Jamie Lentin Cc: Michael Walle Cc: Eric Hutter Cc: Joshua Coombs Cc: Willy Tarreau Cc: Simon Baatz Cc: Alan M Butler Cc: Nigel Roberts Cc: Valentin Longchamp Cc: Stefan Peter Cc: Arnaud Ebalard Cc: Nobuhiro Iwamatsu Cc: netdev@vger.kernel.org Cc: devicetree-discuss@lists.ozlabs.org Cc: linux-doc@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- Documentation/devicetree/bindings/marvell.txt | 22 +++++- drivers/net/ethernet/marvell/mv643xx_eth.c | 108 ++++++++++++++++++++++++- include/linux/mv643xx_eth.h | 3 + 3 files changed, 128 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/marvell.txt b/Documentation/devicetree/bindings/marvell.txt index f7a0da6..73ea12f 100644 --- a/Documentation/devicetree/bindings/marvell.txt +++ b/Documentation/devicetree/bindings/marvell.txt @@ -112,11 +112,13 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Required properties: - #address-cells : <1> - #size-cells : <0> - - compatible : "marvell,mv64360-eth-block" + - compatible : "marvell,mv64360-eth-block", "marvell,mv643xx-eth-block" - reg : Offset and length of the register set for this block Optional properties: - clocks : Phandle to the clock control device and gate bit + - tx-csum-limit : Hardware limit above which transmit checksumming + is disabled. Example Discovery Ethernet block node: ethernet-block@2000 { @@ -133,7 +135,7 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Required properties: - device_type : Should be "network". - - compatible : Should be "marvell,mv64360-eth". + - compatible : Should be "marvell,mv64360-eth", "marvell,mv643xx-eth" - reg : Should be <0>, <1>, or <2>, according to which registers within the silicon block the device uses. - interrupts : where a is the interrupt number for the port. @@ -143,6 +145,22 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. controller. - local-mac-address : 6 bytes, MAC address + Optional properties: + - clocks : Phandle to the clock control device and gate bit + - clock-names : String describing the clock gate bit + - speed : Speed to force the link (10, 100, 1000), used when no + phy property is defined + - duplex : Duplex to force the link (0: half, 1: full), used when no + phy property is defined + - rx-queue-count : number of RX queues to use + - tx-queue-count : number of TX queues to use + - rx-queue-size : size of the RX queue (in bytes) + - tx-queue-size : size of the TX queue (in bytes) + - rx-sram-addr : address of the SRAM for RX path (non 0 means used) + - rx-sram-size : size of the SRAM for RX path (non 0 means used) + - tx-sram-addr : address of the SRAM for TX path (non 0 means used) + - tx-sram-size : size of the SRAM for TX path (non 0 means used) + Example Discovery Ethernet port node: ethernet@0 { device_type = "network"; diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index d0afeea..efa5a2f 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -60,6 +60,11 @@ #include #include #include +#include +#include +#include +#include +#include static char mv643xx_eth_driver_name[] = "mv643xx_eth"; static char mv643xx_eth_driver_version[] = "1.4"; @@ -2450,13 +2455,22 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp) } } +static const struct of_device_id mv643xx_eth_match[] = { + { .compatible = "marvell,mv64360-eth" }, + { .compatible = "marvell,mv643xx-eth" }, + { }, +}; +MODULE_DEVICE_TABLE(of, mv643xx_eth_match); + static int mv643xx_eth_shared_probe(struct platform_device *pdev) { static int mv643xx_eth_version_printed; + struct device_node *np = pdev->dev.of_node; struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; struct mv643xx_eth_shared_private *msp; const struct mbus_dram_target_info *dram; struct resource *res; + int tx_csum_limit = 0; if (!mv643xx_eth_version_printed++) pr_notice("MV-643xx 10/100/1000 ethernet driver version %s\n", @@ -2485,13 +2499,21 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) if (dram) mv643xx_eth_conf_mbus_windows(msp, dram); - msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? - pd->tx_csum_limit : 9 * 1024; + if (np) + of_property_read_u32(np, "tx-csum-limit", &tx_csum_limit); + else + tx_csum_limit = pd->tx_csum_limit; + + msp->tx_csum_limit = tx_csum_limit ? tx_csum_limit : 9 * 1024; infer_hw_params(msp); platform_set_drvdata(pdev, msp); +#ifdef CONFIG_OF + return of_platform_bus_probe(np, mv643xx_eth_match, &pdev->dev); +#else return 0; +#endif } static int mv643xx_eth_shared_remove(struct platform_device *pdev) @@ -2505,12 +2527,20 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id mv643xx_eth_shared_match[] = { + { .compatible = "marvell,mv64360-eth-block" }, + { .compatible = "marvell,mv643xx-eth-block" }, + { }, +}; +MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_match); + static struct platform_driver mv643xx_eth_shared_driver = { .probe = mv643xx_eth_shared_probe, .remove = mv643xx_eth_shared_remove, .driver = { .name = MV643XX_ETH_SHARED_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(mv643xx_eth_shared_match), }, }; @@ -2669,6 +2699,68 @@ static const struct net_device_ops mv643xx_eth_netdev_ops = { #endif }; +#ifdef CONFIG_OF +static int mv643xx_eth_of_probe(struct platform_device *pdev) +{ + struct mv643xx_eth_platform_data *pd; + struct device_node *np = pdev->dev.of_node; + struct device_node *shared = of_get_parent(np); + const int *prop; + const char *mac_addr; + + if (pdev->dev.platform_data || !pdev->dev.of_node) + return 0; + + pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + + pdev->dev.platform_data = pd; + + pd->shared = of_find_device_by_node(shared); + if (!pd->shared) + return -ENODEV; + + if (of_property_read_u32(np, "reg", &pd->port_number)) + return -EINVAL; + + pd->phy_node = of_parse_phandle(np, "phy", 0); + if (!pd->phy_node) { + pd->phy_addr = MV643XX_ETH_PHY_NONE; + + of_property_read_u32(np, "speed", &pd->speed); + of_property_read_u32(np, "duplex", &pd->duplex); + } + + mac_addr = of_get_mac_address(np); + if (mac_addr) + memcpy(pd->mac_addr, mac_addr, ETH_ALEN); + +#define rx_tx_queue_sram_property(_name) \ + do { \ + prop = of_get_property(np, __stringify(_name), NULL); \ + if (prop) \ + pd->_name = be32_to_cpup(prop); \ + } while (0) + + rx_tx_queue_sram_property(rx_queue_count); + rx_tx_queue_sram_property(tx_queue_count); + rx_tx_queue_sram_property(rx_queue_size); + rx_tx_queue_sram_property(tx_queue_size); + rx_tx_queue_sram_property(rx_sram_addr); + rx_tx_queue_sram_property(rx_sram_size); + rx_tx_queue_sram_property(tx_sram_addr); + rx_tx_queue_sram_property(rx_sram_size); + + return 0; +} +#else +static inline int mv643xx_eth_of_probe(struct platform_device *dev) +{ + return 0; +} +#endif + static int mv643xx_eth_probe(struct platform_device *pdev) { struct mv643xx_eth_platform_data *pd; @@ -2677,6 +2769,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev) struct resource *res; int err; + err = mv643xx_eth_of_probe(pdev); + if (err) + return err; + pd = pdev->dev.platform_data; if (pd == NULL) { dev_err(&pdev->dev, "no mv643xx_eth_platform_data\n"); @@ -2717,7 +2813,12 @@ static int mv643xx_eth_probe(struct platform_device *pdev) netif_set_real_num_rx_queues(dev, mp->rxq_count); if (pd->phy_addr != MV643XX_ETH_PHY_NONE) { - mp->phy = phy_scan(mp, pd->phy_addr); + if (pd->phy_node) + mp->phy = of_phy_connect(mp->dev, pd->phy_node, + mv643xx_eth_adjust_link, 0, + PHY_INTERFACE_MODE_GMII); + else + mp->phy = phy_scan(mp, pd->phy_addr); if (IS_ERR(mp->phy)) { err = PTR_ERR(mp->phy); @@ -2837,6 +2938,7 @@ static struct platform_driver mv643xx_eth_driver = { .driver = { .name = MV643XX_ETH_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(mv643xx_eth_match), }, }; diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 141d395..c006d3d 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -30,6 +30,8 @@ struct mv643xx_eth_shared_platform_data { #define MV643XX_ETH_PHY_ADDR(x) (0x80 | (x)) #define MV643XX_ETH_PHY_NONE 0xff +struct device_node; + struct mv643xx_eth_platform_data { /* * Pointer back to our parent instance, and our port number. @@ -41,6 +43,7 @@ struct mv643xx_eth_platform_data { * Whether a PHY is present, and if yes, at which address. */ int phy_addr; + struct device_node *phy_node; /* * Use this MAC address if it is valid, overriding the