Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3E5CC636D3 for ; Sun, 5 Feb 2023 10:51:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229565AbjBEKvx (ORCPT ); Sun, 5 Feb 2023 05:51:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229453AbjBEKvt (ORCPT ); Sun, 5 Feb 2023 05:51:49 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8329720697 for ; Sun, 5 Feb 2023 02:51:48 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 16DFF60B27 for ; Sun, 5 Feb 2023 10:51:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7AF8EC4339B; Sun, 5 Feb 2023 10:51:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1675594307; bh=hgOnkDCrZdJzSs8ND42SQHu3bPHpFwFgumupQQgGpuw=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=l27LQFGVLMkQ1zgjp5jsKlgst0ZhjdL+To0GfWDHxSIUOKJsu8zni74Ii/rL4TlGn Jo3hnmYo8HL0qMhiFpojWAzWlnCi8n6cGEJzqcPpysE2e4r1W7naxmnmJOv/tmNiQI KaF5B6+irC8Eh81xTs0FxyfVU8hxXUXPf4EraLZRlxY/Vjpct8KkQQ6uzoqDGr1oit RVQOzta4oZMeD+NJMsvzSWKei6+oJeNZ99x8aik3LSPR1jo8w2Y8hvXMys3x6UNZtF rHvhZ49cKntJ0SnyNIwVJEqAl4VGtxYWKY2VGeQ1I8bb8j+DETttk1pzGelhmLxMu8 DcwiX3Zt/xrWA== Received: from sofa.misterjones.org ([185.219.108.64] helo=goblin-girl.misterjones.org) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pOccb-007X8Q-CT; Sun, 05 Feb 2023 10:51:45 +0000 Date: Sun, 05 Feb 2023 10:51:45 +0000 Message-ID: <864js01j26.wl-maz@kernel.org> From: Marc Zyngier To: Mason Huo Cc: Thomas Gleixner , Palmer Dabbelt , Paul Walmsley , , , Ley Foon Tan , Sia Jee Heng Subject: Re: [PATCH v1] irqchip/irq-sifive-plic: Add syscore callbacks for hibernation In-Reply-To: <20230113094216.116036-1-mason.huo@starfivetech.com> References: <20230113094216.116036-1-mason.huo@starfivetech.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/28.2 (aarch64-unknown-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: mason.huo@starfivetech.com, tglx@linutronix.de, palmer@dabbelt.com, paul.walmsley@sifive.com, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, leyfoon.tan@starfivetech.com, jeeheng.sia@starfivetech.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 13 Jan 2023 09:42:16 +0000, Mason Huo wrote: >=20 > The priority and enable registers of plic will be reset > during hibernation power cycle in poweroff mode, > add the syscore callbacks to save/restore those registers. >=20 > Signed-off-by: Mason Huo > Reviewed-by: Ley Foon Tan > Reviewed-by: Sia Jee Heng > --- > drivers/irqchip/irq-sifive-plic.c | 93 ++++++++++++++++++++++++++++++- > 1 file changed, 91 insertions(+), 2 deletions(-) >=20 > diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifi= ve-plic.c > index ff47bd0dec45..80306de45d2b 100644 > --- a/drivers/irqchip/irq-sifive-plic.c > +++ b/drivers/irqchip/irq-sifive-plic.c > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > #include > =20 > /* > @@ -67,6 +68,8 @@ struct plic_priv { > struct irq_domain *irqdomain; > void __iomem *regs; > unsigned long plic_quirks; > + unsigned int nr_irqs; > + u32 *priority_reg; > }; > =20 > struct plic_handler { > @@ -79,10 +82,13 @@ struct plic_handler { > raw_spinlock_t enable_lock; > void __iomem *enable_base; > struct plic_priv *priv; > + /* To record interrupts that are enabled before suspend. */ > + u32 enable_reg[MAX_DEVICES / 32]; What does MAX_DEVICES represent here? How is it related to the number of interrupts you're trying to save? It seems to be related to the number of CPUs, so it hardly makes any sense so far. > }; > static int plic_parent_irq __ro_after_init; > static bool plic_cpuhp_setup_done __ro_after_init; > static DEFINE_PER_CPU(struct plic_handler, plic_handlers); > +static struct plic_priv *priv_data; > =20 > static int plic_irq_set_type(struct irq_data *d, unsigned int type); > =20 > @@ -229,6 +235,78 @@ static int plic_irq_set_type(struct irq_data *d, uns= igned int type) > return IRQ_SET_MASK_OK; > } > =20 > +static void plic_irq_resume(void) > +{ > + unsigned int i, cpu; > + u32 __iomem *reg; > + > + for (i =3D 0; i < priv_data->nr_irqs; i++) > + writel(priv_data->priority_reg[i], > + priv_data->regs + PRIORITY_BASE + i * PRIORITY_PER_ID); =46rom what I can tell, this driver uses exactly 2 priorities: 0 and 1. And yet you use a full 32bit to encode those. Does it seem like a good idea? > + > + for_each_cpu(cpu, cpu_present_mask) { > + struct plic_handler *handler =3D per_cpu_ptr(&plic_handlers, cpu); > + > + if (!handler->present) > + continue; > + > + for (i =3D 0; i < DIV_ROUND_UP(priv_data->nr_irqs, 32); i++) { > + reg =3D handler->enable_base + i * sizeof(u32); > + raw_spin_lock(&handler->enable_lock); > + writel(handler->enable_reg[i], reg); > + raw_spin_unlock(&handler->enable_lock); Why do you need to take/release the lock around *each* register access? Isn't that lock constant for a given CPU? > + } > + } > +} > + > +static int plic_irq_suspend(void) > +{ > + unsigned int i, cpu; > + u32 __iomem *reg; > + > + for (i =3D 0; i < priv_data->nr_irqs; i++) > + priv_data->priority_reg[i] =3D > + readl(priv_data->regs + PRIORITY_BASE + i * PRIORITY_PER_ID); > + > + for_each_cpu(cpu, cpu_present_mask) { > + struct plic_handler *handler =3D per_cpu_ptr(&plic_handlers, cpu); > + > + if (!handler->present) > + continue; > + > + for (i =3D 0; i < DIV_ROUND_UP(priv_data->nr_irqs, 32); i++) { > + reg =3D handler->enable_base + i * sizeof(u32); > + raw_spin_lock(&handler->enable_lock); > + handler->enable_reg[i] =3D readl(reg); > + raw_spin_unlock(&handler->enable_lock); Same remarks. M. --=20 Without deviation from the norm, progress is not possible.