1

MIPS: cevt-r4k: Don't call get_c0_compare_int if timer irq is installed

This avoids warning:

[    0.118053] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:283

Caused by get_c0_compare_int on secondary CPU.

We also skipped saving IRQ number to struct clock_event_device *cd as
it's never used by clockevent core, as per comments it's only meant
for "non CPU local devices".

Reported-by: Serge Semin <fancer.lancer@gmail.com>
Closes: https://lore.kernel.org/linux-mips/6szkkqxpsw26zajwysdrwplpjvhl5abpnmxgu2xuj3dkzjnvsf@4daqrz4mf44k/
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
Jiaxun Yang 2024-08-13 10:59:08 +01:00 committed by Thomas Bogendoerfer
parent 1cb6ab4464
commit 50f2b98dc8

View File

@ -303,13 +303,6 @@ int r4k_clockevent_init(void)
if (!c0_compare_int_usable()) if (!c0_compare_int_usable())
return -ENXIO; return -ENXIO;
/*
* With vectored interrupts things are getting platform specific.
* get_c0_compare_int is a hook to allow a platform to return the
* interrupt number of its liking.
*/
irq = get_c0_compare_int();
cd = &per_cpu(mips_clockevent_device, cpu); cd = &per_cpu(mips_clockevent_device, cpu);
cd->name = "MIPS"; cd->name = "MIPS";
@ -320,7 +313,6 @@ int r4k_clockevent_init(void)
min_delta = calculate_min_delta(); min_delta = calculate_min_delta();
cd->rating = 300; cd->rating = 300;
cd->irq = irq;
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
cd->set_next_event = mips_next_event; cd->set_next_event = mips_next_event;
cd->event_handler = mips_event_handler; cd->event_handler = mips_event_handler;
@ -332,6 +324,13 @@ int r4k_clockevent_init(void)
cp0_timer_irq_installed = 1; cp0_timer_irq_installed = 1;
/*
* With vectored interrupts things are getting platform specific.
* get_c0_compare_int is a hook to allow a platform to return the
* interrupt number of its liking.
*/
irq = get_c0_compare_int();
if (request_irq(irq, c0_compare_interrupt, flags, "timer", if (request_irq(irq, c0_compare_interrupt, flags, "timer",
c0_compare_interrupt)) c0_compare_interrupt))
pr_err("Failed to request irq %d (timer)\n", irq); pr_err("Failed to request irq %d (timer)\n", irq);