I've run into a problem in linux-3.5-rc1, and I've tracked it down to this patch, MIPS: Move cache setup to setup_arch()., commit 6650df3c380e0db558dbfec63ed860402c6afb2a. On Mon, May 14, 2012 at 6:04 PM, David Daney <ddaney.cavm@xxxxxxxxx> wrote: > From: David Daney <david.daney@xxxxxxxxxx> > > commit 97ce2c88f9ad42e3c60a9beb9fca87abf3639faa (jump-label: initialize > jump-label subsystem much earlier) breaks MIPS. The jump_label_init() > call was moved before trap_init() which is where we initialize > flush_icache_range(). > > In order to be good citizens, we move cache initialization earlier so > that we don't jump through a null flush_icache_range function pointer > when doing the jump label initialization. > > Signed-off-by: David Daney <david.daney@xxxxxxxxxx> > --- > arch/mips/include/asm/setup.h | 3 ++- > arch/mips/kernel/setup.c | 2 ++ > arch/mips/kernel/smp.c | 2 +- > arch/mips/kernel/traps.c | 9 +++++---- > 4 files changed, 10 insertions(+), 6 deletions(-) > > diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h > index 6dce6d8..2560b6b 100644 > --- a/arch/mips/include/asm/setup.h > +++ b/arch/mips/include/asm/setup.h > @@ -14,7 +14,8 @@ extern void *set_vi_handler(int n, vi_handler_t addr); > > extern void *set_except_vector(int n, void *addr); > extern unsigned long ebase; > -extern void per_cpu_trap_init(void); > +extern void per_cpu_trap_init(bool); > +extern void cpu_cache_init(void); > > #endif /* __KERNEL__ */ > > diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c > index c504b21..a53f8ec 100644 > --- a/arch/mips/kernel/setup.c > +++ b/arch/mips/kernel/setup.c > @@ -605,6 +605,8 @@ void __init setup_arch(char **cmdline_p) > > resource_init(); > plat_smp_setup(); > + > + cpu_cache_init(); > } > > unsigned long kernelsp[NR_CPUS]; > diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c > index ba9376b..dc019a1 100644 > --- a/arch/mips/kernel/smp.c > +++ b/arch/mips/kernel/smp.c > @@ -106,7 +106,7 @@ asmlinkage __cpuinit void start_secondary(void) > #endif /* CONFIG_MIPS_MT_SMTC */ > cpu_probe(); > cpu_report(); > - per_cpu_trap_init(); > + per_cpu_trap_init(false); > mips_clockevent_init(); > mp_ops->init_secondary(); > > diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c > index 2b5675b..0ba66c0 100644 > --- a/arch/mips/kernel/traps.c > +++ b/arch/mips/kernel/traps.c > @@ -1538,7 +1538,6 @@ void *set_vi_handler(int n, vi_handler_t addr) > return set_vi_srs_handler(n, addr, 0); > } > > -extern void cpu_cache_init(void); > extern void tlb_init(void); > extern void flush_tlb_handlers(void); > > @@ -1565,7 +1564,7 @@ static int __init ulri_disable(char *s) > } > __setup("noulri", ulri_disable); > > -void __cpuinit per_cpu_trap_init(void) > +void __cpuinit per_cpu_trap_init(bool is_boot_cpu) > { > unsigned int cpu = smp_processor_id(); > unsigned int status_set = ST0_CU0; > @@ -1664,7 +1663,9 @@ void __cpuinit per_cpu_trap_init(void) > #ifdef CONFIG_MIPS_MT_SMTC > if (bootTC) { > #endif /* CONFIG_MIPS_MT_SMTC */ > - cpu_cache_init(); > + /* Boot CPU's cache setup in setup_arch(). */ > + if (!is_boot_cpu) > + cpu_cache_init(); > tlb_init(); > #ifdef CONFIG_MIPS_MT_SMTC > } else if (!secondaryTC) { > @@ -1741,7 +1742,7 @@ void __init trap_init(void) > > if (board_ebase_setup) > board_ebase_setup(); > - per_cpu_trap_init(); > + per_cpu_trap_init(true); > > /* > * Copy the generic exception handlers to their final destination. > -- > 1.7.2.3 I'm running a single-CPU, PMC-Sierra RM7035C-based system. Before applying this patch, cca_setup() in arch/mips/mm/c-r4k.c is called before coherency_setup() (called from rk4_cache_init()). After applying the patch, it is called afterwards. Because coherency_setup() relies on cca_setup() properly setting the variable cca, it won't use the value of cca supplied on the kernel command line. I haven't verified it, but I suspect the same problem will occur with the call to setcoherentio(), also in c-r4k.c. Unfortunately, I don't have the knowledge to formulate a patch to this problem, but I wanted to raise the issue. Shane McDonald