Received: by 10.223.176.5 with SMTP id f5csp1380061wra; Wed, 7 Feb 2018 18:38:48 -0800 (PST) X-Google-Smtp-Source: AH8x225VA+Ug6lsi3c6C3ImgaPE1T+7f5QiG8cQoQQZRaqFOtATvkWq1Qho/8a9GbMkIufJpgp+K X-Received: by 2002:a17:902:3124:: with SMTP id w33-v6mr8008430plb.356.1518057528518; Wed, 07 Feb 2018 18:38:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518057528; cv=none; d=google.com; s=arc-20160816; b=tmVGIy4WkMK4slY6fvrarz1xrPZHSvnjKzaQr+JlWGpLEexVDF71xHThK8XjKV+tKY KY8yspyooKK2bg47faC4JFSvcsqr+cvgCjKoXM4tyWno1Cm+pC8LYqjqnL3C6ol8c29+ 4FOBX7owTbiPlbTyFEtMee3pRzYNAebhi6krp3kSgUFfeRtaxVRqz2oYyhHeAncPZP83 nXQBh0hgMVyc5HNpcz1QYPfh1BPyE8h30FhSwrF9ncJXZua1ZCA4lrXvPA3szbNefn2M byI9oKPEC5dU5QjKZucHM9DS4Ts/1/vwET9s6Z/Tt+skv6K6NZMZJ9tmLdtxwpP+tlsL ychQ== 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:dkim-signature:arc-authentication-results; bh=s9y5biEv+RFl/1u4Eua0dwSjK+jUzrqU9LcG3m8UF4A=; b=ctwxbLU04E3zv4RglptWkm2pzjgVVYKt8Uway/xy5LLNACxcO12N5UCrKbitgubaol QJXJ1MjepRyAIGN6+Xq5f2pNjQBH/C953QnKo1bOCl9XJDQO6dxYdZ/uCZrB3raw5Lws P29KDWFckC75Samlx9zdA54rX94ClLg7OGEomx5qp7ZeYcfWXtrYuZ5SbDslDazRhc8M YB8+Btl91y58f1ZnUmMlvy9J9UjfeuY5juMyH9X2cd5+EaLBL0JdId2RT1rRlPSXjQog G2P8t+HS4S0TZ6/c5IfjhTodhS8PgasjxYL64fGudIAlHKd+77uHlhAvY2974+kIyqJs /FrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=mZ68EZFn; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b18si1770329pgu.8.2018.02.07.18.38.34; Wed, 07 Feb 2018 18:38:48 -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; dkim=pass header.i=@chromium.org header.s=google header.b=mZ68EZFn; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752189AbeBHChg (ORCPT + 99 others); Wed, 7 Feb 2018 21:37:36 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:37674 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751305AbeBHCgz (ORCPT ); Wed, 7 Feb 2018 21:36:55 -0500 Received: by mail-pf0-f195.google.com with SMTP id p1so1205851pfh.4 for ; Wed, 07 Feb 2018 18:36:55 -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=s9y5biEv+RFl/1u4Eua0dwSjK+jUzrqU9LcG3m8UF4A=; b=mZ68EZFnbD5SmyshdrNXcNOT7qfiGOFovcRS7hvkvpJAwRBBEB6ZxPhJ3eUL10ogW9 Gnd3ip/vaQUMFMu+wsxnF3bgpZ+3o6laDATTSKTXTmbm5HVSWGUiVi/q0sCEc9yEvWEU V0jqI5b5iRF9FOuA2K6e/UE4dDdJPNFYcIKPg= 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=s9y5biEv+RFl/1u4Eua0dwSjK+jUzrqU9LcG3m8UF4A=; b=hqDFzw4uIHc0JiCB9dVBppOxzbH4MvWQIvuwa+do+ITMhNmBD3FaYGvZxAAJamY9Z9 U9aeu/gFZL9W+3krWqALMbx6rSlQP5ixuKG3YfpolWkoGkOwec7IZIeRSi3I3wxR42uS XKmti851DTD6Gu77WuM7f2lWHOMy0ytddXVcgr2KUqD28nlhFEblMyIBE58OvgkRLCmS eO45ovixgZUqCMc+atcm8HcajXYjEd2PuKx1Ednx0h4thF2JwcbhFBudQmlcj5Oecpob uoPvLJGpTdHGeYOm2lyRXl82yMJCGUsGQq85CI1P5Tt5YtMTrfoqdLZnVsfEW+FVvjKD IjnQ== X-Gm-Message-State: APf1xPAmhA8mCQ+wK4m5sk2ZsnB9gSvm5TAwD8cnzw5a0o8CubRYMuXL N9HrqLimI+7atqQIoNeZMF2+xrZ07EA= X-Received: by 10.99.125.82 with SMTP id m18mr6564299pgn.415.1518057414636; Wed, 07 Feb 2018 18:36:54 -0800 (PST) Received: from exogeni.mtv.corp.google.com ([2620:0:1000:1600:211e:5908:95bc:4888]) by smtp.gmail.com with ESMTPSA id 203sm6901941pfa.110.2018.02.07.18.36.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Feb 2018 18:36:53 -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 v6 1/3] irqchip/gic-v3-its: add ability to save/restore ITS state Date: Wed, 7 Feb 2018 18:36:46 -0800 Message-Id: <20180208023648.89124-2-dbasehore@chromium.org> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180208023648.89124-1-dbasehore@chromium.org> References: <20180208023648.89124-1-dbasehore@chromium.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 06f025fd5726..35ad48f51dfa 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) @@ -101,6 +103,8 @@ struct its_node { struct its_collection *collections; struct fwnode_handle *fwnode_handle; u64 (*get_msi_base)(struct its_device *its_dev); + u64 cbaser_save; + u32 ctlr_save; struct list_head its_device_list; u64 flags; unsigned long list_nr; @@ -3042,6 +3046,100 @@ 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) { + void __iomem *base; + + if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) + continue; + + base = its->base; + its->ctlr_save = readl_relaxed(base + GITS_CTLR); + err = its_force_quiescent(base); + if (err) { + pr_err("ITS failed to quiesce\n"); + writel_relaxed(its->ctlr_save, base + GITS_CTLR); + goto err; + } + + its->cbaser_save = gits_read_cbaser(base + GITS_CBASER); + } + +err: + if (err) { + list_for_each_entry_continue_reverse(its, &its_nodes, entry) { + void __iomem *base; + + if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) + continue; + + base = its->base; + writel_relaxed(its->ctlr_save, 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) { + void __iomem *base; + int i; + + if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) + continue; + + base = its->base; + + /* + * Make sure that the ITS is disabled. If it fails to quiesce, + * don't restore it since writing to CBASER or BASER + * registers is undefined according to the GIC v3 ITS + * Specification. + */ + if (its_force_quiescent(base)) { + pr_err("ITS(%p): failed to quiesce on resume\n", base); + continue; + } + + gits_write_cbaser(its->cbaser_save, base + GITS_CBASER); + + /* + * Writing CBASER resets CREADR to 0, so make CWRITER and + * cmd_write line up with it. + */ + its->cmd_write = its->cmd_base; + gits_write_cwriter(0, base + GITS_CWRITER); + + /* Restore GITS_BASER from the value cache. */ + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + struct its_baser *baser = &its->tables[i]; + + if (!(baser->val & GITS_BASER_VALID)) + continue; + + its_write_baser(its, baser, baser->val); + } + writel_relaxed(its->ctlr_save, 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 +3359,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 +3616,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, } } + register_syscore_ops(&its_syscore_ops); + return 0; } -- 2.16.0.rc1.238.g530d649a79-goog