Received: by 10.223.176.5 with SMTP id f5csp92496wra; Fri, 2 Feb 2018 17:32:08 -0800 (PST) X-Google-Smtp-Source: AH8x224B3GI9e6fl3aQDvtcIUIoDZlWfiUibOAZo2E+dzdfJVhREcOJHjliCTsvDzsb79y97Y49A X-Received: by 10.98.28.80 with SMTP id c77mr7399855pfc.24.1517621528302; Fri, 02 Feb 2018 17:32:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517621528; cv=none; d=google.com; s=arc-20160816; b=NYonKf9siHliEAYDbSBny4QkfmIOkhijt//ZiMMbs1xTtNlzYDo+9svVdUT0oTcQQc VxhhAJD/WvOBGa3CAhHGGRfnKxQpncOW5eL/YqP5J4aAEBHRoop557C5IprxaHciWU1p Vs7mj2E2JFkQqVS9PAdi6pUTon1QqF9eBvvKTtc0c2fF9TG9eTk790l6IGYP0fXf4sr3 y7P4mVMivYxzSjNFfNB9RUVf6pnh44VVbQYR6zAMWXvjj0TM+GjTxSgYXvyFpbftthXP CD2WD6S3/C/oljPMtbmgYP8Pjhs//lyn8h4rPIqNE3gFvO1H5NkuDQwPuCDEUywgBPlb PF8w== 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=vWAu7vFo5VlDLaqMYHOS76Rxxv3F3YCxXxVS9TZ0HH4=; b=msiy/cliUgUzXN51FiG2bZOONUE+SUo3nshoO3oVJRVeGhNa2tRzCAIWxzFOQJnsv4 I+yaJKBkZpw7Q7zN/KWwI2nXkETFZMzzX4iqlNi2kXWAs1gS+lialuG9E2pr+mGuyqDy 7NuhDoGxswx0GRZoUEIZlOkzSndyufmmWORZpYDM2baQSn8WrcRvZZ39vC7ImCjtl3ae In3dtb533/CFC4BDLpt7rMoFqYs37+MMyK87LIsUCl6o7w+5pqnaicv3CTQtmTF3a0FC V57qZkJUqzAh4uOkzER/84DUGxfpqsXAuSw+TP6RX+a2quNBooi3u65BTqhH8D9YvqEZ LTSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Yo9yXVao; 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 v7si746077pgr.301.2018.02.02.17.31.53; Fri, 02 Feb 2018 17:32:08 -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=Yo9yXVao; 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 S1752748AbeBCBZZ (ORCPT + 99 others); Fri, 2 Feb 2018 20:25:25 -0500 Received: from mail-pl0-f67.google.com ([209.85.160.67]:39798 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752191AbeBCBY6 (ORCPT ); Fri, 2 Feb 2018 20:24:58 -0500 Received: by mail-pl0-f67.google.com with SMTP id o13so7472030pli.6 for ; Fri, 02 Feb 2018 17:24:58 -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=vWAu7vFo5VlDLaqMYHOS76Rxxv3F3YCxXxVS9TZ0HH4=; b=Yo9yXVaoRa7gi7g8+tT6bcTBPVtCl/nFL9pqxFDIySc3PGtHvK15saRpn/8wyGTU34 Ru5ZIVMZTLsBLFWqO1rmYIaJ4PzBgo23uQLiiD9Fta5YGQ/JpCaof5Fi907rNW7befEM SJrBZ7mWWwkBFUZJieoC56L4MotMEtBUeMg7c= 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=vWAu7vFo5VlDLaqMYHOS76Rxxv3F3YCxXxVS9TZ0HH4=; b=ebz8OTRcU6C/0cUHzQUPCnTVXqShd9p/RuiSkRmIxWutlJeeVKysUylcSRCdG4mijT jBdvco+8iS+RrwgUV5ExS1xZggGkiBO4vyywsbFw+Oef9sWk/4Rf+oqBOhopZ4neLav2 NQs482bmtw89zNbH+K0ykvMqV8+zA3cg1sNUYUq6qGv3Ju9iVOz/Lr08wwapNFCIGVlB GxWR0m98Ojn0FqLx5XfE9kqjADgtyF6d17vmEownZxASEti5CN+gjhZKC5/zkp6XNk2D imXs0+xS/S+M0P+BO+03CWGbE6J+Mm4AtcpaoZ89CPEfDiyqy2KTLR9PWn+7DSdG5aw1 pWUw== X-Gm-Message-State: AKwxytddr/MEDtYTL7Wn8T2XgEeCRSOhfuHXAAhIw/9IX3loL2G1zcaC sCtVrEmlByewYoSh9H6bYxUvDwMhRRU= X-Received: by 2002:a17:902:2843:: with SMTP id e61-v6mr34868568plb.260.1517621098051; Fri, 02 Feb 2018 17:24:58 -0800 (PST) Received: from exogeni.mtv.corp.google.com ([2620:0:1000:1600:211e:5908:95bc:4888]) by smtp.gmail.com with ESMTPSA id x124sm5332917pfx.105.2018.02.02.17.24.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Feb 2018 17:24:57 -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 v4 2/5] irqchip/gic-v3-its: add ability to save/restore ITS state Date: Fri, 2 Feb 2018 17:24:47 -0800 Message-Id: <20180203012450.18378-3-dbasehore@chromium.org> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180203012450.18378-1-dbasehore@chromium.org> References: <20180203012450.18378-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 | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 06f025fd5726..e13515cdb68f 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,90 @@ 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) { + struct its_ctx *ctx; + void __iomem *base; + + if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) + continue; + + ctx = &its->its_ctx; + 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; + /* + * Only the lower 32 bits matter here since the upper 32 + * don't include any of the offset. + */ + u32 creader = readl_relaxed(base + GITS_CREADR); + int i; + + /* + * Reset the write location to where the ITS is + * currently at. + */ + gits_write_cbaser(ctx->cbaser, base + GITS_CBASER); + gits_write_cwriter(creader, base + GITS_CWRITER); + its->cmd_write = &its->cmd_base[ + creader / sizeof(struct its_cmd_block)]; + /* Restore GITS_BASER from the value cache. */ + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + struct its_baser *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 +3357,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 +3614,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