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 */
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,
+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)
{
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);
if (h->callback)
rc = h->callback(hwirq, h->priv);
if (chip->hwirq_eoi)
@@ -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,
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 *opaque), void *priv)
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)
{
+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)
{
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);