From nobody Thu Oct 2 06:29:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A43E218A6A5; Mon, 22 Sep 2025 08:28:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758529724; cv=none; b=VkFd8tCSxOKc5GQJ40Jb8aH8LRq1GdVSVEfon/Nn0oqa4+E8vFN0SAp92Zll2hV4Px+QEp3U/BjHumLIY53uFAX4ZLD5D2usC5daNYbMAXJyOVDsckgUUHJLqjdcZon8mr7/BpsuD7nTLdxxd0j+Rjqtzby+qm7+LSE6K5kJX7g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758529724; c=relaxed/simple; bh=PNhSU//BPW9YLsi7ZBnfD4jFD/thyKEGeB39qdpvnP4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bRtZVb+bHPWY2K3EUBZJsg9D6dS2JBcDSpZUnn9gVndQ4PsQ+9e92UrymyVZWdVHuB+V8xwrnmvPqLJZ599jzG9ThLofdAkt7bOnQ0i+8E92XTiTxU2SXMurJzds15e0o5hunZ1fXSnyyxZMGEvdPHvSoiAPqSH7H3gQzRPBjnU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z+lJwkSs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Z+lJwkSs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C078C4CEF0; Mon, 22 Sep 2025 08:28:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1758529724; bh=PNhSU//BPW9YLsi7ZBnfD4jFD/thyKEGeB39qdpvnP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z+lJwkSsGLQVPnmRu+p9IFTSUGl1hxXx80G0nvSBLiVLyqNil6qdwedjXcI+e9KiM 4n6YUIbEqL7ChaDIpOtgiGmOxlVZliCG+40rD2Dz1Drp6O+wgmgPl6kVSxFgULxZ1D +wkg3AzAhEVaCaK4O5zN1Amf8dV08pKi4SNMhewzCEflaNHnWgImz0O834aj1ZcLW9 UszsWI2n8ZesNBphQ5K1sUAPgHbzGJ5K0Ryb50fTMIifywQ7ATgiGxMx9aGmznSgsV soCm2tB4NzZPBNVPbFKKdNbx2ef6VtYAdsC8uYrutmscXeq43QJyslWy3a4LTt73Ep RA9JoBcgbYRHA== Received: from sofa.misterjones.org ([185.219.108.64] helo=valley-girl.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1v0bub-00000008Kds-40yl; Mon, 22 Sep 2025 08:28:42 +0000 From: Marc Zyngier To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org Cc: Thomas Gleixner , Mark Rutland , Will Deacon , "Rafael J. Wysocki" , Rob Herring , Saravana Kannan , Greg Kroah-Hartman , Sven Peter , Janne Grunau , Suzuki K Poulose , James Clark , Jonathan Cameron Subject: [PATCH v3 01/26] irqdomain: Add firmware info reporting interface Date: Mon, 22 Sep 2025 09:28:08 +0100 Message-ID: <20250922082833.2038905-2-maz@kernel.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20250922082833.2038905-1-maz@kernel.org> References: <20250922082833.2038905-1-maz@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org, tglx@linutronix.de, mark.rutland@arm.com, will@kernel.org, rafael@kernel.org, robh@kernel.org, saravanak@google.com, gregkh@linuxfoundation.org, sven@kernel.org, j@jannau.net, suzuki.poulose@arm.com, james.clark@linaro.org, jonathan.cameron@huawei.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Content-Type: text/plain; charset="utf-8" Allow an irqdomain callback to report firmware-provided information that is otherwise not available in a generic way. This is reported using a new data structure (struct irq_fwspec_info). This callback is optional and the only information that can be reported currently is the affinity of an interrupt. However, the containing structure is designed to be extensible, allowing other potentially relevant information to be reported in the future. Signed-off-by: Marc Zyngier --- include/linux/irqdomain.h | 27 +++++++++++++++++++++++++++ kernel/irq/irqdomain.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 4a86e6b915dd6..9d6a5e99394fa 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -44,6 +44,23 @@ struct irq_fwspec { u32 param[IRQ_DOMAIN_IRQ_SPEC_PARAMS]; }; =20 +/** + * struct irq_fwspec_info - firmware provided IRQ information structure + * + * @flags: Information validity flags + * @cpumask: Affinity mask for this interrupt + * + * This structure reports firmware-specific information about an + * interrupt. The only significant information is the affinity of a + * per-CPU interrupt, but this is designed to be extended as required. + */ +struct irq_fwspec_info { + unsigned long flags; + const struct cpumask *affinity; +}; + +#define IRQ_FWSPEC_INFO_AFFINITY_VALID BIT(0) + /* Conversion function from of_phandle_args fields to fwspec */ void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args, unsigned int count, struct irq_fwspec *fwspec); @@ -69,6 +86,9 @@ void of_phandle_args_to_fwspec(struct device_node *np, co= nst u32 *args, * @translate: Given @fwspec, decode the hardware irq number (@out_hwirq) = and * linux irq type value (@out_type). This is a generalised @xlate * (over struct irq_fwspec) and is preferred if provided. + * @get_fwspec_info: + * Given @fwspec, report additional firmware-provided information in + * @info. Optional. * @debug_show: For domains to show specific data for an interrupt in debu= gfs. * * Functions below are provided by the driver and called whenever a new ma= pping @@ -96,6 +116,7 @@ struct irq_domain_ops { void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data); int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *out_hwirq, unsigned int *out_type); + int (*get_fwspec_info)(struct irq_fwspec *fwspec, struct irq_fwspec_info = *info); #endif #ifdef CONFIG_GENERIC_IRQ_DEBUGFS void (*debug_show)(struct seq_file *m, struct irq_domain *d, @@ -602,6 +623,8 @@ void irq_domain_free_irqs_parent(struct irq_domain *dom= ain, unsigned int irq_bas =20 int irq_domain_disconnect_hierarchy(struct irq_domain *domain, unsigned in= t virq); =20 +int irq_populate_fwspec_info(struct irq_fwspec *fwspec, struct irq_fwspec_= info *info); + static inline bool irq_domain_is_hierarchy(struct irq_domain *domain) { return domain->flags & IRQ_DOMAIN_FLAG_HIERARCHY; @@ -685,6 +708,10 @@ static inline bool irq_domain_is_msi_device(struct irq= _domain *domain) return false; } =20 +static inline int irq_populate_fwspec_info(struct irq_fwspec *fwspec, stru= ct irq_fwspec_info *info) +{ + return -EINVAL; +} #endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */ =20 #ifdef CONFIG_GENERIC_MSI_IRQ diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index dc473faadcc81..2652c4cfd877f 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -867,13 +867,9 @@ void of_phandle_args_to_fwspec(struct device_node *np,= const u32 *args, } EXPORT_SYMBOL_GPL(of_phandle_args_to_fwspec); =20 -unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) +static struct irq_domain *fwspec_to_domain(struct irq_fwspec *fwspec) { struct irq_domain *domain; - struct irq_data *irq_data; - irq_hw_number_t hwirq; - unsigned int type =3D IRQ_TYPE_NONE; - int virq; =20 if (fwspec->fwnode) { domain =3D irq_find_matching_fwspec(fwspec, DOMAIN_BUS_WIRED); @@ -883,6 +879,32 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwsp= ec *fwspec) domain =3D irq_default_domain; } =20 + return domain; +} + +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +int irq_populate_fwspec_info(struct irq_fwspec *fwspec, struct irq_fwspec_= info *info) +{ + struct irq_domain *domain =3D fwspec_to_domain(fwspec); + + memset(info, 0, sizeof(*info)); + + if (!domain || !domain->ops->get_fwspec_info) + return 0; + + return domain->ops->get_fwspec_info(fwspec, info); +} +#endif + +unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) +{ + unsigned int type =3D IRQ_TYPE_NONE; + struct irq_domain *domain; + struct irq_data *irq_data; + irq_hw_number_t hwirq; + int virq; + + domain =3D fwspec_to_domain(fwspec); if (!domain) { pr_warn("no irq domain found for %s !\n", of_node_full_name(to_of_node(fwspec->fwnode))); --=20 2.47.3