The Kernel hangs occasionally during boot after "Calibrating delay loop..".
This is caused by the c0_compare_int_usable() routine in cevt-r4k.c
returning false which causes the system to disable the timer and hang later.
The false return happens because the routine is using a series of four calls
to irq_disable_hazard() as a delay while it waits for the timer changes to
propagate to the cp0 cause register. On newer MIPS cores, like the 74K, the
series of irq_disable_hazard() calls turn into ehb instructions and can take
as little as a few clock ticks for all 4 instructions. This is not enough of
a delay, so the routine thinks the timer is not working. This fix uses up
to a max number of cycle counter ticks for the delay and uses
back_to_back_c0_hazard() instead of irq_disable_hazard() to handle the
hazard condition between cp0 writes and cp0 reads.
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/2911/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Consider the following test case:
write_c0_compare(read_c0_count());
Even if the counter doesn't increment during execution, this might not
generate an interrupt until the counter wraps around. The CPU may
perform the comparison each time CP0 COUNT increments, not when CP0
COMPARE is written.
If mips_next_event() is called with a very small delta, and CP0 COUNT
increments during the calculation of "cnt += delta", it is possible
that CP0 COMPARE will be written with the current value of CP0 COUNT.
If this is detected, the function should return -ETIME, to indicate
that the interrupt might not have actually gotten scheduled.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/1836/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Add missing #inclusions of <linux/irq.h> to a whole bunch of files that should
really include it. Note that this can replace #inclusions of <asm/irq.h>.
This is required for the patch to sort out irqflags handling function naming to
compile on MIPS.
The problem is that these files require access to things like setup_irq() -
which isn't available by #including <linux/interrupt.h>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
The 'mult' element of struct clock_event_device must never be wider
than 32-bits. If it were, it would get truncated when used by
clockevent_delta2ns() when this calls do_div().
We can meet this requirement by using clockevent_set_clock() to set
the MULT and SHIFT values.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1253/
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
The MIPS processor is limited to 64 external interrupt sources. Using a
greater number without IRQ sharing requires reading platform-specific
registers. On such platforms, reading the IntCtl register to determine
which interrupt corresponds to a timer interrupt will not work.
On MIPSR2 systems there is a solution - the TI bit in the Cause register,
specifically indicates that a timer interrupt has occured. This patch uses
that bit to detect interrupts for MIPSR2 processors, which may be expected
to work regardless of how the timer interrupt may be routed in the hardware.
Signed-off-by: David VomLehn (dvomlehn@cisco.com)
To: linux-mips@linux-mips.org
Patchwork: http://patchwork.linux-mips.org/patch/804/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Along the lines of d6c585a434, add IRQF_TIMER
flag for all timer interrupts This ensures that timer interrupts won't be
disabled on suspend and not threaded for PREEMPT_RT.
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Some of the were relying into smp.h being dragged in by another header
which of course is fragile. <asm/cpu-info.h> uses smp_processor_id()
only in macros and including smp.h there leads to an include loop, so
don't change cpu-info.h.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
The current mips clock build infrastructure lets a system only use
either the MIPS cp0 counter or a SoC specific timer as a clocksource /
clockevent device.
This patch renames the core cp0 counter clocksource / clockevent functions
from mips_* to r4k_* and updates the wrappers in asm-mips/time.h to
call these renamed functions instead.
Chips which can detect whether it is safe to use a chip-specific timer
can now fall back on the cp0 counter if necessary and possible
(e.g. Alchemy with a follow-on patch).
Existing behaviour is not changed in any way.
Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Impact: change calling convention of existing clock_event APIs
struct clock_event_timer's cpumask field gets changed to take pointer,
as does the ->broadcast function.
Another single-patch change. For safety, we BUG_ON() in
clockevents_register_device() if it's not set.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@elte.hu>
Rework of SMTC support to make it work with the new clock event system,
allowing "tickless" operation, and to make it compatible with the use of
the "wait_irqoff" idle loop. The new clocking scheme means that the
previously optional IPI instant replay mechanism is now required, and has
been made more robust.
Signed-off-by: Kevin D. Kissell <kevink@paralogos.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
The R4000 and R4400 have an errata where if the cp0 count register is read
in the exact moment when it matches the compare register no interrupt will
be generated.
This bug may be triggered if the cp0 count register is being used as
clocksource and the compare interrupt as clockevent. So a simple
workaround is to avoid using the compare for both facilities on the
affected CPUs.
This is different from the workaround suggested in the old errata documents;
at some opportunity probably the official version should be implemented
and tested. Another thing to find out is which processor versions
exactly are affected. I only have errata documents upto R4400 V3.0
available so for the moment the code treats all R4000 and R4400 as broken.
This is potencially a problem for some machines that have no other decent
clocksource available; this workaround will cause them to fall back to
another clocksource, worst case the "jiffies" source.
Try increasingly longer time periods starting of at 0x10 cycles. This
should be fast on hardware and work nicely with emulators.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
The expression "(long)(read_c0_count() - cnt)" can never be a negative
value on 64-bit kernel. Cast to "int" before comparison.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>