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>
This commit is contained in:
Anup Patel
2026-06-08 18:22:53 +05:30
committed by Anup Patel
parent a59c8fb9fb
commit 8570b93844
4 changed files with 32 additions and 1 deletions
+10 -1
View File
@@ -31,12 +31,17 @@ struct sbi_irqchip_device {
/** Internal data of all hardware interrupts of this irqchip (private) */ /** Internal data of all hardware interrupts of this irqchip (private) */
struct sbi_irqchip_hwirq_data *hwirqs; struct sbi_irqchip_hwirq_data *hwirqs;
/** List of interrupt handlers */ /** List of interrupt handlers (private) */
struct sbi_dlist handler_list; struct sbi_dlist handler_list;
/** Unique ID of this irqchip */ /** Unique ID of this irqchip */
u32 id; 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 */ /** Number of hardware IRQs of this irqchip */
u32 num_hwirq; 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, int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
u32 first_hwirq, u32 num_hwirq); 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 */ /** Find an irqchip device based on unique ID */
struct sbi_irqchip_device *sbi_irqchip_find_device(u32 id); struct sbi_irqchip_device *sbi_irqchip_find_device(u32 id);
+20
View File
@@ -408,6 +408,26 @@ int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
return 0; 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 *sbi_irqchip_find_device(u32 id)
{ {
struct sbi_irqchip_device *chip; struct sbi_irqchip_device *chip;
+1
View File
@@ -307,6 +307,7 @@ int aplic_cold_irqchip_init(struct aplic_data *aplic)
/* Register irqchip device */ /* Register irqchip device */
aplic->irqchip.id = aplic->unique_id; aplic->irqchip.id = aplic->unique_id;
aplic->irqchip.caps = SBI_IRQCHIP_CAPS_WIRED;
aplic->irqchip.num_hwirq = aplic->num_source + 1; aplic->irqchip.num_hwirq = aplic->num_source + 1;
rc = sbi_irqchip_add_device(&aplic->irqchip); rc = sbi_irqchip_add_device(&aplic->irqchip);
if (rc) if (rc)
+1
View File
@@ -400,6 +400,7 @@ int imsic_cold_irqchip_init(struct imsic_data *imsic)
/* Register irqchip device */ /* Register irqchip device */
imsic_device.id = imsic->unique_id; imsic_device.id = imsic->unique_id;
imsic_device.caps = SBI_IRQCHIP_CAPS_MSI;
imsic_device.num_hwirq = imsic->num_ids + 1; imsic_device.num_hwirq = imsic->num_ids + 1;
sbi_hartmask_set_all(&imsic_device.target_harts); sbi_hartmask_set_all(&imsic_device.target_harts);
rc = sbi_irqchip_add_device(&imsic_device); rc = sbi_irqchip_add_device(&imsic_device);