summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@oss.qualcomm.com>2026-06-08 18:22:53 +0530
committerAnup Patel <anup@brainfault.org>2026-06-10 18:13:10 +0530
commit8570b938444d92d4557df7e03bd9cb83fdd4c2b1 (patch)
tree4f4f62d3816e9b17ba9ab261c632f9b3214cf0eb
parenta59c8fb9fb0ee4b56268b84cf94d6a5d66ead514 (diff)
downloadopensbi-8570b938444d92d4557df7e03bd9cb83fdd4c2b1.tar.gz
opensbi-8570b938444d92d4557df7e03bd9cb83fdd4c2b1.zip
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 <anup.patel@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260608125257.3220114-2-anup.patel@oss.qualcomm.com Signed-off-by: Anup Patel <anup@brainfault.org>
-rw-r--r--include/sbi/sbi_irqchip.h11
-rw-r--r--lib/sbi/sbi_irqchip.c20
-rw-r--r--lib/utils/irqchip/aplic.c1
-rw-r--r--lib/utils/irqchip/imsic.c1
4 files changed, 32 insertions, 1 deletions
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);