[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