diff options
Diffstat (limited to 'arch/mips')
53 files changed, 273 insertions, 169 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 09ab87ee6fe..b3e10fdd389 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -288,6 +288,7 @@ config MIPS_MALTA  	select SYS_HAS_CPU_MIPS32_R1  	select SYS_HAS_CPU_MIPS32_R2  	select SYS_HAS_CPU_MIPS64_R1 +	select SYS_HAS_CPU_MIPS64_R2  	select SYS_HAS_CPU_NEVADA  	select SYS_HAS_CPU_RM7000  	select SYS_HAS_EARLY_PRINTK @@ -1423,6 +1424,7 @@ config CPU_SB1  config CPU_CAVIUM_OCTEON  	bool "Cavium Octeon processor"  	depends on SYS_HAS_CPU_CAVIUM_OCTEON +	select ARCH_SPARSEMEM_ENABLE  	select CPU_HAS_PREFETCH  	select CPU_SUPPORTS_64BIT_KERNEL  	select SYS_SUPPORTS_SMP diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index 6210b8d8410..b311be45a72 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -21,6 +21,7 @@ config BCM47XX_BCMA  	select BCMA  	select BCMA_HOST_SOC  	select BCMA_DRIVER_MIPS +	select BCMA_HOST_PCI if PCI  	select BCMA_DRIVER_PCI_HOSTMODE if PCI  	default y  	help diff --git a/arch/mips/bcm63xx/dev-pcmcia.c b/arch/mips/bcm63xx/dev-pcmcia.c index de4d917fd54..a551bab5ecb 100644 --- a/arch/mips/bcm63xx/dev-pcmcia.c +++ b/arch/mips/bcm63xx/dev-pcmcia.c @@ -79,11 +79,11 @@ static int __init config_pcmcia_cs(unsigned int cs,  	return ret;  } -static const __initdata struct { +static const struct {  	unsigned int	cs;  	unsigned int	base;  	unsigned int	size; -} pcmcia_cs[3] = { +} pcmcia_cs[3] __initconst = {  	{  		.cs	= MPI_CS_PCMCIA_COMMON,  		.base	= BCM_PCMCIA_COMMON_BASE_PA, diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index f9e275a50d9..2f4f6d5e05b 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig @@ -82,10 +82,6 @@ config CAVIUM_OCTEON_LOCK_L2_MEMCPY  	help  	  Lock the kernel's implementation of memcpy() into L2. -config ARCH_SPARSEMEM_ENABLE -	def_bool y -	select SPARSEMEM_STATIC -  config IOMMU_HELPER  	bool diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 4b93048044e..ee1fb9f7f51 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -185,7 +185,6 @@ static void __cpuinit octeon_init_secondary(void)  	octeon_init_cvmcount();  	octeon_irq_setup_secondary(); -	raw_local_irq_enable();  }  /** @@ -233,6 +232,7 @@ static void octeon_smp_finish(void)  	/* to generate the first CPU timer interrupt */  	write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); +	local_irq_enable();  }  /** diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 2e1ad4c652b..82ad35ce2b4 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -17,7 +17,6 @@  #include <linux/irqflags.h>  #include <linux/types.h>  #include <asm/barrier.h> -#include <asm/bug.h>  #include <asm/byteorder.h>		/* sigh ... */  #include <asm/cpu-features.h>  #include <asm/sgidefs.h> diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index 285a41fa0b1..eee10dc07ac 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -8,6 +8,7 @@  #ifndef __ASM_CMPXCHG_H  #define __ASM_CMPXCHG_H +#include <linux/bug.h>  #include <linux/irqflags.h>  #include <asm/war.h> diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index f9fa2a479dd..95e40c1e8ed 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -94,6 +94,7 @@  #define PRID_IMP_24KE		0x9600  #define PRID_IMP_74K		0x9700  #define PRID_IMP_1004K		0x9900 +#define PRID_IMP_M14KC		0x9c00  /*   * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE @@ -260,12 +261,12 @@ enum cpu_type_enum {  	 */  	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,  	CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, -	CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, +	CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC,  	/*  	 * MIPS64 class processors  	 */ -	CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, +	CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,  	CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,  	CPU_XLR, CPU_XLP, @@ -288,7 +289,7 @@ enum cpu_type_enum {  #define MIPS_CPU_ISA_M64R2	0x00000100  #define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \ -	MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 ) +	MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2)  #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \  	MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 86548da650e..991b659e254 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -206,7 +206,7 @@  #define GIC_VPE_EIC_SHADOW_SET_BASE	0x0100  #define GIC_VPE_EIC_SS(intr) \ -	(GIC_EIC_SHADOW_SET_BASE + (4 * intr)) +	(GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr))  #define GIC_VPE_EIC_VEC_BASE		0x0800  #define GIC_VPE_EIC_VEC(intr) \ @@ -330,6 +330,17 @@ struct gic_intr_map {  #define GIC_FLAG_TRANSPARENT   0x02  }; +/* + * This is only used in EIC mode. This helps to figure out which + * shared interrupts we need to process when we get a vector interrupt. + */ +#define GIC_MAX_SHARED_INTR  0x5 +struct gic_shared_intr_map { +	unsigned int num_shared_intr; +	unsigned int intr_list[GIC_MAX_SHARED_INTR]; +	unsigned int local_intr_mask; +}; +  extern void gic_init(unsigned long gic_base_addr,  	unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,  	unsigned int intrmap_size, unsigned int irqbase); @@ -338,5 +349,7 @@ extern unsigned int gic_get_int(void);  extern void gic_send_ipi(unsigned int intr);  extern unsigned int plat_ipi_call_int_xlate(unsigned int);  extern unsigned int plat_ipi_resched_int_xlate(unsigned int); +extern void gic_bind_eic_interrupt(int irq, int set); +extern unsigned int gic_get_timer_pending(void);  #endif /* _ASM_GICREGS_H */ diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h index 7ebfc392e58..ab84064283d 100644 --- a/arch/mips/include/asm/inst.h +++ b/arch/mips/include/asm/inst.h @@ -251,7 +251,7 @@ struct f_format {	/* FPU register format */  	unsigned int func : 6;  }; -struct ma_format {	/* FPU multipy and add format (MIPS IV) */ +struct ma_format {	/* FPU multiply and add format (MIPS IV) */  	unsigned int opcode : 6;  	unsigned int fr : 5;  	unsigned int ft : 5; @@ -324,7 +324,7 @@ struct f_format {	/* FPU register format */  	unsigned int opcode : 6;  }; -struct ma_format {	/* FPU multipy and add format (MIPS IV) */ +struct ma_format {	/* FPU multiply and add format (MIPS IV) */  	unsigned int fmt : 2;  	unsigned int func : 4;  	unsigned int fd : 5; diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index a58f22998a8..29d9c23c20c 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -17,6 +17,7 @@  #include <linux/types.h>  #include <asm/addrspace.h> +#include <asm/bug.h>  #include <asm/byteorder.h>  #include <asm/cpu.h>  #include <asm/cpu-features.h> diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index fb698dc09bc..78dbb8a86da 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -136,6 +136,7 @@ extern void free_irqno(unsigned int irq);   * IE7.  Since R2 their number has to be read from the c0_intctl register.   */  #define CP0_LEGACY_COMPARE_IRQ 7 +#define CP0_LEGACY_PERFCNT_IRQ 7  extern int cp0_compare_irq;  extern int cp0_compare_irq_shift; diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 94d4faad29a..fdcd78ca1b0 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -99,7 +99,7 @@  #define CKCTL_6368_USBH_CLK_EN		(1 << 15)  #define CKCTL_6368_DISABLE_GLESS_EN	(1 << 16)  #define CKCTL_6368_NAND_CLK_EN		(1 << 17) -#define CKCTL_6368_IPSEC_CLK_EN		(1 << 17) +#define CKCTL_6368_IPSEC_CLK_EN		(1 << 18)  #define CKCTL_6368_ALL_SAFE_EN		(CKCTL_6368_SWPKT_USB_EN |	\  					CKCTL_6368_SWPKT_SAR_EN |	\ diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index d11aa02a956..5447d9fc421 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -86,6 +86,16 @@  #define GIC_CPU_INT4		4 /* .			*/  #define GIC_CPU_INT5		5 /* Core Interrupt 5   */ +/* MALTA GIC local interrupts */ +#define GIC_INT_TMR             (GIC_CPU_INT5) +#define GIC_INT_PERFCTR         (GIC_CPU_INT5) + +/* GIC constants */ +/* Add 2 to convert non-eic hw int # to eic vector # */ +#define GIC_CPU_TO_VEC_OFFSET   (2) +/* If we map an intr to pin X, GIC will actually generate vector X+1 */ +#define GIC_PIN_TO_VEC_OFFSET   (1) +  #define GIC_EXT_INTR(x)		x  /* External Interrupts used for IPI */ diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h index c9420aa97e3..e71ff4c317f 100644 --- a/arch/mips/include/asm/mipsmtregs.h +++ b/arch/mips/include/asm/mipsmtregs.h @@ -48,7 +48,7 @@  #define CP0_VPECONF0		$1, 2  #define CP0_VPECONF1		$1, 3  #define CP0_YQMASK		$1, 4 -#define CP0_VPESCHEDULE	$1, 5 +#define CP0_VPESCHEDULE		$1, 5  #define CP0_VPESCHEFBK		$1, 6  #define CP0_TCSTATUS		$2, 1  #define CP0_TCBIND		$2, 2 diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index 5d33621b565..4f8ddba8c36 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h @@ -22,7 +22,7 @@ struct task_struct;   * switch_to(n) should switch tasks to task nr n, first   * checking that n isn't the current task, in which case it does nothing.   */ -extern asmlinkage void *resume(void *last, void *next, void *next_ti); +extern asmlinkage void *resume(void *last, void *next, void *next_ti, u32 __usedfpu);  extern unsigned int ll_bit;  extern struct task_struct *ll_task; @@ -66,11 +66,13 @@ do {									\  #define switch_to(prev, next, last)					\  do {									\ +	u32 __usedfpu;							\  	__mips_mt_fpaff_switch_to(prev);				\  	if (cpu_has_dsp)						\  		__save_dsp(prev);					\  	__clear_software_ll_bit();					\ -	(last) = resume(prev, next, task_thread_info(next));		\ +	__usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU);	\ +	(last) = resume(prev, next, task_thread_info(next), __usedfpu);	\  } while (0)  #define finish_arch_switch(prev)					\ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index e2eca7d1059..ca97e0ecb64 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -60,6 +60,8 @@ struct thread_info {  register struct thread_info *__current_thread_info __asm__("$28");  #define current_thread_info()  __current_thread_info +#endif /* !__ASSEMBLY__ */ +  /* thread information allocation */  #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT)  #define THREAD_SIZE_ORDER (1) @@ -85,8 +87,6 @@ register struct thread_info *__current_thread_info __asm__("$28");  #define STACK_WARN	(THREAD_SIZE / 8) -#endif /* !__ASSEMBLY__ */ -  #define PREEMPT_ACTIVE		0x10000000  /* diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 6ae7ce4ac63..f4630e1082a 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -4,7 +4,7 @@   * Copyright (C) xxxx  the Anonymous   * Copyright (C) 1994 - 2006 Ralf Baechle   * Copyright (C) 2003, 2004  Maciej W. Rozycki - * Copyright (C) 2001, 2004  MIPS Inc. + * Copyright (C) 2001, 2004, 2011, 2012  MIPS Technologies, Inc.   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -199,6 +199,7 @@ void __init check_wait(void)  		cpu_wait = rm7k_wait_irqoff;  		break; +	case CPU_M14KC:  	case CPU_24K:  	case CPU_34K:  	case CPU_1004K: @@ -810,6 +811,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)  		c->cputype = CPU_5KC;  		__cpu_name[cpu] = "MIPS 5Kc";  		break; +	case PRID_IMP_5KE: +		c->cputype = CPU_5KE; +		__cpu_name[cpu] = "MIPS 5KE"; +		break;  	case PRID_IMP_20KC:  		c->cputype = CPU_20KC;  		__cpu_name[cpu] = "MIPS 20Kc"; @@ -831,6 +836,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)  		c->cputype = CPU_74K;  		__cpu_name[cpu] = "MIPS 74Kc";  		break; +	case PRID_IMP_M14KC: +		c->cputype = CPU_M14KC; +		__cpu_name[cpu] = "MIPS M14Kc"; +		break;  	case PRID_IMP_1004K:  		c->cputype = CPU_1004K;  		__cpu_name[cpu] = "MIPS 1004Kc"; diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 57ba13edb03..3fc1691110d 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -5,7 +5,7 @@   * License.  See the file "COPYING" in the main directory of this archive   * for more details.   * - * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle + * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05, 12 by Ralf Baechle   * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.   */  #include <linux/interrupt.h> @@ -35,6 +35,12 @@ EXPORT_SYMBOL(memmove);  EXPORT_SYMBOL(kernel_thread);  /* + * Functions that operate on entire pages.  Mostly used by memory management. + */ +EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(copy_page); + +/*   * Userspace access stuff.   */  EXPORT_SYMBOL(__copy_user); diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index ce89c806170..0441f54b2a6 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -31,7 +31,7 @@  /*   * task_struct *resume(task_struct *prev, task_struct *next, - *                     struct thread_info *next_ti) + *                     struct thread_info *next_ti, int usedfpu)   */  	.align	7  	LEAF(resume) diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index f29099b104c..eb5e394a465 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -162,11 +162,6 @@ static unsigned int counters_total_to_per_cpu(unsigned int counters)  	return counters >> vpe_shift();  } -static unsigned int counters_per_cpu_to_total(unsigned int counters) -{ -	return counters << vpe_shift(); -} -  #else /* !CONFIG_MIPS_MT_SMP */  #define vpe_id()	0 diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 293898391e6..9c51be5a163 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -43,7 +43,7 @@  /*   * task_struct *resume(task_struct *prev, task_struct *next, - *                     struct thread_info *next_ti) ) + *                     struct thread_info *next_ti, int usedfpu)   */  LEAF(resume)  	mfc0	t1, CP0_STATUS @@ -51,18 +51,9 @@ LEAF(resume)  	cpu_save_nonscratch a0  	sw	ra, THREAD_REG31(a0) -	/* -	 * check if we need to save FPU registers -	 */ -	lw	t3, TASK_THREAD_INFO(a0) -	lw	t0, TI_FLAGS(t3) -	li	t1, _TIF_USEDFPU -	and	t2, t0, t1 -	beqz	t2, 1f -	nor	t1, zero, t1 +	beqz	a3, 1f -	and	t0, t0, t1 -	sw	t0, TI_FLAGS(t3) +	PTR_L	t3, TASK_THREAD_INFO(a0)  	/*  	 * clear saved user stack CU1 bit diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 9414f935446..42d2a393842 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -41,7 +41,7 @@  /*   * task_struct *resume(task_struct *prev, task_struct *next, - *                     struct thread_info *next_ti) + *                     struct thread_info *next_ti, int usedfpu)   */  	.align	5  	LEAF(resume) @@ -53,16 +53,10 @@  	/*  	 * check if we need to save FPU registers  	 */ -	PTR_L	t3, TASK_THREAD_INFO(a0) -	LONG_L	t0, TI_FLAGS(t3) -	li	t1, _TIF_USEDFPU -	and	t2, t0, t1 -	beqz	t2, 1f -	nor	t1, zero, t1 -	and	t0, t0, t1 -	LONG_S	t0, TI_FLAGS(t3) +	beqz    a3, 1f +	PTR_L	t3, TASK_THREAD_INFO(a0)  	/*  	 * clear saved user stack CU1 bit  	 */ diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 3046e298600..8e393b8443f 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -15,7 +15,6 @@  #include <linux/smp.h>  #include <linux/interrupt.h>  #include <linux/spinlock.h> -#include <linux/init.h>  #include <linux/cpu.h>  #include <linux/cpumask.h>  #include <linux/reboot.h> @@ -197,13 +196,6 @@ static void bmips_init_secondary(void)  	write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));  #endif - -	/* make sure there won't be a timer interrupt for a little while */ -	write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); - -	irq_enable_hazard(); -	set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); -	irq_enable_hazard();  }  /* @@ -212,6 +204,13 @@ static void bmips_init_secondary(void)  static void bmips_smp_finish(void)  {  	pr_info("SMP: CPU%d is running\n", smp_processor_id()); + +	/* make sure there won't be a timer interrupt for a little while */ +	write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); + +	irq_enable_hazard(); +	set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); +	irq_enable_hazard();  }  /* diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 48650c81804..1268392f1d2 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -122,13 +122,21 @@ asmlinkage __cpuinit void start_secondary(void)  	notify_cpu_starting(cpu); -	mp_ops->smp_finish(); +	set_cpu_online(cpu, true); +  	set_cpu_sibling_map(cpu);  	cpu_set(cpu, cpu_callin_map);  	synchronise_count_slave(); +	/* +	 * irq will be enabled in ->smp_finish(), enabling it too early +	 * is dangerous. +	 */ +	WARN_ON_ONCE(!irqs_disabled()); +	mp_ops->smp_finish(); +  	cpu_idle();  } @@ -196,8 +204,6 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)  	while (!cpu_isset(cpu, cpu_callin_map))  		udelay(100); -	set_cpu_online(cpu, true); -  	return 0;  } diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index f5dd38f1d01..15b5f3cfd20 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -322,7 +322,7 @@ int __init smtc_build_cpu_map(int start_cpu_slot)  /*   * Common setup before any secondaries are started - * Make sure all CPU's are in a sensible state before we boot any of the + * Make sure all CPUs are in a sensible state before we boot any of the   * secondaries.   *   * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly @@ -340,12 +340,12 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)  	/*  	 * TCContext gets an offset from the base of the IPIQ array  	 * to be used in low-level code to detect the presence of -	 * an active IPI queue +	 * an active IPI queue.  	 */  	write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16);  	/* Bind tc to vpe */  	write_tc_c0_tcbind(vpe); -	/* In general, all TCs should have the same cpu_data indications */ +	/* In general, all TCs should have the same cpu_data indications. */  	memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));  	/* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */  	if (cpu_data[0].cputype == CPU_34K || @@ -358,8 +358,8 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)  }  /* - * Tweak to get Count registes in as close a sync as possible. - * Value seems good for 34K-class cores. + * Tweak to get Count registes in as close a sync as possible.  The + * value seems good for 34K-class cores.   */  #define CP0_SKEW 8 @@ -615,7 +615,6 @@ void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle)  void smtc_init_secondary(void)  { -	local_irq_enable();  }  void smtc_smp_finish(void) @@ -631,6 +630,8 @@ void smtc_smp_finish(void)  	if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id))  		write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); +	local_irq_enable(); +  	printk("TC %d going on-line as CPU %d\n",  		cpu_data[smp_processor_id()].tc_id, smp_processor_id());  } diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 99f913c8d7a..842d55e411f 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c @@ -111,7 +111,6 @@ void __cpuinit synchronise_count_master(void)  void __cpuinit synchronise_count_slave(void)  {  	int i; -	unsigned long flags;  	unsigned int initcount;  	int ncpus; @@ -123,8 +122,6 @@ void __cpuinit synchronise_count_slave(void)  	return;  #endif -	local_irq_save(flags); -  	/*  	 * Not every cpu is online at the time this gets called,  	 * so we first wait for the master to say everyone is ready @@ -154,7 +151,5 @@ void __cpuinit synchronise_count_slave(void)  	}  	/* Arrange for an interrupt in a short while */  	write_c0_compare(read_c0_count() + COUNTON); - -	local_irq_restore(flags);  }  #undef NR_LOOPS diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 2d0c2a277f5..c3c29354370 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -132,6 +132,9 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)  	unsigned long ra = regs->regs[31];  	unsigned long pc = regs->cp0_epc; +	if (!task) +		task = current; +  	if (raw_show_trace || !__kernel_text_address(pc)) {  		show_raw_backtrace(sp);  		return; @@ -1249,6 +1252,7 @@ static inline void parity_protection_init(void)  		break;  	case CPU_5KC: +	case CPU_5KE:  		write_c0_ecc(0x80000000);  		back_to_back_c0_hazard();  		/* Set the PE bit (bit 31) in the c0_errctl register. */ @@ -1498,6 +1502,7 @@ extern void flush_tlb_handlers(void);   * Timer interrupt   */  int cp0_compare_irq; +EXPORT_SYMBOL_GPL(cp0_compare_irq);  int cp0_compare_irq_shift;  /* @@ -1597,7 +1602,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)  			cp0_perfcount_irq = -1;  	} else {  		cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; -		cp0_compare_irq_shift = cp0_compare_irq; +		cp0_compare_irq_shift = CP0_LEGACY_PERFCNT_IRQ;  		cp0_perfcount_irq = -1;  	} diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 924da5eb703..df243a64f43 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -1,5 +1,6 @@  #include <asm/asm-offsets.h>  #include <asm/page.h> +#include <asm/thread_info.h>  #include <asm-generic/vmlinux.lds.h>  #undef mips @@ -72,7 +73,7 @@ SECTIONS  	.data : {	/* Data */  		. = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */ -		INIT_TASK_DATA(PAGE_SIZE) +		INIT_TASK_DATA(THREAD_SIZE)  		NOSAVE_DATA  		CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)  		READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 4aa20280613..fd6203f14f1 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -3,8 +3,8 @@  #  obj-y				+= cache.o dma-default.o extable.o fault.o \ -				   gup.o init.o mmap.o page.o tlbex.o \ -				   tlbex-fault.o uasm.o +				   gup.o init.o mmap.o page.o page-funcs.o \ +				   tlbex.o tlbex-fault.o uasm.o  obj-$(CONFIG_32BIT)		+= ioremap.o pgtable-32.o  obj-$(CONFIG_64BIT)		+= pgtable-64.o diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 5109be96d98..f092c265dc6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -977,7 +977,7 @@ static void __cpuinit probe_pcache(void)  			c->icache.linesz = 2 << lsize;  		else  			c->icache.linesz = lsize; -		c->icache.sets = 64 << ((config1 >> 22) & 7); +		c->icache.sets = 32 << (((config1 >> 22) + 1) & 7);  		c->icache.ways = 1 + ((config1 >> 16) & 7);  		icache_size = c->icache.sets * @@ -997,7 +997,7 @@ static void __cpuinit probe_pcache(void)  			c->dcache.linesz = 2 << lsize;  		else  			c->dcache.linesz= lsize; -		c->dcache.sets = 64 << ((config1 >> 13) & 7); +		c->dcache.sets = 32 << (((config1 >> 13) + 1) & 7);  		c->dcache.ways = 1 + ((config1 >> 7) & 7);  		dcache_size = c->dcache.sets * @@ -1051,6 +1051,7 @@ static void __cpuinit probe_pcache(void)  	case CPU_R14000:  		break; +	case CPU_M14KC:  	case CPU_24K:  	case CPU_34K:  	case CPU_74K: diff --git a/arch/mips/mm/page-funcs.S b/arch/mips/mm/page-funcs.S new file mode 100644 index 00000000000..48a6b38ff13 --- /dev/null +++ b/arch/mips/mm/page-funcs.S @@ -0,0 +1,50 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License.  See the file "COPYING" in the main directory of this archive + * for more details. + * + * Micro-assembler generated clear_page/copy_page functions. + * + * Copyright (C) 2012  MIPS Technologies, Inc. + * Copyright (C) 2012  Ralf Baechle <ralf@linux-mips.org> + */ +#include <asm/asm.h> +#include <asm/regdef.h> + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +#define cpu_clear_page_function_name	clear_page_cpu +#define cpu_copy_page_function_name	copy_page_cpu +#else +#define cpu_clear_page_function_name	clear_page +#define cpu_copy_page_function_name	copy_page +#endif + +/* + * Maximum sizes: + * + * R4000 128 bytes S-cache:		0x058 bytes + * R4600 v1.7:				0x05c bytes + * R4600 v2.0:				0x060 bytes + * With prefetching, 16 word strides	0x120 bytes + */ +EXPORT(__clear_page_start) +LEAF(cpu_clear_page_function_name) +1:	j	1b		/* Dummy, will be replaced. */ +	.space 288 +END(cpu_clear_page_function_name) +EXPORT(__clear_page_end) + +/* + * Maximum sizes: + * + * R4000 128 bytes S-cache:		0x11c bytes + * R4600 v1.7:				0x080 bytes + * R4600 v2.0:				0x07c bytes + * With prefetching, 16 word strides	0x540 bytes + */ +EXPORT(__copy_page_start) +LEAF(cpu_copy_page_function_name) +1:	j	1b		/* Dummy, will be replaced. */ +	.space 1344 +END(cpu_copy_page_function_name) +EXPORT(__copy_page_end) diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index cc0b626858b..98f530e1821 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -6,6 +6,7 @@   * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)   * Copyright (C) 2007  Maciej W. Rozycki   * Copyright (C) 2008  Thiemo Seufer + * Copyright (C) 2012  MIPS Technologies, Inc.   */  #include <linux/init.h>  #include <linux/kernel.h> @@ -71,45 +72,6 @@ static struct uasm_reloc __cpuinitdata relocs[5];  #define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x00002010)  #define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x00002020) -/* - * Maximum sizes: - * - * R4000 128 bytes S-cache:		0x058 bytes - * R4600 v1.7:				0x05c bytes - * R4600 v2.0:				0x060 bytes - * With prefetching, 16 word strides	0x120 bytes - */ - -static u32 clear_page_array[0x120 / 4]; - -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS -void clear_page_cpu(void *page) __attribute__((alias("clear_page_array"))); -#else -void clear_page(void *page) __attribute__((alias("clear_page_array"))); -#endif - -EXPORT_SYMBOL(clear_page); - -/* - * Maximum sizes: - * - * R4000 128 bytes S-cache:		0x11c bytes - * R4600 v1.7:				0x080 bytes - * R4600 v2.0:				0x07c bytes - * With prefetching, 16 word strides	0x540 bytes - */ -static u32 copy_page_array[0x540 / 4]; - -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS -void -copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array"))); -#else -void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); -#endif - -EXPORT_SYMBOL(copy_page); - -  static int pref_bias_clear_store __cpuinitdata;  static int pref_bias_copy_load __cpuinitdata;  static int pref_bias_copy_store __cpuinitdata; @@ -282,10 +244,15 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off)  		}  } +extern u32 __clear_page_start; +extern u32 __clear_page_end; +extern u32 __copy_page_start; +extern u32 __copy_page_end; +  void __cpuinit build_clear_page(void)  {  	int off; -	u32 *buf = (u32 *)&clear_page_array; +	u32 *buf = &__clear_page_start;  	struct uasm_label *l = labels;  	struct uasm_reloc *r = relocs;  	int i; @@ -356,17 +323,17 @@ void __cpuinit build_clear_page(void)  	uasm_i_jr(&buf, RA);  	uasm_i_nop(&buf); -	BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array)); +	BUG_ON(buf > &__clear_page_end);  	uasm_resolve_relocs(relocs, labels);  	pr_debug("Synthesized clear page handler (%u instructions).\n", -		 (u32)(buf - clear_page_array)); +		 (u32)(buf - &__clear_page_start));  	pr_debug("\t.set push\n");  	pr_debug("\t.set noreorder\n"); -	for (i = 0; i < (buf - clear_page_array); i++) -		pr_debug("\t.word 0x%08x\n", clear_page_array[i]); +	for (i = 0; i < (buf - &__clear_page_start); i++) +		pr_debug("\t.word 0x%08x\n", (&__clear_page_start)[i]);  	pr_debug("\t.set pop\n");  } @@ -427,7 +394,7 @@ static inline void build_copy_store_pref(u32 **buf, int off)  void __cpuinit build_copy_page(void)  {  	int off; -	u32 *buf = (u32 *)©_page_array; +	u32 *buf = &__copy_page_start;  	struct uasm_label *l = labels;  	struct uasm_reloc *r = relocs;  	int i; @@ -595,21 +562,23 @@ void __cpuinit build_copy_page(void)  	uasm_i_jr(&buf, RA);  	uasm_i_nop(&buf); -	BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array)); +	BUG_ON(buf > &__copy_page_end);  	uasm_resolve_relocs(relocs, labels);  	pr_debug("Synthesized copy page handler (%u instructions).\n", -		 (u32)(buf - copy_page_array)); +		 (u32)(buf - &__copy_page_start));  	pr_debug("\t.set push\n");  	pr_debug("\t.set noreorder\n"); -	for (i = 0; i < (buf - copy_page_array); i++) -		pr_debug("\t.word 0x%08x\n", copy_page_array[i]); +	for (i = 0; i < (buf - &__copy_page_start); i++) +		pr_debug("\t.word 0x%08x\n", (&__copy_page_start)[i]);  	pr_debug("\t.set pop\n");  }  #ifdef CONFIG_SIBYTE_DMA_PAGEOPS +extern void clear_page_cpu(void *page); +extern void copy_page_cpu(void *to, void *from);  /*   * Pad descriptors to cacheline, since each is exclusively owned by a diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0bc485b3cd6..03eb0ef9158 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -9,6 +9,7 @@   * Copyright (C) 2005, 2007, 2008, 2009  Maciej W. Rozycki   * Copyright (C) 2006  Ralf Baechle (ralf@linux-mips.org)   * Copyright (C) 2008, 2009 Cavium Networks, Inc. + * Copyright (C) 2011  MIPS Technologies, Inc.   *   * ... and the days got worse and worse and now you see   * I've gone completly out of my mind. @@ -494,6 +495,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,  	case CPU_R14000:  	case CPU_4KC:  	case CPU_4KEC: +	case CPU_M14KC:  	case CPU_SB1:  	case CPU_SB1A:  	case CPU_4KSC: diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c index bf80921f2f5..284dea54faf 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/mti-malta/malta-pci.c @@ -241,8 +241,9 @@ void __init mips_pcibios_init(void)  		return;  	} -	if (controller->io_resource->start < 0x00001000UL)	/* FIXME */ -		controller->io_resource->start = 0x00001000UL; +	/* Change start address to avoid conflicts with ACPI and SMB devices */ +	if (controller->io_resource->start < 0x00002000UL) +		controller->io_resource->start = 0x00002000UL;  	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */  	ioport_resource.end = controller->io_resource->end; @@ -253,7 +254,7 @@ void __init mips_pcibios_init(void)  }  /* Enable PCI 2.1 compatibility in PIIX4 */ -static void __init quirk_dlcsetup(struct pci_dev *dev) +static void __devinit quirk_dlcsetup(struct pci_dev *dev)  {  	u8 odlc, ndlc;  	(void) pci_read_config_byte(dev, 0x82, &odlc); diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index b7f37d4982f..2e28f653f66 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -111,7 +111,7 @@ static void __init pci_clock_check(void)  	unsigned int __iomem *jmpr_p =  		(unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int));  	int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; -	static const int pciclocks[] __initdata = { +	static const int pciclocks[] __initconst = {  		33, 20, 25, 30, 12, 16, 37, 10  	};  	int pciclock = pciclocks[jmpr]; diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index acb677a1227..b3df7c2aad1 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -82,8 +82,10 @@ void __init prom_free_prom_memory(void)  void xlp_mmu_init(void)  { +	/* enable extended TLB and Large Fixed TLB */  	write_c0_config6(read_c0_config6() | 0x24); -	current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; + +	/* set page mask of Fixed TLB in config7 */  	write_c0_config7(PM_DEFAULT_MASK >>  		(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));  } @@ -100,6 +102,10 @@ void __init prom_init(void)  	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));  #ifdef CONFIG_SMP  	nlm_wakeup_secondary_cpus(0xffffffff); + +	/* update TLB size after waking up threads */ +	current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; +  	register_smp_ops(&nlm_smp_ops);  #endif  } diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index d1f2d4c52d4..b6e378211a2 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -78,6 +78,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)  	switch (current_cpu_type()) {  	case CPU_5KC: +	case CPU_M14KC:  	case CPU_20KC:  	case CPU_24K:  	case CPU_25KF: diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index baba3bcaa3c..4d80a856048 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -322,6 +322,10 @@ static int __init mipsxx_init(void)  	op_model_mipsxx_ops.num_counters = counters;  	switch (current_cpu_type()) { +	case CPU_M14KC: +		op_model_mipsxx_ops.cpu_type = "mips/M14Kc"; +		break; +  	case CPU_20KC:  		op_model_mipsxx_ops.cpu_type = "mips/20K";  		break; diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c index d5d4c018fb0..0857ab8c391 100644 --- a/arch/mips/pci/fixup-fuloong2e.c +++ b/arch/mips/pci/fixup-fuloong2e.c @@ -48,7 +48,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)  	return 0;  } -static void __init loongson2e_nec_fixup(struct pci_dev *pdev) +static void __devinit loongson2e_nec_fixup(struct pci_dev *pdev)  {  	unsigned int val; @@ -60,7 +60,7 @@ static void __init loongson2e_nec_fixup(struct pci_dev *pdev)  	pci_write_config_dword(pdev, 0xe4, 1 << 5);  } -static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev) +static void __devinit loongson2e_686b_func0_fixup(struct pci_dev *pdev)  {  	unsigned char c; @@ -135,7 +135,7 @@ static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)  	printk(KERN_INFO"via686b fix: ISA bridge done\n");  } -static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev) +static void __devinit loongson2e_686b_func1_fixup(struct pci_dev *pdev)  {  	printk(KERN_INFO"via686b fix: IDE\n"); @@ -168,19 +168,19 @@ static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)  	printk(KERN_INFO"via686b fix: IDE done\n");  } -static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev) +static void __devinit loongson2e_686b_func2_fixup(struct pci_dev *pdev)  {  	/* irq routing */  	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);  } -static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev) +static void __devinit loongson2e_686b_func3_fixup(struct pci_dev *pdev)  {  	/* irq routing */  	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);  } -static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev) +static void __devinit loongson2e_686b_func5_fixup(struct pci_dev *pdev)  {  	unsigned int val;  	unsigned char c; diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c index 4b9768d5d72..a7b917dcf60 100644 --- a/arch/mips/pci/fixup-lemote2f.c +++ b/arch/mips/pci/fixup-lemote2f.c @@ -96,21 +96,21 @@ int pcibios_plat_dev_init(struct pci_dev *dev)  }  /* CS5536 SPEC. fixup */ -static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev) +static void __devinit loongson_cs5536_isa_fixup(struct pci_dev *pdev)  {  	/* the uart1 and uart2 interrupt in PIC is enabled as default */  	pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);  	pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);  } -static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev) +static void __devinit loongson_cs5536_ide_fixup(struct pci_dev *pdev)  {  	/* setting the mutex pin as IDE function */  	pci_write_config_dword(pdev, PCI_IDE_CFG_REG,  			       CS5536_IDE_FLASH_SIGNATURE);  } -static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) +static void __devinit loongson_cs5536_acc_fixup(struct pci_dev *pdev)  {  	/* enable the AUDIO interrupt in PIC  */  	pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); @@ -118,14 +118,14 @@ static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev)  	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);  } -static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev) +static void __devinit loongson_cs5536_ohci_fixup(struct pci_dev *pdev)  {  	/* enable the OHCI interrupt in PIC */  	/* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */  	pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);  } -static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) +static void __devinit loongson_cs5536_ehci_fixup(struct pci_dev *pdev)  {  	u32 hi, lo; @@ -137,7 +137,7 @@ static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev)  	pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);  } -static void __init loongson_nec_fixup(struct pci_dev *pdev) +static void __devinit loongson_nec_fixup(struct pci_dev *pdev)  {  	unsigned int val; diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 0f48498bc23..70073c98ed3 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c @@ -49,10 +49,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev)  	return 0;  } -static void __init malta_piix_func0_fixup(struct pci_dev *pdev) +static void __devinit malta_piix_func0_fixup(struct pci_dev *pdev)  {  	unsigned char reg_val; -	static int piixirqmap[16] __initdata = {  /* PIIX PIRQC[A:D] irq mappings */ +	static int piixirqmap[16] __devinitdata = {  /* PIIX PIRQC[A:D] irq mappings */  		0,  0, 	0,  3,  		4,  5,  6,  7,  		0,  9, 10, 11, @@ -83,7 +83,7 @@ static void __init malta_piix_func0_fixup(struct pci_dev *pdev)  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,  	 malta_piix_func0_fixup); -static void __init malta_piix_func1_fixup(struct pci_dev *pdev) +static void __devinit malta_piix_func1_fixup(struct pci_dev *pdev)  {  	unsigned char reg_val; diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c index e08f49cb687..8e4f8288eca 100644 --- a/arch/mips/pci/fixup-mpc30x.c +++ b/arch/mips/pci/fixup-mpc30x.c @@ -22,13 +22,13 @@  #include <asm/vr41xx/mpc30x.h> -static const int internal_func_irqs[] __initdata = { +static const int internal_func_irqs[] __initconst = {  	VRC4173_CASCADE_IRQ,  	VRC4173_AC97_IRQ,  	VRC4173_USB_IRQ,  }; -static const int irq_tab_mpc30x[] __initdata = { +static const int irq_tab_mpc30x[] __initconst = {   [12] = VRC4173_PCMCIA1_IRQ,   [13] = VRC4173_PCMCIA2_IRQ,   [29] = MQ200_IRQ, diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c index f0bb9146e6c..d02900a7291 100644 --- a/arch/mips/pci/fixup-sb1250.c +++ b/arch/mips/pci/fixup-sb1250.c @@ -15,7 +15,7 @@   * Set the BCM1250, etc. PCI host bridge's TRDY timeout   * to the finite max.   */ -static void __init quirk_sb1250_pci(struct pci_dev *dev) +static void __devinit quirk_sb1250_pci(struct pci_dev *dev)  {  	pci_write_config_byte(dev, 0x40, 0xff);  } @@ -25,7 +25,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,  /*   * The BCM1250, etc. PCI/HT bridge reports as a host bridge.   */ -static void __init quirk_sb1250_ht(struct pci_dev *dev) +static void __devinit quirk_sb1250_ht(struct pci_dev *dev)  {  	dev->class = PCI_CLASS_BRIDGE_PCI << 8;  } @@ -35,7 +35,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,  /*   * Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max.   */ -static void __init quirk_sp1011(struct pci_dev *dev) +static void __devinit quirk_sp1011(struct pci_dev *dev)  {  	pci_write_config_byte(dev, 0x64, 0xff);  } diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index a1e7e6d80c8..bc13e29d2bb 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -495,7 +495,7 @@ irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id)  }  #ifdef CONFIG_TOSHIBA_FPCIB0 -static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) +static void __devinit tx4927_quirk_slc90e66_bridge(struct pci_dev *dev)  {  	struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus); diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 0fbe4c0c170..fdc24440294 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -212,7 +212,7 @@ static inline void pci_enable_swapping(struct pci_dev *dev)  	bridge->b_widget.w_tflush;	/* Flush */  } -static void __init pci_fixup_ioc3(struct pci_dev *d) +static void __devinit pci_fixup_ioc3(struct pci_dev *d)  {  	pci_disable_swapping(d);  } diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 1644805a673..172af1cd586 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -41,6 +41,7 @@  #include <linux/irq.h>  #include <linux/irqdesc.h>  #include <linux/console.h> +#include <linux/pci_regs.h>  #include <asm/io.h> @@ -156,35 +157,55 @@ struct pci_controller nlm_pci_controller = {  	.io_offset      = 0x00000000UL,  }; +/* + * The top level PCIe links on the XLS PCIe controller appear as + * bridges. Given a device, this function finds which link it is + * on. + */ +static struct pci_dev *xls_get_pcie_link(const struct pci_dev *dev) +{ +	struct pci_bus *bus, *p; + +	/* Find the bridge on bus 0 */ +	bus = dev->bus; +	for (p = bus->parent; p && p->number != 0; p = p->parent) +		bus = p; + +	return p ? bus->self : NULL; +} +  static int get_irq_vector(const struct pci_dev *dev)  { +	struct pci_dev *lnk; +  	if (!nlm_chip_is_xls()) -		return	PIC_PCIX_IRQ;	/* for XLR just one IRQ*/ +		return	PIC_PCIX_IRQ;	/* for XLR just one IRQ */  	/*  	 * For XLS PCIe, there is an IRQ per Link, find out which  	 * link the device is on to assign interrupts -	*/ -	if (dev->bus->self == NULL) +	 */ +	lnk = xls_get_pcie_link(dev); +	if (lnk == NULL)  		return 0; -	switch	(dev->bus->self->devfn) { -	case 0x0: +	switch	(PCI_SLOT(lnk->devfn)) { +	case 0:  		return PIC_PCIE_LINK0_IRQ; -	case 0x8: +	case 1:  		return PIC_PCIE_LINK1_IRQ; -	case 0x10: +	case 2:  		if (nlm_chip_is_xls_b())  			return PIC_PCIE_XLSB0_LINK2_IRQ;  		else  			return PIC_PCIE_LINK2_IRQ; -	case 0x18: +	case 3:  		if (nlm_chip_is_xls_b())  			return PIC_PCIE_XLSB0_LINK3_IRQ;  		else  			return PIC_PCIE_LINK3_IRQ;  	} -	WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn); +	WARN(1, "Unexpected devfn %d\n", lnk->devfn);  	return 0;  } @@ -202,7 +223,27 @@ void arch_teardown_msi_irq(unsigned int irq)  int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)  {  	struct msi_msg msg; +	struct pci_dev *lnk;  	int irq, ret; +	u16 val; + +	/* MSI not supported on XLR */ +	if (!nlm_chip_is_xls()) +		return 1; + +	/* +	 * Enable MSI on the XLS PCIe controller bridge which was disabled +	 * at enumeration, the bridge MSI capability is at 0x50 +	 */ +	lnk = xls_get_pcie_link(dev); +	if (lnk == NULL) +		return 1; + +	pci_read_config_word(lnk, 0x50 + PCI_MSI_FLAGS, &val); +	if ((val & PCI_MSI_FLAGS_ENABLE) == 0) { +		val |= PCI_MSI_FLAGS_ENABLE; +		pci_write_config_word(lnk, 0x50 + PCI_MSI_FLAGS, val); +	}  	irq = get_irq_vector(dev);  	if (irq <= 0) @@ -327,7 +368,7 @@ static int __init pcibios_init(void)  		}  	} else {  		/* XLR PCI controller ACK */ -		irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack); +		irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack);  	}  	return 0; diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index b71fae23104..5edab2bc6fc 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -115,11 +115,11 @@ static void yos_send_ipi_mask(const struct cpumask *mask, unsigned int action)   */  static void __cpuinit yos_init_secondary(void)  { -	set_c0_status(ST0_CO | ST0_IE | ST0_IM);  }  static void __cpuinit yos_smp_finish(void)  { +	set_c0_status(ST0_CO | ST0_IM | ST0_IE);  }  /* Hook for after all CPUs are online */ diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c index 0a170e0ffea..7773f3d956b 100644 --- a/arch/mips/powertv/asic/asic-calliope.c +++ b/arch/mips/powertv/asic/asic-calliope.c @@ -28,7 +28,7 @@  #define CALLIOPE_ADDR(x)	(CALLIOPE_IO_BASE + (x)) -const struct register_map calliope_register_map __initdata = { +const struct register_map calliope_register_map __initconst = {  	.eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)},  	.eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)},  	.eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)}, diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c index bbc0c122be5..da076db7b7e 100644 --- a/arch/mips/powertv/asic/asic-cronus.c +++ b/arch/mips/powertv/asic/asic-cronus.c @@ -28,7 +28,7 @@  #define CRONUS_ADDR(x)	(CRONUS_IO_BASE + (x)) -const struct register_map cronus_register_map __initdata = { +const struct register_map cronus_register_map __initconst = {  	.eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)},  	.eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)},  	.eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)}, diff --git a/arch/mips/powertv/asic/asic-gaia.c b/arch/mips/powertv/asic/asic-gaia.c index 91dda682752..47683b370e7 100644 --- a/arch/mips/powertv/asic/asic-gaia.c +++ b/arch/mips/powertv/asic/asic-gaia.c @@ -23,7 +23,7 @@  #include <linux/init.h>  #include <asm/mach-powertv/asic.h> -const struct register_map gaia_register_map __initdata = { +const struct register_map gaia_register_map __initconst = {  	.eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000},  	.eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038},  	.eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C}, diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c index 4a05bb09647..6ff4b10f09d 100644 --- a/arch/mips/powertv/asic/asic-zeus.c +++ b/arch/mips/powertv/asic/asic-zeus.c @@ -28,7 +28,7 @@  #define ZEUS_ADDR(x)	(ZEUS_IO_BASE + (x)) -const struct register_map zeus_register_map __initdata = { +const struct register_map zeus_register_map __initconst = {  	.eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)},  	.eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)},  	.eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)}, diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 682efb0c108..64eb71b1528 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -269,7 +269,7 @@ txx9_i8259_irq_setup(int irq)  	return err;  } -static void __init quirk_slc90e66_bridge(struct pci_dev *dev) +static void __devinit quirk_slc90e66_bridge(struct pci_dev *dev)  {  	int irq;	/* PCI/ISA Bridge interrupt */  	u8 reg_64;  |