From patchwork Wed Jun 20 12:56:39 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 9490 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 7172023E1B for ; Wed, 20 Jun 2012 12:57:08 +0000 (UTC) Received: from mail-yw0-f52.google.com (mail-yw0-f52.google.com [209.85.213.52]) by fiordland.canonical.com (Postfix) with ESMTP id 2A91FA1851B for ; Wed, 20 Jun 2012 12:57:08 +0000 (UTC) Received: by yhpp61 with SMTP id p61so6181466yhp.11 for ; Wed, 20 Jun 2012 05:57:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=wpVKK830Hjz1uzsoZciSjp6VlaK5GIWcB3gHidvXQEo=; b=QHoZvbOnmsTdmus+s6SgSiFmLUg8PHjc14dszTfIpzTo7hJbnWQEuQ+bMAGLst4KaA FUWaLUMbGreyKFdOicRY4iI4DK8gAFYZAD7RY7Lfu38ga9CiMI+Db2wZAgAVev1lgMJf s0WKNWaiQ9KtcRLhRrgr7TXvHVaXvOrOa/4n2gfYiepPivj3Rs8oDVLZS0K9yQ72s4x8 g9uByjoy7rBHc5zxHYx59AOzW7PJf6xch8I8ykfeR8a7jS8Tvz2rXtT+E9J9spo2L2ha r3Gzn6TQwnEpgLpu5TUyrt4RGHA9dA4lBXRQHQa74ktCRYFVn7aLgRB++yy9fwhL1ZdD egAg== Received: by 10.50.40.193 with SMTP id z1mr4444917igk.0.1340197027388; Wed, 20 Jun 2012 05:57:07 -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.231.24.148 with SMTP id v20csp178529ibb; Wed, 20 Jun 2012 05:57:06 -0700 (PDT) Received: by 10.180.82.42 with SMTP id f10mr11874236wiy.22.1340197025646; Wed, 20 Jun 2012 05:57:05 -0700 (PDT) Received: from mail-wg0-f50.google.com (mail-wg0-f50.google.com [74.125.82.50]) by mx.google.com with ESMTPS id u10si34400692wiw.43.2012.06.20.05.57.05 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 20 Jun 2012 05:57:05 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.50 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) client-ip=74.125.82.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.50 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) smtp.mail=lee.jones@linaro.org Received: by mail-wg0-f50.google.com with SMTP id ds11so7385651wgb.31 for ; Wed, 20 Jun 2012 05:57:05 -0700 (PDT) Received: by 10.180.8.41 with SMTP id o9mr11951655wia.0.1340197025127; Wed, 20 Jun 2012 05:57:05 -0700 (PDT) Received: from localhost.localdomain (cpc1-aztw13-0-0-cust473.18-1.cable.virginmedia.com. [77.102.241.218]) by mx.google.com with ESMTPS id gc6sm38878374wib.0.2012.06.20.05.57.03 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 20 Jun 2012 05:57:04 -0700 (PDT) From: Lee Jones To: linux-arm-kernel@lists.infradead.org Cc: linus.walleij@stericsson.com, arnd@arndb.de, grant.likely@secretlab.ca, linux@arm.linux.org.uk, broonie@opensource.wolfsonmicro.com, Lee Jones , Samuel Ortiz Subject: [PATCH 03/15] mfd: Make MFD core code Device Tree and IRQ domain aware Date: Wed, 20 Jun 2012 13:56:39 +0100 Message-Id: <1340197011-5435-4-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1340197011-5435-1-git-send-email-lee.jones@linaro.org> References: <1340197011-5435-1-git-send-email-lee.jones@linaro.org> X-Gm-Message-State: ALoCoQkHnsgUe0eJx5yDLKp5AJsGl9ZyiTQhjl3IQSq+c4drAhm9zHO2gFi6bpQk96JsarH4/+vc During Device Tree enablement of the ab8500 and db8500-prcmu drivers, a decision was made to omit registration through the MFD API and use Device Tree directly. However, because MFD devices have a different address space and the ab8500 and db8500 both use I2C to communicate, this causes issues with address translation during execution of of_platform_populate(). So the solution is to make the MFD core aware of Device Tree and have it assign the correct node pointers instead. To make this work the MFD core also needs to be awere of IRQ domains, as Device Tree insists on IRQ domain compatibility. So, instead of providing an irq-base via platform code, in the DT case we simply look up the IRQ domain and map to the correct virtual IRQ. Cc: Samuel Ortiz Signed-off-by: Lee Jones --- drivers/mfd/mfd-core.c | 31 +++++++++++++++++++++++++++---- include/linux/mfd/core.h | 1 + 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index ffc3d48..effc4f5 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include int mfd_cell_enable(struct platform_device *pdev) { @@ -76,6 +78,8 @@ static int mfd_add_device(struct device *parent, int id, { struct resource *res; struct platform_device *pdev; + struct device_node *np = NULL; + struct irq_domain *domain = NULL; int ret = -ENOMEM; int r; @@ -89,6 +93,18 @@ static int mfd_add_device(struct device *parent, int id, pdev->dev.parent = parent; + if (parent->of_node) { + if (cell->of_compatible) { + for_each_child_of_node(parent->of_node, np) { + if (of_device_is_compatible(np, cell->of_compatible)) { + pdev->dev.of_node = np; + domain = irq_find_host(parent->of_node); + break; + } + } + } + } + if (cell->pdata_size) { ret = platform_device_add_data(pdev, cell->platform_data, cell->pdata_size); @@ -112,10 +128,17 @@ static int mfd_add_device(struct device *parent, int id, res[r].end = mem_base->start + cell->resources[r].end; } else if (cell->resources[r].flags & IORESOURCE_IRQ) { - res[r].start = irq_base + - cell->resources[r].start; - res[r].end = irq_base + - cell->resources[r].end; + if (domain) { + /* Unable to create mappings for IRQ ranges. */ + WARN_ON(cell->resources[r].start != cell->resources[r].end); + res[r].start = res[r].end = irq_create_mapping( + domain, cell->resources[r].start); + } else { + res[r].start = irq_base + + cell->resources[r].start; + res[r].end = irq_base + + cell->resources[r].end; + } } else { res[r].parent = cell->resources[r].parent; res[r].start = cell->resources[r].start; diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 4e76163..99b7eb1 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -36,6 +36,7 @@ struct mfd_cell { /* platform data passed to the sub devices drivers */ void *platform_data; size_t pdata_size; + const char *of_compatible; /* * These resources can be specified relative to the parent device.