Received: by 2002:ac0:a679:0:0:0:0:0 with SMTP id p54csp672751imp; Wed, 20 Feb 2019 07:07:06 -0800 (PST) X-Google-Smtp-Source: AHgI3IZEzzwyoSUVbZZYTLOS30iA8TAvThGTv5bbPsvtYDt2ag4ykbHOdm5erbKdtSen2h+37dM4 X-Received: by 2002:a63:6506:: with SMTP id z6mr29587383pgb.334.1550675226532; Wed, 20 Feb 2019 07:07:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550675226; cv=none; d=google.com; s=arc-20160816; b=MmUN/3OWKJ6yoARbMiHCAR0GapG/vmFheOykM6QsUoQVRT5Nfb4a6IqHmol7NOVRlv 6hnhb7EVeiEhR8Fsnupnp0+Axsgv4yrsxgOl0osgQeRAsjK6WWJSLCSMVCbyAeKy0QRz 9kXHMJQfRanAJb+eyHPy8DJDMlSy9n3KJUC/f3C9P1cHLIMUbJOXuwSS1b27zp3v2Rce G2YCeKmQqtX1eSsjg41ejYPs0h6TVzmXVcn3IFgTuKiYzbmXF870dnLM64U8gmB8V4/W nruxUTO8jJJnNIAZEAHx8AK5OgPIWjjw6Mqp/XGcwTir+Ti2oAn1PjFgRkcBS442+Cnj 0cmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=5Uq4Z1UHbtWj8XUIOSrbPmGo6lN6oFmMQ+WiHsEkWV0=; b=vkQXQ2q/Ba30wtiDGO/uRsK2qkDKR/d631D5JKkM9d/qNbXxaHBfnSK3tySXLNwCW6 ZyeNihxJmyh1G7S/DLGbU3Fn6/DplvXvEIS/RTcqOxMARMERLyM0ynDSDuAEoK+dyPUj np3SH6F3FrY/wvKMLiSo1WbuPE6n//Jlk8UUQeUv/a0PxDd+x2NmeE1/011uYfnsGGFe 9w+68AUKMXxapCf1FnFflgOt+ZKQGnbuZfqI3aG7U2RSJUhUdjtmh8Bz9pKd6xBu+vC9 Ts+R5G1VD01gEgioEVJM0LOBwd4IAYbicmd5gMWwZa/sG4r+jJ0LAMep8mzD5jNQV34b 1IjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o188si11027636pfb.66.2019.02.20.07.06.39; Wed, 20 Feb 2019 07:07:06 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726798AbfBTPFu (ORCPT + 99 others); Wed, 20 Feb 2019 10:05:50 -0500 Received: from baptiste.telenet-ops.be ([195.130.132.51]:52848 "EHLO baptiste.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726953AbfBTPFi (ORCPT ); Wed, 20 Feb 2019 10:05:38 -0500 Received: from ramsan ([84.194.111.163]) by baptiste.telenet-ops.be with bizsmtp id f35b1z00N3XaVaC0135b9C; Wed, 20 Feb 2019 16:05:36 +0100 Received: from rox.of.borg ([192.168.97.57]) by ramsan with esmtp (Exim 4.90_1) (envelope-from ) id 1gwTRH-0002IS-Mf; Wed, 20 Feb 2019 16:05:35 +0100 Received: from geert by rox.of.borg with local (Exim 4.90_1) (envelope-from ) id 1gwTRH-0000f2-LB; Wed, 20 Feb 2019 16:05:35 +0100 From: Geert Uytterhoeven To: Joerg Roedel , Magnus Damm Cc: Laurent Pinchart , iommu@lists.linux-foundation.org, linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH 7/7] iommu/ipmmu-vmsa: Add suspend/resume support Date: Wed, 20 Feb 2019 16:05:31 +0100 Message-Id: <20190220150531.2462-8-geert+renesas@glider.be> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190220150531.2462-1-geert+renesas@glider.be> References: <20190220150531.2462-1-geert+renesas@glider.be> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org During PSCI system suspend, R-Car Gen3 SoCs are powered down, and all IPMMU state is lost. Hence after s2ram, devices wired behind an IPMMU, and configured to use it, will see their DMA operations hang. To fix this, restore all IPMMU contexts, and re-enable all active micro-TLBs during system resume. To avoid overhead on platforms not needing it, the resume code has a build time dependency on sleep and PSCI support, and a runtime dependency on PSCI. Signed-off-by: Geert Uytterhoeven --- This patch takes a different approach than the BSP, which implements a bulk save/restore of all registers during system suspend/resume. drivers/iommu/ipmmu-vmsa.c | 52 +++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 92a766dd8b459f0c..5d22139914e8f033 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,10 @@ #define arm_iommu_detach_device(...) do {} while (0) #endif -#define IPMMU_CTX_MAX 8U +#define IPMMU_CTX_MAX 8U +#define IPMMU_CTX_INVALID -1 + +#define IPMMU_UTLB_MAX 48U struct ipmmu_features { bool use_ns_alias_offset; @@ -58,6 +62,7 @@ struct ipmmu_vmsa_device { spinlock_t lock; /* Protects ctx and domains[] */ DECLARE_BITMAP(ctx, IPMMU_CTX_MAX); struct ipmmu_vmsa_domain *domains[IPMMU_CTX_MAX]; + s8 utlb_ctx[IPMMU_UTLB_MAX]; struct iommu_group *group; struct dma_iommu_mapping *mapping; @@ -335,6 +340,7 @@ static void ipmmu_utlb_enable(struct ipmmu_vmsa_domain *domain, ipmmu_write(mmu, IMUCTR(utlb), IMUCTR_TTSEL_MMU(domain->context_id) | IMUCTR_FLUSH | IMUCTR_MMUEN); + mmu->utlb_ctx[utlb] = domain->context_id; } /* @@ -346,6 +352,7 @@ static void ipmmu_utlb_disable(struct ipmmu_vmsa_domain *domain, struct ipmmu_vmsa_device *mmu = domain->mmu; ipmmu_write(mmu, IMUCTR(utlb), 0); + mmu->utlb_ctx[utlb] = IPMMU_CTX_INVALID; } static void ipmmu_tlb_flush_all(void *cookie) @@ -1043,6 +1050,7 @@ static int ipmmu_probe(struct platform_device *pdev) spin_lock_init(&mmu->lock); bitmap_zero(mmu->ctx, IPMMU_CTX_MAX); mmu->features = of_device_get_match_data(&pdev->dev); + memset(mmu->utlb_ctx, IPMMU_CTX_INVALID, mmu->features->num_utlbs); dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); /* Map I/O memory and request IRQ. */ @@ -1158,10 +1166,52 @@ static int ipmmu_remove(struct platform_device *pdev) return 0; } +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM_PSCI_FW) +static int ipmmu_resume_noirq(struct device *dev) +{ + struct ipmmu_vmsa_device *mmu = dev_get_drvdata(dev); + unsigned int i; + + /* This is the best we can do to check for the presence of PSCI */ + if (!psci_ops.cpu_suspend) + return 0; + + /* Reset root MMU and restore contexts */ + if (ipmmu_is_root(mmu)) { + ipmmu_device_reset(mmu); + + for (i = 0; i < mmu->num_ctx; i++) { + if (!mmu->domains[i]) + continue; + + ipmmu_context_init(mmu->domains[i]); + } + } + + /* Re-enable active micro-TLBs */ + for (i = 0; i < mmu->features->num_utlbs; i++) { + if (mmu->utlb_ctx[i] == IPMMU_CTX_INVALID) + continue; + + ipmmu_utlb_enable(mmu->root->domains[mmu->utlb_ctx[i]], i); + } + + return 0; +} + +static const struct dev_pm_ops ipmmu_pm = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ipmmu_resume_noirq) +}; +#define DEV_PM_OPS &ipmmu_pm +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ + static struct platform_driver ipmmu_driver = { .driver = { .name = "ipmmu-vmsa", .of_match_table = of_match_ptr(ipmmu_of_ids), + .pm = DEV_PM_OPS, }, .probe = ipmmu_probe, .remove = ipmmu_remove, -- 2.17.1