From: Derek Basehore <dbasehore@chromium.org>
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 <dbasehore@chromium.org>
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 [thread overview]
Message-ID: <20180130010007.256564-3-dbasehore@chromium.org> (raw)
In-Reply-To: <20180130010007.256564-1-dbasehore@chromium.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 <dbasehore@chromium.org>
---
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 <linux/of_platform.h>
#include <linux/percpu.h>
#include <linux/slab.h>
+#include <linux/syscore_ops.h>
#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic-v3.h>
@@ -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;
}
--
2.16.0.rc1.238.g530d649a79-goog
next prev parent reply other threads:[~2018-01-30 1:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-30 1:00 [PATCH v3 0/5] GICv3 Save and Restore Derek Basehore
2018-01-30 1:00 ` [PATCH v3 1/5] cpu_pm: add syscore_suspend error handling Derek Basehore
2018-01-30 1:00 ` Derek Basehore [this message]
2018-02-01 22:54 ` [PATCH v3 2/5] irqchip/gic-v3-its: add ability to save/restore ITS state dbasehore .
[not found] ` <20180130010007.256564-1-dbasehore-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-01-30 1:00 ` [PATCH v3 3/5] DT/arm,gic-v3-its: add reset-on-suspend property Derek Basehore
2018-01-30 1:00 ` [PATCH v3 4/5] irqchip/gic-v3-its: add ability to resend MAPC on resume Derek Basehore
[not found] ` <20180130010007.256564-5-dbasehore-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-02-01 22:52 ` dbasehore .
2018-01-30 1:00 ` [PATCH v3 5/5] DT/arm,gic-v3: add collections-reset-on-suspend property Derek Basehore
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180130010007.256564-3-dbasehore@chromium.org \
--to=dbasehore@chromium.org \
--cc=Soby.Mathew@arm.com \
--cc=briannorris@chromium.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=mark.rutland@arm.com \
--cc=rafael.j.wysocki@intel.com \
--cc=robh+dt@kernel.org \
--cc=sudeep.holla@arm.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).