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 <anup.patel@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260423052339.356900-5-anup.patel@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Anup Patel
2026-04-23 10:53:37 +05:30
committed by Anup Patel
parent adb4caf765
commit d861447b0b
3 changed files with 44 additions and 13 deletions
+5 -1
View File
@@ -101,7 +101,11 @@ int sbi_irqchip_set_raw_handler(struct sbi_irqchip_device *chip, u32 hwirq,
/** Register a hardware interrupt handler */ /** Register a hardware interrupt handler */
int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip, int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags, 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 */ /** Unregister a hardware interrupt handler */
int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip, int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
+31 -9
View File
@@ -108,12 +108,13 @@ 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) int sbi_irqchip_raw_handler_default(struct sbi_irqchip_device *chip, u32 hwirq)
{ {
struct sbi_irqchip_handler *h; struct sbi_irqchip_handler *h;
int rc; int rc = SBI_OK;
if (!chip || chip->num_hwirq <= hwirq) if (!chip || chip->num_hwirq <= hwirq)
return SBI_EINVAL; return SBI_EINVAL;
h = sbi_irqchip_find_handler(chip, hwirq); h = sbi_irqchip_find_handler(chip, hwirq);
if (h->callback)
rc = h->callback(hwirq, h->priv); rc = h->callback(hwirq, h->priv);
if (chip->hwirq_eoi) if (chip->hwirq_eoi)
@@ -135,20 +136,14 @@ int sbi_irqchip_set_raw_handler(struct sbi_irqchip_device *chip, u32 hwirq,
return 0; return 0;
} }
int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip, static int __sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags, u32 first_hwirq, u32 num_hwirq, u32 hwirq_flags,
int (*callback)(u32 hwirq, void *opaque), void *priv) int (*callback)(u32 hwirq, void *priv), void *priv)
{ {
struct sbi_irqchip_handler *h, *th, *nh; struct sbi_irqchip_handler *h, *th, *nh;
u32 i, j; u32 i, j;
int rc; 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++) { for (i = first_hwirq; i < (first_hwirq + num_hwirq); i++) {
h = sbi_irqchip_find_handler(chip, i); h = sbi_irqchip_find_handler(chip, i);
if (h) if (h)
@@ -198,6 +193,33 @@ int sbi_irqchip_register_handler(struct sbi_irqchip_device *chip,
return 0; 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, int sbi_irqchip_unregister_handler(struct sbi_irqchip_device *chip,
u32 first_hwirq, u32 num_hwirq) u32 first_hwirq, u32 num_hwirq)
{ {
+6 -1
View File
@@ -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) 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 SBI_ENOTSUPP;
return 0; return 0;
} }
@@ -406,6 +406,11 @@ int imsic_cold_irqchip_init(struct imsic_data *imsic)
if (rc) if (rc)
return 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 */ /* Register IPI device */
sbi_ipi_add_device(&imsic_ipi_device); sbi_ipi_add_device(&imsic_ipi_device);