From patchwork Fri Feb 28 20:42:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 3744731 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2E6AA9F2F7 for ; Fri, 28 Feb 2014 21:35:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 53C97202AE for ; Fri, 28 Feb 2014 21:35:12 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3EDCF201D3 for ; Fri, 28 Feb 2014 21:35:11 +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 1WJUKs-00038F-B8; Fri, 28 Feb 2014 20:47:11 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WJUKB-0004Pm-NR; Fri, 28 Feb 2014 20:46:27 +0000 Received: from arroyo.ext.ti.com ([192.94.94.40]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WJUIY-0004A5-QK for linux-arm-kernel@lists.infradead.org; Fri, 28 Feb 2014 20:44:53 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id s1SKiKUD029550; Fri, 28 Feb 2014 14:44:20 -0600 Received: from DLEE70.ent.ti.com (dlee70.ent.ti.com [157.170.170.113]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id s1SKiKW4029459; Fri, 28 Feb 2014 14:44:20 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.3.174.1; Fri, 28 Feb 2014 14:44:20 -0600 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s1SKiKdB017253; Fri, 28 Feb 2014 14:44:20 -0600 Received: from localhost (irmo.am.dhcp.ti.com [128.247.71.175]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id s1SKiKt09330; Fri, 28 Feb 2014 14:44:20 -0600 (CST) From: Suman Anna To: Joerg Roedel , Tony Lindgren Subject: [PATCHv3 07/13] iommu/omap: allocate archdata on the fly for DT-based devices Date: Fri, 28 Feb 2014 14:42:38 -0600 Message-ID: <1393620164-14633-8-git-send-email-s-anna@ti.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1393620164-14633-1-git-send-email-s-anna@ti.com> References: <1393620164-14633-1-git-send-email-s-anna@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140228_154447_172752_62F968FB X-CRM114-Status: GOOD ( 15.04 ) X-Spam-Score: -6.9 (------) Cc: devicetree@vger.kernel.org, Suman Anna , iommu@lists.linux-foundation.org, Laurent Pinchart , Florian Vaussard , linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Laurent Pinchart The OMAP IOMMU driver locates the IOMMU associated to a device using the IOMMU name stored in the device archdata iommu field. That field is expected to be populated by platform code and is left unset for DT-based devices. This results in a crash when the IOMMU driver attaches a domain to a device. Fix this by allocating the archdata iommu structure when devices are added and freeing when they are removed. Devices without an OF node, and devices without an iommus property in their OF node are ignored. The iommu name is initialized from the IOMMU device node name. This should be simplified when removing non-DT support completely from the IOMMU users as the IOMMU name won't be needed anymore, and the IOMMU device pointer could then be stored in the archdata iommu field directly. Signed-off-by: Laurent Pinchart [s-anna@ti.com: updated to use device name instead of OF name] Signed-off-by: Suman Anna --- drivers/iommu/omap-iommu.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 28bc631..8acea87 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1253,6 +1253,49 @@ static int omap_iommu_domain_has_cap(struct iommu_domain *domain, return 0; } +static int omap_iommu_add_device(struct device *dev) +{ + struct omap_iommu_arch_data *arch_data; + struct device_node *np; + + /* + * Allocate the archdata iommu structure for DT-based devices. + * + * TODO: Simplify this when removing non-DT support completely from the + * IOMMU users. + */ + if (!dev->of_node) + return 0; + + np = of_parse_phandle(dev->of_node, "iommus", 0); + if (!np) + return 0; + + arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL); + if (!arch_data) { + of_node_put(np); + return -ENOMEM; + } + + arch_data->name = kstrdup(dev_name(dev), GFP_KERNEL); + dev->archdata.iommu = arch_data; + + of_node_put(np); + + return 0; +} + +static void omap_iommu_remove_device(struct device *dev) +{ + struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; + + if (!dev->of_node || !arch_data) + return; + + kfree(arch_data->name); + kfree(arch_data); +} + static struct iommu_ops omap_iommu_ops = { .domain_init = omap_iommu_domain_init, .domain_destroy = omap_iommu_domain_destroy, @@ -1262,6 +1305,8 @@ static struct iommu_ops omap_iommu_ops = { .unmap = omap_iommu_unmap, .iova_to_phys = omap_iommu_iova_to_phys, .domain_has_cap = omap_iommu_domain_has_cap, + .add_device = omap_iommu_add_device, + .remove_device = omap_iommu_remove_device, .pgsize_bitmap = OMAP_IOMMU_PGSIZES, };