[<prev] [next>] [day] [month] [year] [list]
Message-ID: <0831fc40-267d-f974-8785-d304265837d5@vlsi.fi>
Date: Tue, 11 Jul 2023 16:18:01 +0300
From: Mikko Saari <Mikko.Saari@...i.fi>
To: linux-kernel@...r.kernel.org
Subject: riscv pending interrupts freezes the kernel, fixing by csr_clear-call
Hello Linux! In earlier Linux Risc-V-patches (ultraembedded 4.20-kernel)
there was interrupt handling implemented by following way in
"linux/arch/riscv/kernel/irq.c".
-----------------------------------------------------------------------------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");
-------------------------------------------------------------------------------
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.
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. I am just a beginner in the adventure of the driver
development, and any sensible answer is real help :)
Best Regards, Mikko Saari
Powered by blists - more mailing lists