[tip: irq/drivers] irqchip/starfive: Increase the interrupt source number up to 64
From: tip-bot2 for Mason Huo
Date: Thu Apr 30 2026 - 06:57:58 EST
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 5d1b12880fd878f315f41ac5dd19fd9fb476e7a0
Gitweb: https://git.kernel.org/tip/5d1b12880fd878f315f41ac5dd19fd9fb476e7a0
Author: Mason Huo <mason.huo@xxxxxxxxxxxxxxxx>
AuthorDate: Wed, 15 Apr 2026 23:47:50 -07:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Thu, 30 Apr 2026 12:53:05 +02:00
irqchip/starfive: Increase the interrupt source number up to 64
StarFive JHB100 SoC interrupt controller actually supports 64 interrupt
sources, the original code only supported up to 32. now it is extended to 64.
Also use guard(raw_spinlock) to automatically release spinlocks.
Signed-off-by: Mason Huo <mason.huo@xxxxxxxxxxxxxxxx>
Signed-off-by: Changhuang Liang <changhuang.liang@xxxxxxxxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Link: https://patch.msgid.link/20260416064751.632138-5-changhuang.liang@xxxxxxxxxxxxxxxx
---
drivers/irqchip/irq-starfive-jhb100-intc.c | 47 ++++++++++++---------
1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/drivers/irqchip/irq-starfive-jhb100-intc.c b/drivers/irqchip/irq-starfive-jhb100-intc.c
index c33229b..b3d86bd 100644
--- a/drivers/irqchip/irq-starfive-jhb100-intc.c
+++ b/drivers/irqchip/irq-starfive-jhb100-intc.c
@@ -19,10 +19,11 @@
#include <linux/reset.h>
#include <linux/spinlock.h>
-#define STARFIVE_INTC_SRC0_CLEAR 0x10
-#define STARFIVE_INTC_SRC0_MASK 0x14
-#define STARFIVE_INTC_SRC0_INT 0x1c
+#define STARFIVE_INTC_SRC_CLEAR(n) (0x10 + ((n) * 0x20))
+#define STARFIVE_INTC_SRC_MASK(n) (0x14 + ((n) * 0x20))
+#define STARFIVE_INTC_SRC_INT(n) (0x1c + ((n) * 0x20))
+#define STARFIVE_INTC_NUM 2
#define STARFIVE_INTC_SRC_IRQ_NUM 32
struct starfive_irq_chip {
@@ -54,19 +55,25 @@ static void starfive_intc_bit_clear(struct starfive_irq_chip *irqc,
static void starfive_intc_unmask(struct irq_data *d)
{
struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);
+ int i, bitpos;
- raw_spin_lock(&irqc->lock);
- starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC0_MASK, BIT(d->hwirq));
- raw_spin_unlock(&irqc->lock);
+ i = d->hwirq / STARFIVE_INTC_SRC_IRQ_NUM;
+ bitpos = d->hwirq % STARFIVE_INTC_SRC_IRQ_NUM;
+
+ guard(raw_spinlock)(&irqc->lock);
+ starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC_MASK(i), BIT(bitpos));
}
static void starfive_intc_mask(struct irq_data *d)
{
struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);
+ int i, bitpos;
+
+ i = d->hwirq / STARFIVE_INTC_SRC_IRQ_NUM;
+ bitpos = d->hwirq % STARFIVE_INTC_SRC_IRQ_NUM;
- raw_spin_lock(&irqc->lock);
- starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC0_MASK, BIT(d->hwirq));
- raw_spin_unlock(&irqc->lock);
+ guard(raw_spinlock)(&irqc->lock);
+ starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC_MASK(i), BIT(bitpos));
}
static struct irq_chip intc_dev = {
@@ -98,16 +105,19 @@ static void starfive_intc_irq_handler(struct irq_desc *desc)
chained_irq_enter(chip, desc);
- value = ioread32(irqc->base + STARFIVE_INTC_SRC0_INT);
- while (value) {
- hwirq = ffs(value) - 1;
+ for (int i = 0; i < STARFIVE_INTC_NUM; i++) {
+ value = ioread32(irqc->base + STARFIVE_INTC_SRC_INT(i));
+ while (value) {
+ hwirq = ffs(value) - 1;
- generic_handle_domain_irq(irqc->domain, hwirq);
+ generic_handle_domain_irq(irqc->domain,
+ hwirq + i * STARFIVE_INTC_SRC_IRQ_NUM);
- starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC0_CLEAR, BIT(hwirq));
- starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC0_CLEAR, BIT(hwirq));
+ starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC_CLEAR(i), BIT(hwirq));
+ starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC_CLEAR(i), BIT(hwirq));
- __clear_bit(hwirq, &value);
+ __clear_bit(hwirq, &value);
+ }
}
chained_irq_exit(chip, desc);
@@ -140,7 +150,8 @@ static int starfive_intc_probe(struct platform_device *pdev, struct device_node
raw_spin_lock_init(&irqc->lock);
- irqc->domain = irq_domain_create_linear(of_fwnode_handle(intc), STARFIVE_INTC_SRC_IRQ_NUM,
+ irqc->domain = irq_domain_create_linear(of_fwnode_handle(intc),
+ STARFIVE_INTC_SRC_IRQ_NUM * STARFIVE_INTC_NUM,
&starfive_intc_domain_ops, irqc);
if (!irqc->domain)
return dev_err_probe(&pdev->dev, -EINVAL, "Unable to create IRQ domain\n");
@@ -155,7 +166,7 @@ static int starfive_intc_probe(struct platform_device *pdev, struct device_node
irqc);
dev_info(&pdev->dev, "Interrupt controller register, nr_irqs %d\n",
- STARFIVE_INTC_SRC_IRQ_NUM);
+ STARFIVE_INTC_SRC_IRQ_NUM * STARFIVE_INTC_NUM);
retain_and_null_ptr(irqc);
return 0;