From patchwork Tue Jan 30 01:00:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derek Basehore X-Patchwork-Id: 10191189 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1050560388 for ; Tue, 30 Jan 2018 01:00:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 01D4A2854A for ; Tue, 30 Jan 2018 01:00:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EAD38288FD; Tue, 30 Jan 2018 01:00:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E1F92854A for ; Tue, 30 Jan 2018 01:00:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752453AbeA3BAW (ORCPT ); Mon, 29 Jan 2018 20:00:22 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:40444 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752362AbeA3BAT (ORCPT ); Mon, 29 Jan 2018 20:00:19 -0500 Received: by mail-pg0-f67.google.com with SMTP id g16so5850993pgn.7 for ; Mon, 29 Jan 2018 17:00:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=T6hRt9oPUQWtbbM8C2Zdly2dEF5lEB6GA06KWhn3u3Y=; b=aTfn82D6Cu88wltxLpNvdq/PfQ0VNOYF8Ar1onSJpdX70Klbge+5DhseMX4nYErEyv +R6A4pycYfRm9OVxuPtVBp+HK4zXjlUmygHdcw12PGUCD4jiEXua5g/Ru/TMetmK1y1U bS734sejcQRFhXoF0SCLljnJFw6JpzNBgWFAs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=T6hRt9oPUQWtbbM8C2Zdly2dEF5lEB6GA06KWhn3u3Y=; b=Sgl6nWCPEsVom4iFqzh5aU8/6T9Q2s1DcNb9XGP38AY4TVYCeiHyMHAbd6r7hyIXNv hnMcqrU60U81fNYJqiG7pyWQIMVqMpC2BCsV/cuAm4PKlLALzI87YDsBDOLh5VF0jYh5 IZCU5VTD2+no13vVFV9BjBSgBT/dFAHiBSQftWnTCaxFQURUpe9KNGbLDdZAOILwKvC8 mOl4x/Pm9oHM+NW/bQR8nv6oMPGKza+D83e2KvCnvHx2Ss0bWZQzY4nqVuKSMxrrR709 /ooE46iM8AbthrlHUd1xKad4w7ysJBrf1somBlod56AzqTiSo/KSMjIytwxWxB87Lq2U 10xA== X-Gm-Message-State: AKwxytcp7MF1OcsvdM+8fN6G3vWekiFNm0QlYy/tJd7qDQ3hinIdaWxK GUf+Uy1181SrIcZO/jUh81U9Ow== X-Google-Smtp-Source: AH8x226E3WWjUYhfMPTN4sEuogsM3+1yZJm3/3e3+Grlab0zXdDkmZFhUUBH6P94Dc3DRMzqAx3rAQ== X-Received: by 10.98.62.69 with SMTP id l66mr28760010pfa.20.1517274017696; Mon, 29 Jan 2018 17:00:17 -0800 (PST) Received: from exogeni.mtv.corp.google.com ([2620:0:1000:1600:211e:5908:95bc:4888]) by smtp.gmail.com with ESMTPSA id c29sm36477492pfd.172.2018.01.29.17.00.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 17:00:16 -0800 (PST) From: Derek Basehore To: linux-kernel@vger.kernel.org Cc: Soby.Mathew@arm.com, sudeep.holla@arm.com, devicetree@vger.kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, linux-pm@vger.kernel.org, rafael.j.wysocki@intel.com, tglx@linutronix.de, briannorris@chromium.org, marc.zyngier@arm.com, Derek Basehore Subject: [PATCH v3 2/5] irqchip/gic-v3-its: add ability to save/restore ITS state Date: Mon, 29 Jan 2018 17:00:04 -0800 Message-Id: <20180130010007.256564-3-dbasehore@chromium.org> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180130010007.256564-1-dbasehore@chromium.org> References: <20180130010007.256564-1-dbasehore@chromium.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some platforms power off GIC logic in suspend, so we need to save/restore state. The distributor and redistributor registers need to be handled in platform code due to access permissions on those registers, but the ITS registers can be restored in the kernel. Signed-off-by: Derek Basehore --- drivers/irqchip/irq-gic-v3-its.c | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 06f025fd5726..759ede7048ed 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) +#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3) #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) @@ -83,6 +85,15 @@ struct its_baser { u32 psz; }; +/* + * Saved ITS state - this is where saved state for the ITS is stored + * when it's disabled during system suspend. + */ +struct its_ctx { + u64 cbaser; + u32 ctlr; +}; + struct its_device; /* @@ -101,6 +112,7 @@ struct its_node { struct its_collection *collections; struct fwnode_handle *fwnode_handle; u64 (*get_msi_base)(struct its_device *its_dev); + struct its_ctx its_ctx; struct list_head its_device_list; u64 flags; unsigned long list_nr; @@ -3042,6 +3054,75 @@ static void its_enable_quirks(struct its_node *its) gic_enable_quirks(iidr, its_quirks, its); } +static int its_save_disable(void) +{ + struct its_node *its; + int err = 0; + + spin_lock(&its_lock); + list_for_each_entry(its, &its_nodes, entry) { + if (its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE) { + struct its_ctx *ctx = &its->its_ctx; + void __iomem *base = its->base; + + ctx->ctlr = readl_relaxed(base + GITS_CTLR); + err = its_force_quiescent(base); + if (err) { + pr_err("ITS failed to quiesce\n"); + writel_relaxed(ctx->ctlr, base + GITS_CTLR); + goto err; + } + + ctx->cbaser = gits_read_cbaser(base + GITS_CBASER); + } + } + +err: + if (err) { + list_for_each_entry_continue_reverse(its, &its_nodes, entry) { + if (its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE) { + struct its_ctx *ctx = &its->its_ctx; + void __iomem *base = its->base; + + writel_relaxed(ctx->ctlr, base + GITS_CTLR); + } + } + } + + spin_unlock(&its_lock); + + return err; +} + +static void its_restore_enable(void) +{ + struct its_node *its; + + spin_lock(&its_lock); + list_for_each_entry(its, &its_nodes, entry) { + if (its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE) { + struct its_ctx *ctx = &its->its_ctx; + void __iomem *base = its->base; + struct its_baser *baser; + int i; + + gits_write_cbaser(ctx->cbaser, base + GITS_CBASER); + /* Restore GITS_BASER from the value cache. */ + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + baser = &its->tables[i]; + its_write_baser(its, baser, baser->val); + } + writel_relaxed(ctx->ctlr, base + GITS_CTLR); + } + } + spin_unlock(&its_lock); +} + +static struct syscore_ops its_syscore_ops = { + .suspend = its_save_disable, + .resume = its_restore_enable, +}; + static int its_init_domain(struct fwnode_handle *handle, struct its_node *its) { struct irq_domain *inner_domain; @@ -3261,6 +3342,9 @@ static int __init its_probe_one(struct resource *res, ctlr |= GITS_CTLR_ImDe; writel_relaxed(ctlr, its->base + GITS_CTLR); + if (fwnode_property_present(handle, "reset-on-suspend")) + its->flags |= ITS_FLAGS_SAVE_SUSPEND_STATE; + err = its_init_domain(handle, its); if (err) goto out_free_tables; @@ -3515,5 +3599,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, } } + register_syscore_ops(&its_syscore_ops); + return 0; }