From d861447b0b0297db5fbe28878f8568a93fcfa965 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 23 Apr 2026 10:53:37 +0530 Subject: [PATCH] lib: sbi_irqchip: Allow marking hardware interrupts as reserved 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 Link: https://lore.kernel.org/r/20260423052339.356900-5-anup.patel@oss.qualcomm.com Signed-off-by: Anup Patel --- 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);