riscv interrupt-handling

95 views
Skip to first unread message

Mikko Saari

unread,
Jul 11, 2023, 7:59:33 AM7/11/23
to RISC-V SW Dev
       Hello! In earlier Linux riscv-patches (ultraembedded 4.20-kernel) there was interrupt handling implemented by following way in "linux/arch/riscv/kernel/irq.c".  However, in current Linux version (6.5) there is no corresponding   csr_clear(sip, 1 << INTERRUPT_CAUSE_EXTERNAL)-call anywhere, at least I haven't been able to find it.
-----------------------------------------------------------------------------kernel 4.20
 case INTERRUPT_CAUSE_EXTERNAL:
#ifdef CONFIG_XILINX_INTC
                {
                  unsigned int irq;
                        irq = xintc_get_irq();
                next_irq:
                        BUG_ON(!irq);
                        generic_handle_irq(irq);

                        irq = xintc_get_irq();
                        if (irq != -1U) {
pr_debug("next irq: %d\n", irq);
goto next_irq;
}
}
                csr_clear(sip, 1 << INTERRUPT_CAUSE_EXTERNAL);
#else
      handle_arch_irq(regs);
#endif
      break;
default:
                panic("unexpected interrupt cause");
-------------------------------------------------------------------------------

Instead I did a "quick and dirty" -fix to the file "linux/drivers/irqchip/irq-xilinx-intc.c" and put the corresponding call     csr_clear(CSR_SIP, IE_EIE);
to function
------------------------------------------------------------------------kernel 6.5
 static void xil_intc_irq_handler(struct irq_desc *desc)
{
    struct irq_chip *chip = irq_desc_get_chip(desc);
    struct xintc_irq_chip *irqc;
    u32 pending;


    irqc = irq_data_get_irq_handler_data(&desc->irq_data);
    chained_irq_enter(chip, desc);
    do {
        pending = xintc_get_irq_local(irqc);
        if (pending == 0)
            break;
        generic_handle_irq(pending);
    } while (true);
    chained_irq_exit(chip, desc);
    csr_clear(CSR_SIP, IE_EIE);
}
---------------------------------------------------------------------------
Now the interrupts are not pending and the system is not halted as it was before for example while using spidevtest before the modifications. The call csr_clear() clears pending interrupts that would otherwise halt the Linux kernel.
I wonder if this should be fixed somehow more elegantly? I am grateful for any answers.
Best Regards, Mikko Saari

Tommy Murphy

unread,
Jul 11, 2023, 8:36:57 AM7/11/23
to Mikko Saari, RISC-V SW Dev
Have you tried the Linux Kernel Mailing List for info about this issue and change?

Mikko Saari

unread,
Jul 11, 2023, 8:49:03 AM7/11/23
to RISC-V SW Dev, tommy_...@hotmail.com, Mikko Saari
No, I didn't have courage yet , but maybe should :)  That could be the best way to progress, since it is very kernel-specific problem, the implementation of the "/linux/arch/riscv/kernel/irq.c" has been changing quite often.  Trying to
find the correct implementation in kernel versions 4.20, 5.00, 5.10 and 6.5, it seems the oldest implementation is the closest to correct one in this detail. But let's see
BR, Mikko 
Reply all
Reply to author
Forward
0 new messages