mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-29 13:04:27 -04:00 
			
		
		
		
	Update bmips cleanup patches with upstream submission and backport a few bmips fixes. Signed-off-by: Jonas Gorski <jogo@openwrt.org> SVN-Revision: 39267
		
			
				
	
	
		
			603 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			603 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 7d790bd6cab314462a29ba194e243b8b1d529524 Mon Sep 17 00:00:00 2001
 | |
| From: Jonas Gorski <jogo@openwrt.org>
 | |
| Date: Thu, 27 Jun 2013 21:33:56 +0200
 | |
| Subject: [PATCH V2 03/13] MIPS: BMIPS: change compile time checks to runtime
 | |
|  checks
 | |
| 
 | |
| Allow building for all bmips cpus at the same time by changing ifdefs
 | |
| to checks for the cpu type, or adding appropriate checks to the
 | |
| assembly.
 | |
| 
 | |
| Since BMIPS43XX and BMIPS5000 require different IPI implementations,
 | |
| split the SMP ops into one for each, so the runtime overhead is only
 | |
| at registration time for them.
 | |
| 
 | |
| Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 | |
| ---
 | |
| V1 -> V2:
 | |
|   * use switch (cpu_type()) instead of if () else if () ...
 | |
|   * split the smp ops into bmips43xx and bmips5000
 | |
| 
 | |
|  arch/mips/bcm63xx/prom.c      |   2 +-
 | |
|  arch/mips/include/asm/bmips.h |   3 +-
 | |
|  arch/mips/kernel/bmips_vec.S  |  55 ++++++--
 | |
|  arch/mips/kernel/smp-bmips.c  | 312 +++++++++++++++++++++++++-----------------
 | |
|  4 files changed, 235 insertions(+), 137 deletions(-)
 | |
| 
 | |
| --- a/arch/mips/bcm63xx/prom.c
 | |
| +++ b/arch/mips/bcm63xx/prom.c
 | |
| @@ -61,7 +61,7 @@ void __init prom_init(void)
 | |
|  
 | |
|  	if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
 | |
|  		/* set up SMP */
 | |
| -		register_smp_ops(&bmips_smp_ops);
 | |
| +		register_smp_ops(&bmips43xx_smp_ops);
 | |
|  
 | |
|  		/*
 | |
|  		 * BCM6328 might not have its second CPU enabled, while BCM3368
 | |
| --- a/arch/mips/include/asm/bmips.h
 | |
| +++ b/arch/mips/include/asm/bmips.h
 | |
| @@ -47,7 +47,8 @@
 | |
|  #include <linux/cpumask.h>
 | |
|  #include <asm/r4kcache.h>
 | |
|  
 | |
| -extern struct plat_smp_ops bmips_smp_ops;
 | |
| +extern struct plat_smp_ops bmips43xx_smp_ops;
 | |
| +extern struct plat_smp_ops bmips5000_smp_ops;
 | |
|  extern char bmips_reset_nmi_vec;
 | |
|  extern char bmips_reset_nmi_vec_end;
 | |
|  extern char bmips_smp_movevec;
 | |
| --- a/arch/mips/kernel/bmips_vec.S
 | |
| +++ b/arch/mips/kernel/bmips_vec.S
 | |
| @@ -13,6 +13,7 @@
 | |
|  #include <asm/asm.h>
 | |
|  #include <asm/asmmacro.h>
 | |
|  #include <asm/cacheops.h>
 | |
| +#include <asm/cpu.h>
 | |
|  #include <asm/regdef.h>
 | |
|  #include <asm/mipsregs.h>
 | |
|  #include <asm/stackframe.h>
 | |
| @@ -93,12 +94,18 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
 | |
|  	beqz	k0, bmips_smp_entry
 | |
|  
 | |
|  #if defined(CONFIG_CPU_BMIPS5000)
 | |
| +	mfc0	k0, CP0_PRID
 | |
| +	li	k1, PRID_IMP_BMIPS5000
 | |
| +	andi	k0, 0xff00
 | |
| +	bne	k0, k1, 1f
 | |
| +
 | |
|  	/* if we're not on core 0, this must be the SMP boot signal */
 | |
|  	li	k1, (3 << 25)
 | |
|  	mfc0	k0, $22
 | |
|  	and	k0, k1
 | |
|  	bnez	k0, bmips_smp_entry
 | |
| -#endif
 | |
| +1:
 | |
| +#endif /* CONFIG_CPU_BMIPS5000 */
 | |
|  #endif /* CONFIG_SMP */
 | |
|  
 | |
|  	/* nope, it's just a regular NMI */
 | |
| @@ -141,7 +148,12 @@ bmips_smp_entry:
 | |
|  	xori	k0, 0x04
 | |
|  	mtc0	k0, CP0_CONFIG
 | |
|  
 | |
| +	mfc0	k0, CP0_PRID
 | |
| +	andi	k0, 0xff00
 | |
|  #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
 | |
| +	li	k1, PRID_IMP_BMIPS43XX
 | |
| +	bne	k0, k1, 2f
 | |
| +
 | |
|  	/* initialize CPU1's local I-cache */
 | |
|  	li	k0, 0x80000000
 | |
|  	li	k1, 0x80010000
 | |
| @@ -152,14 +164,21 @@ bmips_smp_entry:
 | |
|  1:	cache	Index_Store_Tag_I, 0(k0)
 | |
|  	addiu	k0, 16
 | |
|  	bne	k0, k1, 1b
 | |
| -#elif defined(CONFIG_CPU_BMIPS5000)
 | |
| +
 | |
| +	b	3f
 | |
| +2:
 | |
| +#endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
 | |
| +#if defined(CONFIG_CPU_BMIPS5000)
 | |
|  	/* set exception vector base */
 | |
| +	li	k1, PRID_IMP_BMIPS5000
 | |
| +	bne	k0, k1, 3f
 | |
| +
 | |
|  	la	k0, ebase
 | |
|  	lw	k0, 0(k0)
 | |
|  	mtc0	k0, $15, 1
 | |
|  	BARRIER
 | |
| -#endif
 | |
| -
 | |
| +#endif /* CONFIG_CPU_BMIPS5000 */
 | |
| +3:
 | |
|  	/* jump back to kseg0 in case we need to remap the kseg1 area */
 | |
|  	la	k0, 1f
 | |
|  	jr	k0
 | |
| @@ -225,8 +244,18 @@ END(bmips_smp_int_vec)
 | |
|  LEAF(bmips_enable_xks01)
 | |
|  
 | |
|  #if defined(CONFIG_XKS01)
 | |
| -
 | |
| +	mfc0	t0, CP0_PRID
 | |
| +	andi	t2, t0, 0xff00
 | |
|  #if defined(CONFIG_CPU_BMIPS4380)
 | |
| +	li	t1, PRID_IMP_BMIPS43XX
 | |
| +	bne	t2, t1, 1f
 | |
| +
 | |
| +	andi	t0, 0xff
 | |
| +	addiu	t1, t0, -PRID_REV_BMIPS4380_HI
 | |
| +	bgtz	t1, 2f
 | |
| +	addiu	t0, -PRID_REV_BMIPS4380_LO
 | |
| +	bltz	t0, 2f
 | |
| +
 | |
|  	mfc0	t0, $22, 3
 | |
|  	li	t1, 0x1ff0
 | |
|  	li	t2, (1 << 12) | (1 << 9)
 | |
| @@ -235,7 +264,13 @@ LEAF(bmips_enable_xks01)
 | |
|  	or	t0, t2
 | |
|  	mtc0	t0, $22, 3
 | |
|  	BARRIER
 | |
| -#elif defined(CONFIG_CPU_BMIPS5000)
 | |
| +	b	2f
 | |
| +1:
 | |
| +#endif /* CONFIG_CPU_BMIPS4380 */
 | |
| +#if defined(CONFIG_CPU_BMIPS5000)
 | |
| +	li	t1, PRID_IMP_BMIPS5000
 | |
| +	bne	t2, t1, 2f
 | |
| +
 | |
|  	mfc0	t0, $22, 5
 | |
|  	li	t1, 0x01ff
 | |
|  	li	t2, (1 << 8) | (1 << 5)
 | |
| @@ -244,12 +279,8 @@ LEAF(bmips_enable_xks01)
 | |
|  	or	t0, t2
 | |
|  	mtc0	t0, $22, 5
 | |
|  	BARRIER
 | |
| -#else
 | |
| -
 | |
| -#error Missing XKS01 setup
 | |
| -
 | |
| -#endif
 | |
| -
 | |
| +#endif /* CONFIG_CPU_BMIPS5000 */
 | |
| +2:
 | |
|  #endif /* defined(CONFIG_XKS01) */
 | |
|  
 | |
|  	jr	ra
 | |
| --- a/arch/mips/kernel/smp-bmips.c
 | |
| +++ b/arch/mips/kernel/smp-bmips.c
 | |
| @@ -49,8 +49,10 @@ cpumask_t bmips_booted_mask;
 | |
|  unsigned long bmips_smp_boot_sp;
 | |
|  unsigned long bmips_smp_boot_gp;
 | |
|  
 | |
| -static void bmips_send_ipi_single(int cpu, unsigned int action);
 | |
| -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
 | |
| +static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
 | |
| +static void bmips5000_send_ipi_single(int cpu, unsigned int action);
 | |
| +static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
 | |
| +static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
 | |
|  
 | |
|  /* SW interrupts 0,1 are used for interprocessor signaling */
 | |
|  #define IPI0_IRQ			(MIPS_CPU_IRQ_BASE + 0)
 | |
| @@ -64,49 +66,58 @@ static irqreturn_t bmips_ipi_interrupt(i
 | |
|  static void __init bmips_smp_setup(void)
 | |
|  {
 | |
|  	int i, cpu = 1, boot_cpu = 0;
 | |
| -
 | |
| -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
 | |
|  	int cpu_hw_intr;
 | |
|  
 | |
| -	/* arbitration priority */
 | |
| -	clear_c0_brcm_cmt_ctrl(0x30);
 | |
| -
 | |
| -	/* NBK and weak order flags */
 | |
| -	set_c0_brcm_config_0(0x30000);
 | |
| -
 | |
| -	/* Find out if we are running on TP0 or TP1 */
 | |
| -	boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
 | |
| -
 | |
| -	/*
 | |
| -	 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
 | |
| -	 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
 | |
| -	 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
 | |
| -	 */
 | |
| -	if (boot_cpu == 0)
 | |
| -		cpu_hw_intr = 0x02;
 | |
| -	else
 | |
| -		cpu_hw_intr = 0x1d;
 | |
| -
 | |
| -	change_c0_brcm_cmt_intr(0xf8018000, (cpu_hw_intr << 27) | (0x03 << 15));
 | |
| -
 | |
| -	/* single core, 2 threads (2 pipelines) */
 | |
| -	max_cpus = 2;
 | |
| -#elif defined(CONFIG_CPU_BMIPS5000)
 | |
| -	/* enable raceless SW interrupts */
 | |
| -	set_c0_brcm_config(0x03 << 22);
 | |
| -
 | |
| -	/* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
 | |
| -	change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
 | |
| -
 | |
| -	/* N cores, 2 threads per core */
 | |
| -	max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
 | |
| +	switch (current_cpu_type()) {
 | |
| +	case CPU_BMIPS4350:
 | |
| +	case CPU_BMIPS4380:
 | |
| +		/* arbitration priority */
 | |
| +		clear_c0_brcm_cmt_ctrl(0x30);
 | |
| +
 | |
| +		/* NBK and weak order flags */
 | |
| +		set_c0_brcm_config_0(0x30000);
 | |
| +
 | |
| +		/* Find out if we are running on TP0 or TP1 */
 | |
| +		boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
 | |
| +
 | |
| +		/*
 | |
| +		 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
 | |
| +		 * thread
 | |
| +		 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
 | |
| +		 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
 | |
| +		 */
 | |
| +		if (boot_cpu == 0)
 | |
| +			cpu_hw_intr = 0x02;
 | |
| +		else
 | |
| +			cpu_hw_intr = 0x1d;
 | |
| +
 | |
| +		change_c0_brcm_cmt_intr(0xf8018000,
 | |
| +					(cpu_hw_intr << 27) | (0x03 << 15));
 | |
| +
 | |
| +		/* single core, 2 threads (2 pipelines) */
 | |
| +		max_cpus = 2;
 | |
| +
 | |
| +		break;
 | |
| +	case CPU_BMIPS5000:
 | |
| +		/* enable raceless SW interrupts */
 | |
| +		set_c0_brcm_config(0x03 << 22);
 | |
| +
 | |
| +		/* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
 | |
| +		change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
 | |
| +
 | |
| +		/* N cores, 2 threads per core */
 | |
| +		max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
 | |
| +
 | |
| +		/* clear any pending SW interrupts */
 | |
| +		for (i = 0; i < max_cpus; i++) {
 | |
| +			write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
 | |
| +			write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
 | |
| +		}
 | |
|  
 | |
| -	/* clear any pending SW interrupts */
 | |
| -	for (i = 0; i < max_cpus; i++) {
 | |
| -		write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
 | |
| -		write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
 | |
| +		break;
 | |
| +	default:
 | |
| +		max_cpus = 1;
 | |
|  	}
 | |
| -#endif
 | |
|  
 | |
|  	if (!bmips_smp_enabled)
 | |
|  		max_cpus = 1;
 | |
| @@ -134,6 +145,20 @@ static void __init bmips_smp_setup(void)
 | |
|   */
 | |
|  static void bmips_prepare_cpus(unsigned int max_cpus)
 | |
|  {
 | |
| +	irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
 | |
| +
 | |
| +	switch (current_cpu_type()) {
 | |
| +	case CPU_BMIPS4350:
 | |
| +	case CPU_BMIPS4380:
 | |
| +		bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
 | |
| +		break;
 | |
| +	case CPU_BMIPS5000:
 | |
| +		bmips_ipi_interrupt = bmips5000_ipi_interrupt;
 | |
| +		break;
 | |
| +	default:
 | |
| +		return;
 | |
| +	}
 | |
| +
 | |
|  	if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
 | |
|  			"smp_ipi0", NULL))
 | |
|  		panic("Can't request IPI0 interrupt\n");
 | |
| @@ -168,26 +193,39 @@ static void bmips_boot_secondary(int cpu
 | |
|  
 | |
|  	pr_info("SMP: Booting CPU%d...\n", cpu);
 | |
|  
 | |
| -	if (cpumask_test_cpu(cpu, &bmips_booted_mask))
 | |
| -		bmips_send_ipi_single(cpu, 0);
 | |
| +	if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
 | |
| +		switch (current_cpu_type()) {
 | |
| +		case CPU_BMIPS4350:
 | |
| +		case CPU_BMIPS4380:
 | |
| +			bmips43xx_send_ipi_single(cpu, 0);
 | |
| +			break;
 | |
| +		case CPU_BMIPS5000:
 | |
| +			bmips5000_send_ipi_single(cpu, 0);
 | |
| +			break;
 | |
| +		}
 | |
| +	}
 | |
|  	else {
 | |
| -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
 | |
| -		/* Reset slave TP1 if booting from TP0 */
 | |
| -		if (cpu_logical_map(cpu) == 1)
 | |
| -			set_c0_brcm_cmt_ctrl(0x01);
 | |
| -#elif defined(CONFIG_CPU_BMIPS5000)
 | |
| -		if (cpu & 0x01)
 | |
| -			write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
 | |
| -		else {
 | |
| -			/*
 | |
| -			 * core N thread 0 was already booted; just
 | |
| -			 * pulse the NMI line
 | |
| -			 */
 | |
| -			bmips_write_zscm_reg(0x210, 0xc0000000);
 | |
| -			udelay(10);
 | |
| -			bmips_write_zscm_reg(0x210, 0x00);
 | |
| +		switch (current_cpu_type()) {
 | |
| +		case CPU_BMIPS4350:
 | |
| +		case CPU_BMIPS4380:
 | |
| +			/* Reset slave TP1 if booting from TP0 */
 | |
| +			if (cpu_logical_map(cpu) == 1)
 | |
| +				set_c0_brcm_cmt_ctrl(0x01);
 | |
| +			break;
 | |
| +		case CPU_BMIPS5000:
 | |
| +			if (cpu & 0x01)
 | |
| +				write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
 | |
| +			else {
 | |
| +				/*
 | |
| +				 * core N thread 0 was already booted; just
 | |
| +				 * pulse the NMI line
 | |
| +				 */
 | |
| +				bmips_write_zscm_reg(0x210, 0xc0000000);
 | |
| +				udelay(10);
 | |
| +				bmips_write_zscm_reg(0x210, 0x00);
 | |
| +			}
 | |
| +			break;
 | |
|  		}
 | |
| -#endif
 | |
|  		cpumask_set_cpu(cpu, &bmips_booted_mask);
 | |
|  	}
 | |
|  }
 | |
| @@ -199,26 +237,32 @@ static void bmips_init_secondary(void)
 | |
|  {
 | |
|  	/* move NMI vector to kseg0, in case XKS01 is enabled */
 | |
|  
 | |
| -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
 | |
| -	void __iomem *cbr = BMIPS_GET_CBR();
 | |
| +	void __iomem *cbr;
 | |
|  	unsigned long old_vec;
 | |
|  	unsigned long relo_vector;
 | |
|  	int boot_cpu;
 | |
|  
 | |
| -	boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
 | |
| -	relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
 | |
| -			  BMIPS_RELO_VECTOR_CONTROL_1;
 | |
| -
 | |
| -	old_vec = __raw_readl(cbr + relo_vector);
 | |
| -	__raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
 | |
| -
 | |
| -	clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
 | |
| -#elif defined(CONFIG_CPU_BMIPS5000)
 | |
| -	write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
 | |
| -		(smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
 | |
| +	switch (current_cpu_type()) {
 | |
| +	case CPU_BMIPS4350:
 | |
| +	case CPU_BMIPS4380:
 | |
| +		cbr = BMIPS_GET_CBR();
 | |
| +
 | |
| +		boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
 | |
| +		relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
 | |
| +				  BMIPS_RELO_VECTOR_CONTROL_1;
 | |
| +
 | |
| +		old_vec = __raw_readl(cbr + relo_vector);
 | |
| +		__raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
 | |
| +
 | |
| +		clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
 | |
| +		break;
 | |
| +	case CPU_BMIPS5000:
 | |
| +		write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
 | |
| +			(smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
 | |
|  
 | |
| -	write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
 | |
| -#endif
 | |
| +		write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
 | |
| +		break;
 | |
| +	}
 | |
|  }
 | |
|  
 | |
|  /*
 | |
| @@ -243,8 +287,6 @@ static void bmips_cpus_done(void)
 | |
|  {
 | |
|  }
 | |
|  
 | |
| -#if defined(CONFIG_CPU_BMIPS5000)
 | |
| -
 | |
|  /*
 | |
|   * BMIPS5000 raceless IPIs
 | |
|   *
 | |
| @@ -253,12 +295,12 @@ static void bmips_cpus_done(void)
 | |
|   * IPI1 is used for SMP_CALL_FUNCTION
 | |
|   */
 | |
|  
 | |
| -static void bmips_send_ipi_single(int cpu, unsigned int action)
 | |
| +static void bmips5000_send_ipi_single(int cpu, unsigned int action)
 | |
|  {
 | |
|  	write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
 | |
|  }
 | |
|  
 | |
| -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
 | |
| +static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
 | |
|  {
 | |
|  	int action = irq - IPI0_IRQ;
 | |
|  
 | |
| @@ -272,7 +314,14 @@ static irqreturn_t bmips_ipi_interrupt(i
 | |
|  	return IRQ_HANDLED;
 | |
|  }
 | |
|  
 | |
| -#else
 | |
| +static void bmips5000_send_ipi_mask(const struct cpumask *mask,
 | |
| +	unsigned int action)
 | |
| +{
 | |
| +	unsigned int i;
 | |
| +
 | |
| +	for_each_cpu(i, mask)
 | |
| +		bmips5000_send_ipi_single(i, action);
 | |
| +}
 | |
|  
 | |
|  /*
 | |
|   * BMIPS43xx racey IPIs
 | |
| @@ -287,7 +336,7 @@ static irqreturn_t bmips_ipi_interrupt(i
 | |
|  static DEFINE_SPINLOCK(ipi_lock);
 | |
|  static DEFINE_PER_CPU(int, ipi_action_mask);
 | |
|  
 | |
| -static void bmips_send_ipi_single(int cpu, unsigned int action)
 | |
| +static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
 | |
|  {
 | |
|  	unsigned long flags;
 | |
|  
 | |
| @@ -298,7 +347,7 @@ static void bmips_send_ipi_single(int cp
 | |
|  	spin_unlock_irqrestore(&ipi_lock, flags);
 | |
|  }
 | |
|  
 | |
| -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
 | |
| +static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
 | |
|  {
 | |
|  	unsigned long flags;
 | |
|  	int action, cpu = irq - IPI0_IRQ;
 | |
| @@ -317,15 +366,13 @@ static irqreturn_t bmips_ipi_interrupt(i
 | |
|  	return IRQ_HANDLED;
 | |
|  }
 | |
|  
 | |
| -#endif /* BMIPS type */
 | |
| -
 | |
| -static void bmips_send_ipi_mask(const struct cpumask *mask,
 | |
| +static void bmips43xx_send_ipi_mask(const struct cpumask *mask,
 | |
|  	unsigned int action)
 | |
|  {
 | |
|  	unsigned int i;
 | |
|  
 | |
|  	for_each_cpu(i, mask)
 | |
| -		bmips_send_ipi_single(i, action);
 | |
| +		bmips43xx_send_ipi_single(i, action);
 | |
|  }
 | |
|  
 | |
|  #ifdef CONFIG_HOTPLUG_CPU
 | |
| @@ -381,15 +428,30 @@ void __ref play_dead(void)
 | |
|  
 | |
|  #endif /* CONFIG_HOTPLUG_CPU */
 | |
|  
 | |
| -struct plat_smp_ops bmips_smp_ops = {
 | |
| +struct plat_smp_ops bmips43xx_smp_ops = {
 | |
| +	.smp_setup		= bmips_smp_setup,
 | |
| +	.prepare_cpus		= bmips_prepare_cpus,
 | |
| +	.boot_secondary		= bmips_boot_secondary,
 | |
| +	.smp_finish		= bmips_smp_finish,
 | |
| +	.init_secondary		= bmips_init_secondary,
 | |
| +	.cpus_done		= bmips_cpus_done,
 | |
| +	.send_ipi_single	= bmips43xx_send_ipi_single,
 | |
| +	.send_ipi_mask		= bmips43xx_send_ipi_mask,
 | |
| +#ifdef CONFIG_HOTPLUG_CPU
 | |
| +	.cpu_disable		= bmips_cpu_disable,
 | |
| +	.cpu_die		= bmips_cpu_die,
 | |
| +#endif
 | |
| +};
 | |
| +
 | |
| +struct plat_smp_ops bmips5000_smp_ops = {
 | |
|  	.smp_setup		= bmips_smp_setup,
 | |
|  	.prepare_cpus		= bmips_prepare_cpus,
 | |
|  	.boot_secondary		= bmips_boot_secondary,
 | |
|  	.smp_finish		= bmips_smp_finish,
 | |
|  	.init_secondary		= bmips_init_secondary,
 | |
|  	.cpus_done		= bmips_cpus_done,
 | |
| -	.send_ipi_single	= bmips_send_ipi_single,
 | |
| -	.send_ipi_mask		= bmips_send_ipi_mask,
 | |
| +	.send_ipi_single	= bmips5000_send_ipi_single,
 | |
| +	.send_ipi_mask		= bmips5000_send_ipi_mask,
 | |
|  #ifdef CONFIG_HOTPLUG_CPU
 | |
|  	.cpu_disable		= bmips_cpu_disable,
 | |
|  	.cpu_die		= bmips_cpu_die,
 | |
| @@ -427,43 +489,47 @@ void __cpuinit bmips_ebase_setup(void)
 | |
|  
 | |
|  	BUG_ON(ebase != CKSEG0);
 | |
|  
 | |
| -#if defined(CONFIG_CPU_BMIPS4350)
 | |
| -	/*
 | |
| -	 * BMIPS4350 cannot relocate the normal vectors, but it
 | |
| -	 * can relocate the BEV=1 vectors.  So CPU1 starts up at
 | |
| -	 * the relocated BEV=1, IV=0 general exception vector @
 | |
| -	 * 0xa000_0380.
 | |
| -	 *
 | |
| -	 * set_uncached_handler() is used here because:
 | |
| -	 *  - CPU1 will run this from uncached space
 | |
| -	 *  - None of the cacheflush functions are set up yet
 | |
| -	 */
 | |
| -	set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
 | |
| -		&bmips_smp_int_vec, 0x80);
 | |
| -	__sync();
 | |
| -	return;
 | |
| -#elif defined(CONFIG_CPU_BMIPS4380)
 | |
| -	/*
 | |
| -	 * 0x8000_0000: reset/NMI (initially in kseg1)
 | |
| -	 * 0x8000_0400: normal vectors
 | |
| -	 */
 | |
| -	new_ebase = 0x80000400;
 | |
| -	cbr = BMIPS_GET_CBR();
 | |
| -	__raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
 | |
| -	__raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
 | |
| -#elif defined(CONFIG_CPU_BMIPS5000)
 | |
| -	/*
 | |
| -	 * 0x8000_0000: reset/NMI (initially in kseg1)
 | |
| -	 * 0x8000_1000: normal vectors
 | |
| -	 */
 | |
| -	new_ebase = 0x80001000;
 | |
| -	write_c0_brcm_bootvec(0xa0088008);
 | |
| -	write_c0_ebase(new_ebase);
 | |
| -	if (max_cpus > 2)
 | |
| -		bmips_write_zscm_reg(0xa0, 0xa008a008);
 | |
| -#else
 | |
| -	return;
 | |
| -#endif
 | |
| +	switch (current_cpu_type()) {
 | |
| +	case CPU_BMIPS4350:
 | |
| +		/*
 | |
| +		 * BMIPS4350 cannot relocate the normal vectors, but it
 | |
| +		 * can relocate the BEV=1 vectors.  So CPU1 starts up at
 | |
| +		 * the relocated BEV=1, IV=0 general exception vector @
 | |
| +		 * 0xa000_0380.
 | |
| +		 *
 | |
| +		 * set_uncached_handler() is used here because:
 | |
| +		 *  - CPU1 will run this from uncached space
 | |
| +		 *  - None of the cacheflush functions are set up yet
 | |
| +		 */
 | |
| +		set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
 | |
| +			&bmips_smp_int_vec, 0x80);
 | |
| +		__sync();
 | |
| +		return;
 | |
| +	case CPU_BMIPS4380:
 | |
| +		/*
 | |
| +		 * 0x8000_0000: reset/NMI (initially in kseg1)
 | |
| +		 * 0x8000_0400: normal vectors
 | |
| +		 */
 | |
| +		new_ebase = 0x80000400;
 | |
| +		cbr = BMIPS_GET_CBR();
 | |
| +		__raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
 | |
| +		__raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
 | |
| +		break;
 | |
| +	case CPU_BMIPS5000:
 | |
| +		/*
 | |
| +		 * 0x8000_0000: reset/NMI (initially in kseg1)
 | |
| +		 * 0x8000_1000: normal vectors
 | |
| +		 */
 | |
| +		new_ebase = 0x80001000;
 | |
| +		write_c0_brcm_bootvec(0xa0088008);
 | |
| +		write_c0_ebase(new_ebase);
 | |
| +		if (max_cpus > 2)
 | |
| +			bmips_write_zscm_reg(0xa0, 0xa008a008);
 | |
| +		break;
 | |
| +	default:
 | |
| +		return;
 | |
| +	}
 | |
| +
 | |
|  	board_nmi_handler_setup = &bmips_nmi_handler_setup;
 | |
|  	ebase = new_ebase;
 | |
|  }
 |