From patchwork Thu Feb 13 18:15:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 3646761 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B307BBF13A for ; Thu, 13 Feb 2014 18:17:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D208020123 for ; Thu, 13 Feb 2014 18:17:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E9CD220179 for ; Thu, 13 Feb 2014 18:17:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752544AbaBMSRT (ORCPT ); Thu, 13 Feb 2014 13:17:19 -0500 Received: from arroyo.ext.ti.com ([192.94.94.40]:45807 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752407AbaBMSRO (ORCPT ); Thu, 13 Feb 2014 13:17:14 -0500 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id s1DIGXvB009703; Thu, 13 Feb 2014 12:16:33 -0600 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s1DIGWQX014525; Thu, 13 Feb 2014 12:16:32 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Thu, 13 Feb 2014 12:16:32 -0600 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s1DIGWb8031576; Thu, 13 Feb 2014 12:16:32 -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 s1DIGWt02004; Thu, 13 Feb 2014 12:16:32 -0600 (CST) From: Suman Anna To: Joerg Roedel , Tony Lindgren CC: Florian Vaussard , Laurent Pinchart , , , , , Suman Anna Subject: [PATCHv2 06/16] iommu/omap: allocate archdata on the fly for DT-based devices Date: Thu, 13 Feb 2014 12:15:37 -0600 Message-ID: <1392315347-32967-7-git-send-email-s-anna@ti.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1392315347-32967-1-git-send-email-s-anna@ti.com> References: <1392315347-32967-1-git-send-email-s-anna@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 e64025a..f6afe8f 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1256,6 +1256,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, @@ -1265,6 +1308,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, };