From patchwork Fri Mar 29 18:14:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Fainelli X-Patchwork-Id: 2366431 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 8461C3FD40 for ; Fri, 29 Mar 2013 18:19:23 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ULdr7-0005K9-QC; Fri, 29 Mar 2013 18:16:49 +0000 Received: from zmc.proxad.net ([212.27.53.206]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ULdpK-0004ch-M9 for linux-arm-kernel@lists.infradead.org; Fri, 29 Mar 2013 18:15:03 +0000 Received: from localhost (localhost [127.0.0.1]) by zmc.proxad.net (Postfix) with ESMTP id 81FF68F8CCA; Fri, 29 Mar 2013 19:14:53 +0100 (CET) X-Virus-Scanned: amavisd-new at localhost Received: from zmc.proxad.net ([127.0.0.1]) by localhost (zmc.proxad.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 89rWceJ5BkSQ; Fri, 29 Mar 2013 19:14:52 +0100 (CET) Received: from flexo.iliad.local (freebox.vlq16.iliad.fr [213.36.7.13]) by zmc.proxad.net (Postfix) with ESMTPSA id A46F7B3D008; Fri, 29 Mar 2013 19:14:52 +0100 (CET) From: Florian Fainelli To: davem@davemloft.net Subject: [PATCH 1/4] mv643xx_eth: add Device Tree bindings Date: Fri, 29 Mar 2013 19:14:36 +0100 Message-Id: <1364580879-4297-2-git-send-email-florian@openwrt.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1364580879-4297-1-git-send-email-florian@openwrt.org> References: <1364580879-4297-1-git-send-email-florian@openwrt.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130329_141459_199476_ABFF1523 X-CRM114-Status: GOOD ( 21.80 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: thomas.petazzoni@free-electrons.com, moinejf@free.fr, jason@lakedaemon.net, andrew@lunn.ch, netdev@vger.kernel.org, devicetree-discuss@lists.ozlabs.org, rob.herring@calxeda.com, Florian Fainelli , grant.likely@secretlab.ca, buytenh@wantstofly.org, jm@lentin.co.uk, linux-arm-kernel@lists.infradead.org, sebastian.hesselbarth@gmail.com 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 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. Signed-off-by: Florian Fainelli --- Documentation/devicetree/bindings/marvell.txt | 21 ++++- drivers/net/ethernet/marvell/mv643xx_eth.c | 114 ++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/marvell.txt b/Documentation/devicetree/bindings/marvell.txt index f1533d9..fd05016 100644 --- a/Documentation/devicetree/bindings/marvell.txt +++ b/Documentation/devicetree/bindings/marvell.txt @@ -112,9 +112,14 @@ 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,mv64360-eth-group", + "marvell,mv643xx-eth-block" - reg : Offset and length of the register set for this block + Optional properties: + - tx-csum-limit : Hardware limit above which transmit checksumming + is disabled. + Example Discovery Ethernet block node: ethernet-block@2000 { #address-cells = <1>; @@ -130,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. @@ -140,6 +145,18 @@ 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 + - 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 aedbd82..57164cb 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -60,6 +60,10 @@ #include #include #include +#include +#include +#include +#include static char mv643xx_eth_driver_name[] = "mv643xx_eth"; static char mv643xx_eth_driver_version[] = "1.4"; @@ -2542,14 +2546,24 @@ 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" }, + { /* sentinel */ }, +}; +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 ret; + const int *prop; + int tx_csum_limit = 0; if (!mv643xx_eth_version_printed++) pr_notice("MV-643xx 10/100/1000 ethernet driver version %s\n", @@ -2576,13 +2590,19 @@ 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) { + prop = of_get_property(np, "tx-csum-limit", NULL); + if (prop) + tx_csum_limit = be32_to_cpup(prop); + } 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); - return 0; + return of_platform_bus_probe(np, mv643xx_eth_match, &pdev->dev); out_free: kfree(msp); @@ -2600,12 +2620,22 @@ 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-group" }, + { .compatible = "marvell,mv64360-eth-block" }, + { .compatible = "marvell,mv643xx-eth-group" }, + { .compatible = "marvell,mv643xx-eth-block" }, + { /* sentinel */ }, +}; +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 = mv643xx_eth_shared_match, }, }; @@ -2764,6 +2794,71 @@ 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); + struct device_node *phy_node; + const int *prop; + const char *mac_addr; + + if (!pdev->dev.of_node) + return 0; + + pd = kzalloc(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; + + prop = of_get_property(np, "reg", NULL); + if (!prop) + return -EINVAL; + + pd->port_number = be32_to_cpup(prop); + + phy_node = of_parse_phandle(np, "phy", 0); + if (!phy_node) + pd->phy_addr = MV643XX_ETH_PHY_NONE; + else { + prop = of_get_property(phy_node, "reg", NULL); + if (prop) + pd->phy_addr = be32_to_cpup(prop); + } + + 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) \ + prop = of_get_property(np, __stringify(_name), NULL); \ + if (prop) \ + pd->_name = be32_to_cpup(prop); + + 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; @@ -2772,7 +2867,12 @@ 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"); return -ENODEV; @@ -2896,6 +2996,8 @@ out: } #endif free_netdev(dev); + if (pdev->dev.of_node) + kfree(pd); return err; } @@ -2903,6 +3005,7 @@ out: static int mv643xx_eth_remove(struct platform_device *pdev) { struct mv643xx_eth_private *mp = platform_get_drvdata(pdev); + struct mv643xx_eth_platform_data *pd = pdev->dev.platform_data; unregister_netdev(mp->dev); if (mp->phy != NULL) @@ -2918,6 +3021,9 @@ static int mv643xx_eth_remove(struct platform_device *pdev) free_netdev(mp->dev); + if (pdev->dev.of_node) + kfree(pd); + platform_set_drvdata(pdev, NULL); return 0; @@ -2935,6 +3041,7 @@ static void mv643xx_eth_shutdown(struct platform_device *pdev) port_reset(mp); } + static struct platform_driver mv643xx_eth_driver = { .probe = mv643xx_eth_probe, .remove = mv643xx_eth_remove, @@ -2942,6 +3049,7 @@ static struct platform_driver mv643xx_eth_driver = { .driver = { .name = MV643XX_ETH_NAME, .owner = THIS_MODULE, + .of_match_table = mv643xx_eth_match, }, };