From 8570b938444d92d4557df7e03bd9cb83fdd4c2b1 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 8 Jun 2026 18:22:53 +0530 Subject: [PATCH] lib: sbi_irqchip: Allow irqchip drivers advertise capabilities Extend struct sbi_irqchip_device to allow irqchip drivers advertise interrupt controller capabilities (such as wired interrupt, MSIs, etc). This further allows other parts of OpenSBI to lookup irqchip devices based on capabilities. Signed-off-by: Anup Patel Link: https://lore.kernel.org/r/20260608125257.3220114-2-anup.patel@oss.qualcomm.com Signed-off-by: Anup Patel --- include/sbi/sbi_irqchip.h | 11 ++++++++++- lib/sbi/sbi_irqchip.c | 20 ++++++++++++++++++++ lib/utils/irqchip/aplic.c | 1 + lib/utils/irqchip/imsic.c | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/sbi/sbi_irqchip.h b/include/sbi/sbi_irqchip.h index 8e7ff573..e778d747 100644 --- a/include/sbi/sbi_irqchip.h +++ b/include/sbi/sbi_irqchip.h @@ -31,12 +31,17 @@ struct sbi_irqchip_device { /** Internal data of all hardware interrupts of this irqchip (private) */ struct sbi_irqchip_hwirq_data *hwirqs; - /** List of interrupt handlers */ + /** List of interrupt handlers (private) */ struct sbi_dlist handler_list; /** Unique ID of this irqchip */ u32 id; + /** Capabilities of this irqchip */ +#define SBI_IRQCHIP_CAPS_WIRED BIT(0) +#define SBI_IRQCHIP_CAPS_MSI BIT(1) + unsigned long caps; + /** Number of hardware IRQs of this irqchip */ u32 num_hwirq; @@ -141,6 +146,10 @@ int sbi_irqchip_register_reserved(struct sbi_irqchip_device *chip, int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip, u32 first_hwirq, u32 num_hwirq); +/** Find an irqchip device based on matching capabilities */ +struct sbi_irqchip_device *sbi_irqchip_find_device_by_caps(unsigned long caps, + struct sbi_irqchip_device *first); + /** Find an irqchip device based on unique ID */ struct sbi_irqchip_device *sbi_irqchip_find_device(u32 id); diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c index 5880872c..6d0df02e 100644 --- a/lib/sbi/sbi_irqchip.c +++ b/lib/sbi/sbi_irqchip.c @@ -408,6 +408,26 @@ int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip, return 0; } +struct sbi_irqchip_device *sbi_irqchip_find_device_by_caps(unsigned long caps, + struct sbi_irqchip_device *first) +{ + struct sbi_irqchip_device *chip; + bool found = false; + + sbi_list_for_each_entry(chip, &irqchip_list, node) { + if (!found) { + if (first == chip) + found = true; + else + continue; + } + if ((chip->caps & caps) == caps) + return chip; + } + + return NULL; +} + struct sbi_irqchip_device *sbi_irqchip_find_device(u32 id) { struct sbi_irqchip_device *chip; diff --git a/lib/utils/irqchip/aplic.c b/lib/utils/irqchip/aplic.c index ec69c82b..6c63620e 100644 --- a/lib/utils/irqchip/aplic.c +++ b/lib/utils/irqchip/aplic.c @@ -307,6 +307,7 @@ int aplic_cold_irqchip_init(struct aplic_data *aplic) /* Register irqchip device */ aplic->irqchip.id = aplic->unique_id; + aplic->irqchip.caps = SBI_IRQCHIP_CAPS_WIRED; aplic->irqchip.num_hwirq = aplic->num_source + 1; rc = sbi_irqchip_add_device(&aplic->irqchip); if (rc) diff --git a/lib/utils/irqchip/imsic.c b/lib/utils/irqchip/imsic.c index 521d17fe..0e7f3e6b 100644 --- a/lib/utils/irqchip/imsic.c +++ b/lib/utils/irqchip/imsic.c @@ -400,6 +400,7 @@ int imsic_cold_irqchip_init(struct imsic_data *imsic) /* Register irqchip device */ imsic_device.id = imsic->unique_id; + imsic_device.caps = SBI_IRQCHIP_CAPS_MSI; imsic_device.num_hwirq = imsic->num_ids + 1; sbi_hartmask_set_all(&imsic_device.target_harts); rc = sbi_irqchip_add_device(&imsic_device);