aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-01-18 04:42:26 -0500
committerVineet Gupta <vgupta@synopsys.com>2013-02-15 12:46:16 -0500
commit10b1271875abb9d590c14fa6c8b24b0d6f768ca2 (patch)
tree6abcf7cd3c787eaec128fb428da11e0eea8f7c8b /arch/arc
parentfc7943d29e9f6f5f6d4b111120b66ec86501673e (diff)
ARC: [Review] Multi-platform image #7: SMP common code to use callbacks
This again is for switch from singleton platform SMP API to multi-platform paradigm Platform code is not yet setup to populate the callbacks, that happens in next commit Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Cc: Arnd Bergmann <arnd@arndb.de> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/include/asm/smp.h36
-rw-r--r--arch/arc/kernel/smp.c16
2 files changed, 28 insertions, 24 deletions
diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 0cff3a548136..c4fb211dcd25 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -31,6 +31,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
31 */ 31 */
32extern void __init smp_init_cpus(void); 32extern void __init smp_init_cpus(void);
33extern void __init first_lines_of_secondary(void); 33extern void __init first_lines_of_secondary(void);
34extern const char *arc_platform_smp_cpuinfo(void);
34 35
35/* 36/*
36 * API expected BY platform smp code (FROM arch smp code) 37 * API expected BY platform smp code (FROM arch smp code)
@@ -41,29 +42,22 @@ extern void __init first_lines_of_secondary(void);
41extern int smp_ipi_irq_setup(int cpu, int irq); 42extern int smp_ipi_irq_setup(int cpu, int irq);
42 43
43/* 44/*
44 * APIs expected FROM platform smp code 45 * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP
45 *
46 * arc_platform_smp_cpuinfo:
47 * returns a string containing info for /proc/cpuinfo
48 *
49 * arc_platform_smp_wait_to_boot:
50 * Called from early bootup code for non-Master CPUs to "park" them
51 * 46 *
52 * arc_platform_smp_wakeup_cpu: 47 * @info: SoC SMP specific info for /proc/cpuinfo etc
53 * Called from __cpu_up (Master CPU) to kick start another one 48 * @cpu_kick: For Master to kickstart a cpu (optionally at a PC)
54 * 49 * @ipi_send: To send IPI to a @cpumask
55 * arc_platform_ipi_send: 50 * @ips_clear: To clear IPI received by @cpu at @irq
56 * Takes @cpumask to which IPI(s) would be sent.
57 * The actual msg-id/buffer is manager in arch-common code
58 *
59 * arc_platform_ipi_clear:
60 * Takes @cpu which got IPI at @irq to do any IPI clearing
61 */ 51 */
62extern const char *arc_platform_smp_cpuinfo(void); 52struct plat_smp_ops {
63extern void arc_platform_smp_wait_to_boot(int cpu); 53 const char *info;
64extern void arc_platform_smp_wakeup_cpu(int cpu, unsigned long pc); 54 void (*cpu_kick)(int cpu, unsigned long pc);
65extern void arc_platform_ipi_send(const struct cpumask *callmap); 55 void (*ipi_send)(void *callmap);
66extern void arc_platform_ipi_clear(int cpu, int irq); 56 void (*ipi_clear)(int cpu, int irq);
57};
58
59/* TBD: stop exporting it for direct population by platform */
60extern struct plat_smp_ops plat_smp_ops;
67 61
68#endif /* CONFIG_SMP */ 62#endif /* CONFIG_SMP */
69 63
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 8ee010fdbc18..3af3e06dcf02 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -37,6 +37,8 @@
37arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED; 37arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
38arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED; 38arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
39 39
40struct plat_smp_ops plat_smp_ops;
41
40/* XXX: per cpu ? Only needed once in early seconday boot */ 42/* XXX: per cpu ? Only needed once in early seconday boot */
41struct task_struct *secondary_idle_tsk; 43struct task_struct *secondary_idle_tsk;
42 44
@@ -105,6 +107,11 @@ void __attribute__((weak)) arc_platform_smp_wait_to_boot(int cpu)
105 " b 1b \n"); 107 " b 1b \n");
106} 108}
107 109
110const char *arc_platform_smp_cpuinfo(void)
111{
112 return plat_smp_ops.info;
113}
114
108/* 115/*
109 * The very first "C" code executed by secondary 116 * The very first "C" code executed by secondary
110 * Called from asm stub in head.S 117 * Called from asm stub in head.S
@@ -156,7 +163,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
156 pr_info("Idle Task [%d] %p", cpu, idle); 163 pr_info("Idle Task [%d] %p", cpu, idle);
157 pr_info("Trying to bring up CPU%u ...\n", cpu); 164 pr_info("Trying to bring up CPU%u ...\n", cpu);
158 165
159 arc_platform_smp_wakeup_cpu(cpu, 166 if (plat_smp_ops.cpu_kick)
167 plat_smp_ops.cpu_kick(cpu,
160 (unsigned long)first_lines_of_secondary); 168 (unsigned long)first_lines_of_secondary);
161 169
162 /* wait for 1 sec after kicking the secondary */ 170 /* wait for 1 sec after kicking the secondary */
@@ -225,7 +233,8 @@ static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg)
225 } 233 }
226 234
227 /* Call the platform specific cross-CPU call function */ 235 /* Call the platform specific cross-CPU call function */
228 arc_platform_ipi_send(callmap); 236 if (plat_smp_ops.ipi_send)
237 plat_smp_ops.ipi_send((void *)callmap);
229 238
230 local_irq_restore(flags); 239 local_irq_restore(flags);
231} 240}
@@ -299,7 +308,8 @@ irqreturn_t do_IPI(int irq, void *dev_id)
299 struct ipi_data *ipi = &per_cpu(ipi_data, cpu); 308 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
300 unsigned long ops; 309 unsigned long ops;
301 310
302 arc_platform_ipi_clear(cpu, irq); 311 if (plat_smp_ops.ipi_clear)
312 plat_smp_ops.ipi_clear(cpu, irq);
303 313
304 /* 314 /*
305 * XXX: is this loop really needed 315 * XXX: is this loop really needed