From patchwork Tue Sep 16 11:20:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 4916621 Return-Path: X-Original-To: patchwork-linux-sh@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 6DC63BEEA5 for ; Tue, 16 Sep 2014 11:18:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0B95920149 for ; Tue, 16 Sep 2014 11:18:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 37DDB20120 for ; Tue, 16 Sep 2014 11:18:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752927AbaIPLSE (ORCPT ); Tue, 16 Sep 2014 07:18:04 -0400 Received: from mail-pa0-f51.google.com ([209.85.220.51]:41800 "EHLO mail-pa0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752824AbaIPLSE (ORCPT ); Tue, 16 Sep 2014 07:18:04 -0400 Received: by mail-pa0-f51.google.com with SMTP id kx10so8593624pab.38 for ; Tue, 16 Sep 2014 04:18:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:date:message-id:in-reply-to:references:subject; bh=1/mQmUOCrKjNWmAruGhugd3S3wSy3RBgTDJRtdOKj5w=; b=Yy0+FFeORZSA1qWfQ8b5UTkG2jVsQakIwDIfvSx7wtLcn48XxV0kEBO71uVnNJeBYq 5qz+zDhPTvf76eeqcHuOhQHTtddgSzEbUljqHRoV80BR01cNLl33/KHIgH18fVqM+uz8 Aszg2F4Yku5uK4J/S3g/OaHUoZ4Aqi6y/Ew0ns50tBnocQ/o+5nQ3TOIuj+yUMyonMzT oVjexZM57ULHloW2VFNNpDS1VXl21kszzMDaLTkfSZH/SNXTGQgQWjTRwFfPwS6vCRY7 C98ttjBuor8GpbEf7ViJQr6bFPdrQ9CBBzYaTu8RE3fObEoygwNih5F32pzN95mtcwPa tvsg== X-Received: by 10.66.161.41 with SMTP id xp9mr22738373pab.120.1410866282940; Tue, 16 Sep 2014 04:18:02 -0700 (PDT) Received: from [127.0.0.1] (s214090.ppp.asahi-net.or.jp. [220.157.214.90]) by mx.google.com with ESMTPSA id fk11sm13832279pdb.91.2014.09.16.04.18.00 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Sep 2014 04:18:01 -0700 (PDT) From: Magnus Damm To: Magnus Damm , linux-sh@vger.kernel.org Cc: Magnus Damm , laurent.pinchart@ideasonboard.com Date: Tue, 16 Sep 2014 20:20:22 +0900 Message-Id: <20140916112022.14889.48320.sendpatchset@w520> In-Reply-To: <20140916112001.14889.62059.sendpatchset@w520> References: <20140916112001.14889.62059.sendpatchset@w520> Subject: [PATCH 02/03] iommu/ipmmu-vmsa: Create mapping via group notifier Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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: Magnus Damm Extend the IPMMU-VMSA driver to use a notifier together with IOMMU groups to hook in all devices in the same IOMMU group to the same IOMMU. This patch introduces an assumption that all devices in one IOMMU group share the same UTLB number. Tested with USB Host 2.0 on r8a7790 Lager. Signed-off-by: Magnus Damm --- drivers/iommu/ipmmu-vmsa.c | 121 +++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 46 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- 0001/drivers/iommu/ipmmu-vmsa.c +++ work/drivers/iommu/ipmmu-vmsa.c 2014-09-16 16:52:21.000000000 +0900 @@ -33,6 +33,7 @@ struct ipmmu_vmsa_device { unsigned int num_utlbs; struct dma_iommu_mapping *mapping; + struct notifier_block group_notifier; }; struct ipmmu_vmsa_domain { @@ -1013,9 +1014,79 @@ static int ipmmu_find_utlb(struct ipmmu_ return -1; } -static int ipmmu_add_device(struct device *dev) +static int ipmmu_add_device_mapping(struct device *dev, + struct ipmmu_vmsa_device *mmu, + int utlb) { struct ipmmu_vmsa_archdata *archdata; + int ret; + + archdata = kzalloc(sizeof(*archdata), GFP_KERNEL); + if (!archdata) + return -ENOMEM; + + archdata->mmu = mmu; + archdata->utlb = utlb; + dev->archdata.iommu = archdata; + + /* + * Create the ARM mapping, used by the ARM DMA mapping core to allocate + * VAs. This will allocate a corresponding IOMMU domain. + * + * TODO: + * - Create one mapping per context (TLB). + * - Make the mapping size configurable ? We currently use a 2GB mapping + * at a 1GB offset to ensure that NULL VAs will fault. + */ + if (!mmu->mapping) { + struct dma_iommu_mapping *mapping; + + mapping = arm_iommu_create_mapping(&platform_bus_type, + SZ_1G, SZ_2G); + if (IS_ERR(mapping)) { + dev_err(mmu->dev, "failed to create ARM IOMMU mapping\n"); + return PTR_ERR(mapping); + } + + mmu->mapping = mapping; + } + + /* Attach the ARM VA mapping to the device. */ + ret = arm_iommu_attach_device(dev, mmu->mapping); + if (ret < 0) { + dev_err(dev, "Failed to attach device to VA mapping\n"); + goto error; + } + return 0; + +error: + kfree(archdata); + dev->archdata.iommu = NULL; + return ret; +} + +static int ipmmu_group_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct ipmmu_vmsa_device *mmu; + struct device *dev = data; + struct iommu_group *group = iommu_group_get(dev); + int utlb = (int)iommu_group_get_iommudata(group); + + mmu = container_of(nb, struct ipmmu_vmsa_device, group_notifier); + + /* TODO: remove device */ + switch (action) { + case IOMMU_GROUP_NOTIFY_ADD_DEVICE: + ipmmu_add_device_mapping(dev, mmu, utlb); + break; + } + + return NOTIFY_OK; +} + +static int ipmmu_add_device(struct device *dev) +{ struct ipmmu_vmsa_device *mmu; struct iommu_group *group; int utlb = -1; @@ -1056,6 +1127,8 @@ static int ipmmu_add_device(struct devic return PTR_ERR(group); } + iommu_group_set_iommudata(group, (void *)utlb, NULL); + iommu_group_register_notifier(group, &mmu->group_notifier); ret = iommu_group_add_device(group, dev); iommu_group_put(group); @@ -1064,51 +1137,6 @@ static int ipmmu_add_device(struct devic return ret; } - archdata = kzalloc(sizeof(*archdata), GFP_KERNEL); - if (!archdata) { - ret = -ENOMEM; - goto error; - } - - archdata->mmu = mmu; - archdata->utlb = utlb; - dev->archdata.iommu = archdata; - - /* - * Create the ARM mapping, used by the ARM DMA mapping core to allocate - * VAs. This will allocate a corresponding IOMMU domain. - * - * TODO: - * - Create one mapping per context (TLB). - * - Make the mapping size configurable ? We currently use a 2GB mapping - * at a 1GB offset to ensure that NULL VAs will fault. - */ - if (!mmu->mapping) { - struct dma_iommu_mapping *mapping; - - mapping = arm_iommu_create_mapping(&platform_bus_type, - SZ_1G, SZ_2G); - if (IS_ERR(mapping)) { - dev_err(mmu->dev, "failed to create ARM IOMMU mapping\n"); - return PTR_ERR(mapping); - } - - mmu->mapping = mapping; - } - - /* Attach the ARM VA mapping to the device. */ - ret = arm_iommu_attach_device(dev, mmu->mapping); - if (ret < 0) { - dev_err(dev, "Failed to attach device to VA mapping\n"); - goto error; - } - - return 0; - -error: - kfree(dev->archdata.iommu); - dev->archdata.iommu = NULL; - iommu_group_remove_device(dev); return ret; } @@ -1167,6 +1195,7 @@ static int ipmmu_probe(struct platform_d mmu->dev = &pdev->dev; mmu->pdata = pdev->dev.platform_data; mmu->num_utlbs = 32; + mmu->group_notifier.notifier_call = ipmmu_group_notify; /* Map I/O memory and request IRQ. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);