Received: by 10.223.185.116 with SMTP id b49csp7045338wrg; Wed, 28 Feb 2018 21:50:44 -0800 (PST) X-Google-Smtp-Source: AG47ELvMn2HKDWPQiIxynKPLTxSoXPOYepoCpPdGU3c+dcpijEuPhLbcvL+EqQExQ9DWDVhI2VX9 X-Received: by 10.101.66.193 with SMTP id l1mr601820pgp.57.1519883444638; Wed, 28 Feb 2018 21:50:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519883444; cv=none; d=google.com; s=arc-20160816; b=j3okHWxmmACJiZmeH7yTEqU/99jyOTT1cws+PnoGgWX647qoj9dMc3RcmEr7VjGNyO ZmTVoy7IwqPChi0pOKM6PT6LCWRz4dGeS/8tUgqK7HynwB41bbouTQNGpZlcam2kBTM5 V26eB7+X/1f94f3dHMK04dl8Bq7hhXwI4nbMhybI9YZLgye18407nIXCrcta+nEjLlf+ /QvB90I+1L4wEcArSl32ovgG2tfrD6xyWaPheOiPSKzWUoOM6fO9NNmEmApdKSKCQ94y d9nSEv9r297dWUNVNDr5QJu3qyX0iuozJSu0Bvfa5d052tYj5j9MevF+BGGLwDCsoHd2 Qtuw== 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=k4kHsfAJ5JxUKhIB06WTskDGW0vDfJei5PhM2pCIlOU=; b=yz9MMrvk75Tx5D2rYuJbyOCODV5hb13oa9u8G71VbkB5zYfQ6HVq1GvKDsfMvckpqV L73lVRLvlXwVWQwe02TVGbpLUU8zLIIzi1XwZbBDm6wH4tKgeiC6VejoAQ8OGaqTIAN6 nL1iWzjlpV7PGZd3tXoJio7D4uO5F+4YufK2MFptZ7++mqzO3pZm4KeeizUbehU5yaXi YTYtCvoFqj4XOIHF9PoTIW74qD4CsSfXpKrQ+/EI0kK03TAY78JXvQ/DPFLze8cm6gwF 5QCweMWtWqyJ9l51dLvjxLK6c89GoDEw4R6pjFjtfWwT6qtfaA4Dt8mR0gLKuPbhIO6y FhRQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=hNIoQIln; 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 j186si1979919pge.747.2018.02.28.21.50.29; Wed, 28 Feb 2018 21:50:44 -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=hNIoQIln; 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 S966222AbeCAFtT (ORCPT + 99 others); Thu, 1 Mar 2018 00:49:19 -0500 Received: from mail-pl0-f68.google.com ([209.85.160.68]:38224 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966121AbeCAFs2 (ORCPT ); Thu, 1 Mar 2018 00:48:28 -0500 Received: by mail-pl0-f68.google.com with SMTP id d4-v6so3068566pll.5 for ; Wed, 28 Feb 2018 21:48:27 -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=k4kHsfAJ5JxUKhIB06WTskDGW0vDfJei5PhM2pCIlOU=; b=hNIoQIlnrSkrJDLta7jxqOsSu1Zd1PikOM2Vn9KBjKYSX+WKBn1WkRj72sC5FGOEwr QSIx5itdz/o1bv3Ie8Kgo2lmpTKHulj/2QogiT2wwOvpa+LZOMvqmQ9gV9sySRc/lwLT SomC+6/of0mW5gmm49Y1Muh60Ri67lGceEvLE= 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=k4kHsfAJ5JxUKhIB06WTskDGW0vDfJei5PhM2pCIlOU=; b=FAVVCZ52Mm9eUPiOzRoW9tiM77Jl5TLYXQa5zc8VOAeVtCBfiTf17e8yzdJOxLqgqe 2wN7qorezcrGLhg9DFX3cdxoM82LJ7bqM8pNz7D7nhkSgcSCIlPe4drdfDf6x/+Gwrf7 plzo1wOcoVY91Lzl+lfR+YRVfR53X/yeTxQOaIV1irEfaTWw5KlUpJNZPb93AsT6mDaA H2rOyv9/Y08AsLKFTNz3iTjA4CJUtWUYTJNL4w7bcjzcAkBB1Qcs5NdqVQ4gWxw8LCTe 6vyYeNELXB7Az+F5iHRpxg11rp/09/VToM0jdv8msc5+v/vpvRiewvPlfgg0YYNDO4wr IeJQ== X-Gm-Message-State: APf1xPCHKa39AwRicXIUySp2UlaHw+UG1F91hcY0DPgJzBJJO4N8ooKt HdkuwF5/dNEpYdl1jIR5QP+eO034fI4= X-Received: by 2002:a17:902:7045:: with SMTP id h5-v6mr781648plt.217.1519883307305; Wed, 28 Feb 2018 21:48:27 -0800 (PST) Received: from exogeni.mtv.corp.google.com ([2620:0:1000:1501:f407:8d12:c205:7153]) by smtp.gmail.com with ESMTPSA id 184sm6194674pfg.125.2018.02.28.21.48.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Feb 2018 21:48:26 -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 v7 1/3] irqchip/gic-v3-its: add ability to save/restore ITS state Date: Wed, 28 Feb 2018 21:48:18 -0800 Message-Id: <20180301054820.42847-2-dbasehore@chromium.org> X-Mailer: git-send-email 2.16.2.395.g2e18187dfd-goog In-Reply-To: <20180301054820.42847-1-dbasehore@chromium.org> References: <20180301054820.42847-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 | 107 +++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1d3056f53747..926f76944a75 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,104 @@ 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@%pa: failed to quiesce: %d\n", + &its->phys_base, err); + 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; + int ret; + + 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. + */ + ret = its_force_quiescent(base); + if (ret) { + pr_err("ITS@%pa: failed to quiesce on resume: %d\n", + &its->phys_base, ret); + 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 +3363,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; @@ -3517,5 +3622,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, } } + register_syscore_ops(&its_syscore_ops); + return 0; } -- 2.16.2.395.g2e18187dfd-goog