Received: by 10.223.176.5 with SMTP id f5csp3653557wra; Mon, 29 Jan 2018 17:02:07 -0800 (PST) X-Google-Smtp-Source: AH8x22503W2NWB5rmSJ8ZxAuCta/k0Ab7spSMfeaFglqC6/GnhtqTm1D4rwvr/YQBrQA9ZxUKPuG X-Received: by 10.99.149.67 with SMTP id t3mr22907093pgn.411.1517274127665; Mon, 29 Jan 2018 17:02:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517274127; cv=none; d=google.com; s=arc-20160816; b=fD+FwoPzratpTR1NH14bRSPmVHfKdRPt/0EIXhoTw1QLqU83/d+qqnwb9EW+KgCNoL kH3cVaB63qzshKOe+McvZoFBOI8Zcn39iiKsI3Y4VubvqvpbolfzKjF2XAsHqmWywNHB XfkpXQzb3ml0jFjBfF49fCLXuMI+vCKJ3euabANp1CIF58DuDve6pCKkWR/fORawOCBx Ti0TkrAQL+YtoHdpvMfwOTGcxoDNoU/j4kJWraIyxzgYDanebb7pwSVymNvMS0xxY3aE L6TQOxvIsvoOAvzbwqhve632YA9YJo+wFcrjSWkER6b6HaK2rstwSnwlZvErDii56ZZu aMcA== 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=T6hRt9oPUQWtbbM8C2Zdly2dEF5lEB6GA06KWhn3u3Y=; b=tzcfnc2RJKhUlHIvsatf32fYnB3KU4Cd2dt3jof7dNrYWxgxzKqPJNkOIWhqnZrR/4 VyG/FIHN5PXqwbCG1wBMq40ICdYxpSqgGXByW7UzYeSsLCbbr4dvu6HCr/uhpAmyowQc WQKUsP+JFIv3dzpzwEJY/4r+als7xl59Q9hDJEQLsAMlIt2nHfASMs4OnWhfIYzpr7Ri 4Ifba45aRgtLFNDJGHkuzNge4rzITYwUgusstmrdtyR+ctHK+Os2t+6WEPFof9vjx8x5 XvxVNGiBb8B8Bek2hW96K9Hbi6qtPINnMZxzNj+qiUGMp7FuzUnuJGWVS4kuDBFNDNq4 udhw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=aTfn82D6; 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 a23si499064pff.83.2018.01.29.17.01.53; Mon, 29 Jan 2018 17:02:07 -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=aTfn82D6; 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 S1752443AbeA3BAW (ORCPT + 99 others); Mon, 29 Jan 2018 20:00:22 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:42785 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752278AbeA3BAU (ORCPT ); Mon, 29 Jan 2018 20:00:20 -0500 Received: by mail-pg0-f67.google.com with SMTP id j16so4448740pgn.9 for ; Mon, 29 Jan 2018 17:00:20 -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=Mfb540tRFB9Z7asLrUxBvaBN1WszYTPOXXcGfkiL8637OWVVdrS+irfzq/TiESdbOX owor39MEH71aBXKVeosGEMiUlzeG4DgHfwNtpAdvdeRlg90f+Hy2FiY5uZ7NShScPOEJ DmE/WuV5FeAwCIgwOzYlfM1ublZRcHSPS4pUI+HSxr0yPvWZaUVfl5JVv4WqaQGj6dkT 2JdtYTqzrR2vccinMZqZsul+ayYR96vKMK1OJoTPWw3zjnJKiaTEV6twTLjhc5oOKGAs /PssOADz9ziD79b3f/0pb9cNNhyJ1Yif0RoSIGtKben10x2VsVi3WyYK4T07dFOsPheh 4H4g== X-Gm-Message-State: AKwxytczMhCDj4/8283Ah2WFmHdTMA/O8b2g5SJto6ivDs0hZDExsGFn HlqQcGaqBNdM5Q+rTshK63sOhoZGUhY= 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-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 | 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; } -- 2.16.0.rc1.238.g530d649a79-goog