[PATCH 4/6] lib: sbi_irqchip: Allow marking hardware interrupts as reserved
Anup Patel
anup.patel at oss.qualcomm.com
Wed Apr 22 22:23:37 PDT 2026
Some of the hardware interrupts may be special so allow irqchip
drivers to make these hardware interrupts as reserved. Introduce
sbi_irqchip_register_reserved() for this purpose.
Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
---
include/sbi/sbi_irqchip.h | 6 +++++-
lib/sbi/sbi_irqchip.c | 44 +++++++++++++++++++++++++++++----------
lib/utils/irqchip/imsic.c | 7 ++++++-
3 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/include/sbi/sbi_irqchip.h b/include/sbi/sbi_irqchip.h
index 9035dcef..880ff49f 100644
--- a/include/sbi/sbi_irqchip.h
+++ b/include/sbi/sbi_irqchip.h
@@ -101,7 +101,11 @@ int sbi_irqchip_set_raw_handler(struct sbi_irqchip_device *chip, u32 hwirq,
/** Register a hardware interrupt handler */
int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags,
- int (*callback)(u32 hwirq, void *opaque), void *opaque);
+ int (*callback)(u32 hwirq, void *priv), void *priv);
+
+/** Register a hardware interrupts as reserved */
+int sbi_irqchip_register_reserved(struct sbi_irqchip_device *chip,
+ u32 first_hwirq, u32 num_hwirq);
/** Unregister a hardware interrupt handler */
int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index ea684303..15ea2211 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -108,13 +108,14 @@ static struct sbi_irqchip_handler *sbi_irqchip_find_handler(struct sbi_irqchip_d
int sbi_irqchip_raw_handler_default(struct sbi_irqchip_device *chip, u32 hwirq)
{
struct sbi_irqchip_handler *h;
- int rc;
+ int rc = SBI_OK;
if (!chip || chip->num_hwirq <= hwirq)
return SBI_EINVAL;
h = sbi_irqchip_find_handler(chip, hwirq);
- rc = h->callback(hwirq, h->priv);
+ if (h->callback)
+ rc = h->callback(hwirq, h->priv);
if (chip->hwirq_eoi)
chip->hwirq_eoi(chip, hwirq);
@@ -135,20 +136,14 @@ int sbi_irqchip_set_raw_handler(struct sbi_irqchip_device *chip, u32 hwirq,
return 0;
}
-int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
- u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags,
- int (*callback)(u32 hwirq, void *opaque), void *priv)
+static int __sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
+ u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags,
+ int (*callback)(u32 hwirq, void *priv), void *priv)
{
struct sbi_irqchip_handler *h, *th, *nh;
u32 i, j;
int rc;
- if (!chip || !num_hwirq || !callback)
- return SBI_EINVAL;
- if (chip->num_hwirq <= first_hwirq ||
- chip->num_hwirq <= (first_hwirq + num_hwirq - 1))
- return SBI_EBAD_RANGE;
-
for (i = first_hwirq; i < (first_hwirq + num_hwirq); i++) {
h = sbi_irqchip_find_handler(chip, i);
if (h)
@@ -198,6 +193,33 @@ int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
return 0;
}
+int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
+ u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags,
+ int (*callback)(u32 hwirq, void *priv), void *priv)
+{
+ if (!chip || !num_hwirq || !callback)
+ return SBI_EINVAL;
+ if (chip->num_hwirq <= first_hwirq ||
+ chip->num_hwirq <= (first_hwirq + num_hwirq - 1))
+ return SBI_EBAD_RANGE;
+
+ return __sbi_irqchip_register_handler(chip, first_hwirq, num_hwirq, hwirq_flags,
+ callback, priv);
+}
+
+int sbi_irqchip_register_reserved(struct sbi_irqchip_device *chip,
+ u32 first_hwirq, u32 num_hwirq)
+{
+ if (!chip || !num_hwirq)
+ return SBI_EINVAL;
+ if (chip->num_hwirq <= first_hwirq ||
+ chip->num_hwirq <= (first_hwirq + num_hwirq - 1))
+ return SBI_EBAD_RANGE;
+
+ return __sbi_irqchip_register_handler(chip, first_hwirq, num_hwirq,
+ SBI_HWIRQ_FLAGS_NONE, NULL, NULL);
+}
+
int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
u32 first_hwirq, u32 num_hwirq)
{
diff --git a/lib/utils/irqchip/imsic.c b/lib/utils/irqchip/imsic.c
index 877255f8..521d17fe 100644
--- a/lib/utils/irqchip/imsic.c
+++ b/lib/utils/irqchip/imsic.c
@@ -348,7 +348,7 @@ int imsic_data_check(struct imsic_data *imsic)
static int imsic_hwirq_setup(struct sbi_irqchip_device *chip, u32 hwirq, u32 hwirq_flags)
{
- if (!hwirq || hwirq == IMSIC_IPI_ID || hwirq_flags != SBI_HWIRQ_FLAGS_NONE)
+ if (hwirq_flags != SBI_HWIRQ_FLAGS_NONE)
return SBI_ENOTSUPP;
return 0;
}
@@ -406,6 +406,11 @@ int imsic_cold_irqchip_init(struct imsic_data *imsic)
if (rc)
return rc;
+ /* Mark hwirq 0 and IPI hwirq as reserved */
+ rc = sbi_irqchip_register_reserved(&imsic_device, 0, IMSIC_IPI_ID + 1);
+ if (rc)
+ return rc;
+
/* Register IPI device */
sbi_ipi_add_device(&imsic_ipi_device);
--
2.43.0
More information about the opensbi
mailing list