mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-06-12 22:31:45 +01:00
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:
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user