From patchwork Sun Mar 10 17:18:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 2245111 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 6C9ACDF24C for ; Sun, 10 Mar 2013 17:18:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752732Ab3CJRSr (ORCPT ); Sun, 10 Mar 2013 13:18:47 -0400 Received: from bhuna.collabora.co.uk ([93.93.135.160]:39319 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751619Ab3CJRSq (ORCPT ); Sun, 10 Mar 2013 13:18:46 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: javier) with ESMTPSA id E1543169851B From: Javier Martinez Canillas To: Jon Hunter Cc: Benoit Cousson , Tony Lindgren , Russell King , Grant Likely , Enric Balletbo i Serra , Ezequiel Garcia , linux-omap , devicetree-discuss@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, Javier Martinez Canillas Subject: [PATCH 1/1] ARM: OMAP: gpmc: request CS address space for ethernet chips Date: Sun, 10 Mar 2013 18:18:22 +0100 Message-Id: <1362935902-29720-1-git-send-email-javier.martinez@collabora.co.uk> X-Mailer: git-send-email 1.7.7.6 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org Besides being used to interface with external memory devices, the General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices such as ethernet controllers to OMAP2+ processors using the GPMC as a data bus. The actual mapping between the GPMC address space and OMAP2+ address space is made using the GPMC DT "ranges" property. But also a explicit call to gpmc_cs_request() is needed. So, this patch allows an ethernet chip to be defined as an GPMC child node an its chip-select memory address be requested. Signed-off-by: Javier Martinez Canillas --- Jon, This patch assumes that we have solved somehow the issue that a call to request_irq() is needed before before using a GPIO as an IRQ and this is no longer the case when using from Device Trees. Anyway, this is independent as how we solve this, whether is using Jan's patch [1], adding a .request function pointer to irq_chip as suggested by Stephen [2], or any other approach. [1]: https://patchwork.kernel.org/patch/2009331/ [2]: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg85592.html arch/arm/mach-omap2/gpmc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 4fe9ee7..d1bf48b 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -1296,6 +1297,42 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev, } #endif +static int gpmc_probe_ethernet_child(struct platform_device *pdev, + struct device_node *child) +{ + int ret, cs; + unsigned long base; + struct resource res; + struct platform_device *of_dev; + + if (of_property_read_u32(child, "reg", &cs) < 0) { + dev_err(&pdev->dev, "%s has no 'reg' property\n", + child->full_name); + return -ENODEV; + } + + if (of_address_to_resource(child, 0, &res)) { + dev_err(&pdev->dev, "%s has malformed 'reg' property\n", + child->full_name); + return -ENODEV; + } + + ret = gpmc_cs_request(cs, resource_size(&res), &base); + if (IS_ERR_VALUE(ret)) { + dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); + return ret; + } + + of_dev = of_platform_device_create(child, NULL, &pdev->dev); + if (!of_dev) { + dev_err(&pdev->dev, "cannot create platform device for %s\n", + child->full_name); + return -ENODEV; + } + + return 0; +} + static int gpmc_probe_dt(struct platform_device *pdev) { int ret; @@ -1326,6 +1363,14 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } } + + for_each_node_by_name(child, "ethernet") { + ret = gpmc_probe_ethernet_child(pdev, child); + if (ret < 0) { + of_node_put(child); + return ret; + } + } return 0; } #else