Received: by 10.223.176.5 with SMTP id f5csp2985097wra; Mon, 5 Feb 2018 13:36:11 -0800 (PST) X-Google-Smtp-Source: AH8x227Q+iYxxBVtfp6MptKe9HccLqsPedsnsBdykmhlGw2AltQvXx3GRQ+6u5QmMa2Ot906fjon X-Received: by 10.98.178.218 with SMTP id z87mr201232pfl.88.1517866571143; Mon, 05 Feb 2018 13:36:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517866571; cv=none; d=google.com; s=arc-20160816; b=OcF/wnePDdsK7HJ5oUZ0YU+FB8CYErsSMtHCqqhL4TE9+9Utxne2MaUdZ/ptPolNex HBpWxx0PakjOi3sdH5FB49Z6iDZYx4l91Iq63sdgKU214ScdNtXJnLvcwbx0DANP7mYk amGLQrsBuTVd61cSDyUvEHCXuHiENJu1NSvw5HMJ/KfrPIBEAjlSyBgqjJGpC+1dhkt0 uvbG3IgK9cen8xGfs/tr0ilgAZuWGDQNNHV8kL9QJL5GASTI8HC5cLiZfNBWxePqmT18 tX6giTGEqsV2yU+k+iSGb8qrvLRDFgSOeNG8WmcjZB8Zn87EKS67cND1TBt+giPhpUcK oDmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature:dkim-signature :arc-authentication-results; bh=s4U4K1opHgKv2fiBEdfMNZHsE8dLWqWnvIvwIBPr4tY=; b=IVVUZOy38TtgsmiYiFzKn9YwTLzGbo0BRbbCnGkAG49VyhHAEq8Kpd9ZwuTahwJDXf an9LcUuwazayEs+rztmJZbmbc6ozYGudnOtZk0QAeu424NjD9c09H4ar93SHgYJyhrXs o4nmQH5dmDrtJlOHMAfvfMr2Vx4rIPEDjNhZ2E4qpAEUoMd4WBa49wMbjQAnDaJ6B/Tn PmMEUzM0mTv/pCOVgPmWRq66do8REqNw+mToB4r6iVS5ZU+fNg3EpL8l+Y0ip21mmElO 6Rr8C1QSjLW1qOKi4jve7id/+HQcnLbnW2q9ZrPdjhyVydfZVd7FZgYu4YfYbZ3n4jqT RvFg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@google.com header.s=20161025 header.b=kcsMgQkb; dkim=fail header.i=@chromium.org header.s=google header.b=l5B2dJ6Y; 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=fail (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 b1si810206pgc.807.2018.02.05.13.35.56; Mon, 05 Feb 2018 13:36:11 -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=fail header.i=@google.com header.s=20161025 header.b=kcsMgQkb; dkim=fail header.i=@chromium.org header.s=google header.b=l5B2dJ6Y; 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=fail (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752151AbeBEVd6 (ORCPT + 99 others); Mon, 5 Feb 2018 16:33:58 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:36371 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751970AbeBEVdx (ORCPT ); Mon, 5 Feb 2018 16:33:53 -0500 Received: by mail-wm0-f67.google.com with SMTP id f3so273996wmc.1 for ; Mon, 05 Feb 2018 13:33:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=s4U4K1opHgKv2fiBEdfMNZHsE8dLWqWnvIvwIBPr4tY=; b=kcsMgQkbIwB6f4LAnzx/TaP2Pp3HX2euPW4y7X5Xkgf2Ns/w0uQsEZc9tMU8KSn2xk LgcYO91IqV+r6ZWLPEyX7+evUQLugBNeyW2agms7SLNMYBxx4xhY8CCxDcELMx3HQrjL 5PXEHXWekbI5/HfkVORFItAjFXsLWmt7CLfw8YGqyGnAbyVYh6OjAR3vGUXgoFfmw3oY fo/n+oAai22sP2YAoRIo+eDllK5YfLUuUn4ZX4ZLXVunfFQzQuf3DBVLgMAwYezYPQW0 2aq5HX7ChPJjr3fBGsJKbABiWkyNs2lUs5ChmzMLT15D65D31DQv7EaY0+pnKRBmla2R V5ww== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=s4U4K1opHgKv2fiBEdfMNZHsE8dLWqWnvIvwIBPr4tY=; b=l5B2dJ6YfJ/7vEA42M2L3Rx7vgfg8eLSzTdMoLttcVqIQqRcOzJziDEQcGEmStihj9 hI8Fsq/z1yWntAC2bIT9Anr67busaTdu/RBIBdulvCL7lhGzftq4/pNp0O209WwmTZRS hN3+aQ4j+6vn5xRS7RBs3Ki2rOn8I658ecE9E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=s4U4K1opHgKv2fiBEdfMNZHsE8dLWqWnvIvwIBPr4tY=; b=d/rmbpz780yhyFwl3gOyK1zIfK/KGJdMtP6ZrrtGbOwDgpruZoXVftNc3W1nksXneb bUaKj8R6cpOfs1trf32+9vHThxmXxf4xX2EIvyVrtRs2htGBQel0JOr8rW+PqXohpt+E HQSG9x69PhykvNtTqMaFp5zh0aj7GPu7TR+f+UkmVvqlbv06ptvPGVRQdvQTYY4iFksU 678t4csTQaR/XlVDzyFZKaOJPZ7JPBb1zKj07twHTK9gvr5lgcOww4ZrBBDVHsQvPTel wqTvUS/TZc5SdRu+oI7MaakPp4ut86ssiUZKpnwsldYXoPZzITPAnase+UnJWTfgt5yU QUoA== X-Gm-Message-State: APf1xPByQ5/W6jNPrlFaWuFpKBo9CCzbuHSHslxBLvLt8XFMLHiGWBYM jMbYKeRI3ZJ0pgpOMNBN0g4RvQQnYYelv4ta5xwtWw== X-Received: by 10.28.222.5 with SMTP id v5mr99673wmg.161.1517866431338; Mon, 05 Feb 2018 13:33:51 -0800 (PST) MIME-Version: 1.0 Received: by 10.28.124.6 with HTTP; Mon, 5 Feb 2018 13:33:50 -0800 (PST) In-Reply-To: References: <20180203012450.18378-1-dbasehore@chromium.org> <20180203012450.18378-3-dbasehore@chromium.org> From: "dbasehore ." Date: Mon, 5 Feb 2018 13:33:50 -0800 X-Google-Sender-Auth: _9ZIwgpIsUYItLSeGmxNHr0VZqw Message-ID: Subject: Re: [PATCH v4 2/5] irqchip/gic-v3-its: add ability to save/restore ITS state To: Marc Zyngier Cc: linux-kernel , Soby Mathew , Sudeep Holla , devicetree@vger.kernel.org, robh+dt@kernel.org, Mark Rutland , Linux-pm mailing list , "Wysocki, Rafael J" , Thomas Gleixner , Brian Norris Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Feb 5, 2018 at 7:56 AM, Marc Zyngier wrote: > On 03/02/18 01:24, Derek Basehore wrote: >> 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; >> +}; > > Nit: This is pretty small for the ITS context. Given that its_node is > the context, you can safely expand this in the its_node structure. Sounds reasonable. I think I just have it this way because I used to have more in here. > >> + >> 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); > > Accessor matching gits_write_cwriter and co? > >> + 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)]; > > Nit: please do not split lines like this, this is unreadable. We both > have screens that are wide enough for this to fit on a single line. > > More importantly: Why isn't it sufficient to reset both CREADR and > CWRITER to zero? Is there any case where you can suspend whilst having > anything in flight? CREADR is RO and we need to handle the non-zero case. I was planning on getting rid of the write to CWRITER since it shouldn't be needed. Either CREADR and CWRITER have the prior values, or both are reset to 0. > >> + /* 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); > > You may want to first test that this BASER register is actually > requiring something before writing to it. Yes, this is normally safe. > But HW is also normally broken. > >> + } >> + writel_relaxed(ctx->ctlr, base + GITS_CTLR); > > Before restoring all of this, shouldn't you first test that the ITS is > actually in a disabled state? The save_disable code put it in a disabled state. The reset state is also disabled. I don't expect PSCI to change the GITS_CTLR register at all. Are you expecting something on the other side of the PSCI layer to poke this register? We'd probably want to force disable at the start of restore_enable if so. > >> + } >> + } >> + 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; >> } >> > > Thanks, > > M. > -- > Jazz is not dead. It just smells funny... Thanks for the review.