alistair23-linux/arch/mips/kernel
Maciej W. Rozycki afddce0cc9 MIPS: R4k clock source initialization bug fix
This is a fix for a bug introduced with commit
447cdf2628, submitted as archived here:
http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20080312235002.c717dde3.yoichi_yuasa%40tripeaks.co.jp
regrettably with no further explanation.

The issue is with the CP0 Count register read erratum present on R4000 and
some R4400 processors.  If this erratum is present, then a read from this
register that happens around the time it reaches the value stored in the
CP0 Compare register causes a CP0 timer interrupt that is supposed to
happen when the values in the two registers match to be missed.  The
implication for the chips affected is the CP0 timer can be used either as
a source of a timer interrupt (a clock event) or as a source of a
high-resolution counter (a clock source), but not both at a time.

The erratum does not affect timer interrupt operation itself, because in
this case the CP0 Count register is only read while the timer interrupt
has already been raised, while high-resolution counter references happen
at random times.

Additionally some systems apparently have issues with the timer interrupt
line being routed externally and not following the usual CP0 Count/Compare
semantics.  In this case we don't want to use the R4k clock event.

We've meant to address the erratum and the timer interrupt routing issue
in time_init, however the commit referred to above broke our solution.
What we currently have is we enable the R4k clock source if the R4k clock
event initialization has succeeded (the timer is present and has no timer
interrupt routing issue) or there is no CP0 Count register read erratum.
Which gives the following boolean matrix:

clock event | count erratum => clock source
------------+---------------+--------------
     0      |       0       |      1 (OK)
     0      |       1       |      0 (bug!) -> no interference, could use
     1      |       0       |      1 (OK)
     1      |       1       |      1 (bug!) -> can't use, interference

What we want instead is to enable the R4k clock source if there is no CP0
Count register read erratum (obviously) or the R4k clock event
initialization has *failed* -- because in the latter case we won't be
using the timer interrupt anyway, so we don't care about any interference
CP0 Count reads might cause with the interrupt.  This corresponds to the
following boolean matrix:

clock event | count erratum => clock source
------------+---------------+--------------
     0      |       0       |      1
     0      |       1       |      1
     1      |       0       |      1
     1      |       1       |      0

This is implemented here, effectively reverting the problematic commit,
and a short explanation is given next to code modified so that the
rationale is known to future readers and confusion is prevented from
happening here again.

It is worth noting that mips_clockevent_init returns 0 upon success while
cpu_has_mfc0_count_bug returns 0 upon failure.  This is because the former
function returns an error code while the latter returns a boolean value.
To signify the difference I have therefore chosen to compare the result of
the former call explicitly against 0.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/5799/
2013-09-03 14:44:02 +02:00
..
.gitignore
8250-platform.c
asm-offsets.c MIPS: r4k,octeon,r2300: stack protector: change canary per task 2013-07-01 15:10:52 +02:00
binfmt_elfn32.c MIPS: Compat: Fix cputime_to_timeval() arguments in compat binfmt_elf. 2013-06-06 16:11:26 +02:00
binfmt_elfo32.c MIPS: Compat: Fix cputime_to_timeval() arguments in compat binfmt_elf. 2013-06-06 16:11:26 +02:00
bmips_vec.S MIPS: BMIPS: fix slave CPU booting when physical CPU is not 0 2013-07-30 18:54:29 +02:00
branch.c MIPS: Cleanup indentation and whitespace 2013-07-01 15:10:57 +02:00
cevt-bcm1480.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
cevt-ds1287.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
cevt-gic.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
cevt-gt641xx.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
cevt-r4k.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
cevt-sb1250.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
cevt-smtc.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
cevt-txx9.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
cpu-bugs64.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
cpu-probe.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
crash.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
crash_dump.c mips: remove savemaxmem parameter setup 2013-07-03 16:08:03 -07:00
csrc-bcm1480.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
csrc-gic.c MIPS: Refactor GIC clocksource code. 2013-05-09 17:55:20 +02:00
csrc-ioasic.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
csrc-powertv.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
csrc-r4k.c
csrc-sb1250.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
early_printk.c early_printk: consolidate random copies of identical code 2013-04-29 18:28:13 -07:00
entry.S
ftrace.c MIPS: ftrace: Add missing CONFIG_DYNAMIC_FTRACE 2013-06-10 18:15:18 +02:00
genex.S MIPS: Idle: Break r4k_wait into two functions and fix it. 2013-05-22 01:34:28 +02:00
gpio_txx9.c
head.S MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
i8253.c
i8259.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
idle.c MIPS: Alchemy: fix wait function 2013-06-10 17:59:46 +02:00
irq-gic.c MIPS: GIC: Fix gic_set_affinity infinite loop 2013-07-01 15:10:56 +02:00
irq-gt641xx.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
irq-msc01.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
irq-rm7000.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
irq.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
irq_cpu.c Merge branch 'mips-next-3.9' of git://git.linux-mips.org/pub/scm/john/linux-john into mips-for-linux-next 2013-02-21 12:51:33 +01:00
irq_txx9.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
jump_label.c
kgdb.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
kprobes.c kprobes/mips: Fix to check double free of insn slot 2013-05-22 12:48:30 +02:00
linux32.c unify compat fanotify_mark(2), switch to COMPAT_SYSCALL_DEFINE 2013-05-09 13:46:38 -04:00
machine_kexec.c
Makefile MIPS: Consolidate idle loop / WAIT instruction support in a single file. 2013-05-22 01:34:25 +02:00
mcount.S MIPS: kernel: mcount.S: Drop FRAME_POINTER codepath 2013-06-11 15:19:51 +02:00
mips-mt-fpaff.c sched: Rename sched.c as sched/core.c in comments and Documentation 2013-06-19 12:58:42 +02:00
mips-mt.c
mips_ksyms.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
mips_machine.c MIPS: move mips_{set,get}_machine_name() to a more generic place 2013-05-08 01:19:07 +02:00
module-rela.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
module.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
octeon_switch.S MIPS: r4k,octeon,r2300: stack protector: change canary per task 2013-07-01 15:10:52 +02:00
perf_event.c
perf_event_mipsxx.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
proc.c MIPS: Get rid of MIPS I flag and test macros. 2013-07-01 15:10:56 +02:00
process.c MIPS: Fix typos and cleanup comment 2013-07-01 15:10:57 +02:00
prom.c MIPS: using strlcpy() instead of strncpy() 2013-06-10 18:01:26 +02:00
ptrace.c MIPS: Implement HAVE_CONTEXT_TRACKING. 2013-06-10 18:02:30 +02:00
ptrace32.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
r4k_fpu.S
r4k_switch.S MIPS: r4k,octeon,r2300: stack protector: change canary per task 2013-07-01 15:10:52 +02:00
r2300_fpu.S MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
r2300_switch.S MIPS: r4k,octeon,r2300: stack protector: change canary per task 2013-07-01 15:10:52 +02:00
r6000_fpu.S
relocate_kernel.S MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
reset.c
rtlx.c MIPS: Fix rtlx build error. 2013-06-21 18:07:03 +02:00
scall32-o32.S Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-07-13 14:52:21 -07:00
scall64-64.S MIPS: Cleanup flags in syscall flags handlers. 2013-06-10 18:01:26 +02:00
scall64-n32.S MIPS: Cleanup flags in syscall flags handlers. 2013-06-10 18:01:26 +02:00
scall64-o32.S MIPS: Cleanup flags in syscall flags handlers. 2013-06-10 18:01:26 +02:00
setup.c MIPS: add detect_memory_region() 2013-05-08 01:19:11 +02:00
signal-common.h
signal.c MIPS: Implement HAVE_CONTEXT_TRACKING. 2013-06-10 18:02:30 +02:00
signal32.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-03-02 07:44:16 -08:00
signal_n32.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-03-02 07:44:16 -08:00
smp-bmips.c MIPS: BMIPS: fix hardware interrupt routing for boot CPU != 0 2013-08-05 13:35:18 +02:00
smp-cmp.c MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
smp-mt.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
smp-up.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
smp.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
smtc-asm.S MIPS: microMIPS: Add support for exception handling. 2013-05-09 17:55:18 +02:00
smtc-proc.c mips: single_open() leaks 2013-05-05 00:10:21 -04:00
smtc.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
spinlock_test.c
spram.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
stacktrace.c
sync-r4k.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00
syscall.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-03-02 07:44:16 -08:00
time.c MIPS: R4k clock source initialization bug fix 2013-09-03 14:44:02 +02:00
topology.c
traps.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-07-19 15:10:01 -07:00
unaligned.c MIPS: Declare emulate_load_store_microMIPS as a static function. 2013-07-01 15:10:57 +02:00
vdso.c
vmlinux.lds.S MIPS: Whitespace cleanup. 2013-02-01 10:00:22 +01:00
vpe.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-03-02 07:44:16 -08:00
watch.c MIPS: Delete __cpuinit/__CPUINIT usage from MIPS code 2013-07-14 19:36:51 -04:00