aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel/smp.c')
-rw-r--r--arch/parisc/kernel/smp.c178
1 files changed, 23 insertions, 155 deletions
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 12cc019307ad..6ba9257fdb7f 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -16,9 +16,6 @@
16** the Free Software Foundation; either version 2 of the License, or 16** the Free Software Foundation; either version 2 of the License, or
17** (at your option) any later version. 17** (at your option) any later version.
18*/ 18*/
19#undef ENTRY_SYS_CPUS /* syscall support for iCOD-like functionality */
20
21
22#include <linux/types.h> 19#include <linux/types.h>
23#include <linux/spinlock.h> 20#include <linux/spinlock.h>
24#include <linux/slab.h> 21#include <linux/slab.h>
@@ -51,7 +48,15 @@
51#include <asm/unistd.h> 48#include <asm/unistd.h>
52#include <asm/cacheflush.h> 49#include <asm/cacheflush.h>
53 50
54#define kDEBUG 0 51#undef DEBUG_SMP
52#ifdef DEBUG_SMP
53static int smp_debug_lvl = 0;
54#define smp_debug(lvl, printargs...) \
55 if (lvl >= smp_debug_lvl) \
56 printk(printargs);
57#else
58#define smp_debug(lvl, ...)
59#endif /* DEBUG_SMP */
55 60
56DEFINE_SPINLOCK(smp_lock); 61DEFINE_SPINLOCK(smp_lock);
57 62
@@ -76,6 +81,7 @@ cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL; /* Bitmap of Present CP
76EXPORT_SYMBOL(cpu_online_map); 81EXPORT_SYMBOL(cpu_online_map);
77EXPORT_SYMBOL(cpu_possible_map); 82EXPORT_SYMBOL(cpu_possible_map);
78 83
84DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
79 85
80struct smp_call_struct { 86struct smp_call_struct {
81 void (*func) (void *info); 87 void (*func) (void *info);
@@ -107,13 +113,6 @@ enum ipi_message_type {
107static void 113static void
108ipi_init(int cpuid) 114ipi_init(int cpuid)
109{ 115{
110
111 /* If CPU is present ... */
112#ifdef ENTRY_SYS_CPUS
113 /* *and* running (not stopped) ... */
114#error iCOD support wants state checked here.
115#endif
116
117#error verify IRQ_OFFSET(IPI_IRQ) is ipi_interrupt() in new IRQ region 116#error verify IRQ_OFFSET(IPI_IRQ) is ipi_interrupt() in new IRQ region
118 117
119 if(cpu_online(cpuid) ) 118 if(cpu_online(cpuid) )
@@ -133,23 +132,12 @@ ipi_init(int cpuid)
133static void 132static void
134halt_processor(void) 133halt_processor(void)
135{ 134{
136#ifdef ENTRY_SYS_CPUS
137#error halt_processor() needs rework
138/*
139** o migrate I/O interrupts off this CPU.
140** o leave IPI enabled - __cli() will disable IPI.
141** o leave CPU in online map - just change the state
142*/
143 cpu_data[this_cpu].state = STATE_STOPPED;
144 mark_bh(IPI_BH);
145#else
146 /* REVISIT : redirect I/O Interrupts to another CPU? */ 135 /* REVISIT : redirect I/O Interrupts to another CPU? */
147 /* REVISIT : does PM *know* this CPU isn't available? */ 136 /* REVISIT : does PM *know* this CPU isn't available? */
148 cpu_clear(smp_processor_id(), cpu_online_map); 137 cpu_clear(smp_processor_id(), cpu_online_map);
149 local_irq_disable(); 138 local_irq_disable();
150 for (;;) 139 for (;;)
151 ; 140 ;
152#endif
153} 141}
154 142
155 143
@@ -167,10 +155,11 @@ ipi_interrupt(int irq, void *dev_id)
167 mb(); /* Order interrupt and bit testing. */ 155 mb(); /* Order interrupt and bit testing. */
168 156
169 for (;;) { 157 for (;;) {
170 spin_lock_irqsave(&(p->lock),flags); 158 spinlock_t *lock = &per_cpu(ipi_lock, this_cpu);
159 spin_lock_irqsave(lock, flags);
171 ops = p->pending_ipi; 160 ops = p->pending_ipi;
172 p->pending_ipi = 0; 161 p->pending_ipi = 0;
173 spin_unlock_irqrestore(&(p->lock),flags); 162 spin_unlock_irqrestore(lock, flags);
174 163
175 mb(); /* Order bit clearing and data access. */ 164 mb(); /* Order bit clearing and data access. */
176 165
@@ -184,15 +173,11 @@ ipi_interrupt(int irq, void *dev_id)
184 173
185 switch (which) { 174 switch (which) {
186 case IPI_NOP: 175 case IPI_NOP:
187#if (kDEBUG>=100) 176 smp_debug(100, KERN_DEBUG "CPU%d IPI_NOP\n", this_cpu);
188 printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
189#endif /* kDEBUG */
190 break; 177 break;
191 178
192 case IPI_RESCHEDULE: 179 case IPI_RESCHEDULE:
193#if (kDEBUG>=100) 180 smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
194 printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
195#endif /* kDEBUG */
196 /* 181 /*
197 * Reschedule callback. Everything to be 182 * Reschedule callback. Everything to be
198 * done is done by the interrupt return path. 183 * done is done by the interrupt return path.
@@ -200,9 +185,7 @@ ipi_interrupt(int irq, void *dev_id)
200 break; 185 break;
201 186
202 case IPI_CALL_FUNC: 187 case IPI_CALL_FUNC:
203#if (kDEBUG>=100) 188 smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC\n", this_cpu);
204 printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
205#endif /* kDEBUG */
206 { 189 {
207 volatile struct smp_call_struct *data; 190 volatile struct smp_call_struct *data;
208 void (*func)(void *info); 191 void (*func)(void *info);
@@ -233,28 +216,16 @@ ipi_interrupt(int irq, void *dev_id)
233 break; 216 break;
234 217
235 case IPI_CPU_START: 218 case IPI_CPU_START:
236#if (kDEBUG>=100) 219 smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu);
237 printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
238#endif /* kDEBUG */
239#ifdef ENTRY_SYS_CPUS
240 p->state = STATE_RUNNING;
241#endif
242 break; 220 break;
243 221
244 case IPI_CPU_STOP: 222 case IPI_CPU_STOP:
245#if (kDEBUG>=100) 223 smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_STOP\n", this_cpu);
246 printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
247#endif /* kDEBUG */
248#ifdef ENTRY_SYS_CPUS
249#else
250 halt_processor(); 224 halt_processor();
251#endif
252 break; 225 break;
253 226
254 case IPI_CPU_TEST: 227 case IPI_CPU_TEST:
255#if (kDEBUG>=100) 228 smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu);
256 printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
257#endif /* kDEBUG */
258 break; 229 break;
259 230
260 default: 231 default:
@@ -275,12 +246,13 @@ static inline void
275ipi_send(int cpu, enum ipi_message_type op) 246ipi_send(int cpu, enum ipi_message_type op)
276{ 247{
277 struct cpuinfo_parisc *p = &cpu_data[cpu]; 248 struct cpuinfo_parisc *p = &cpu_data[cpu];
249 spinlock_t *lock = &per_cpu(ipi_lock, cpu);
278 unsigned long flags; 250 unsigned long flags;
279 251
280 spin_lock_irqsave(&(p->lock),flags); 252 spin_lock_irqsave(lock, flags);
281 p->pending_ipi |= 1 << op; 253 p->pending_ipi |= 1 << op;
282 gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa); 254 gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
283 spin_unlock_irqrestore(&(p->lock),flags); 255 spin_unlock_irqrestore(lock, flags);
284} 256}
285 257
286 258
@@ -560,13 +532,8 @@ int __init smp_boot_one_cpu(int cpuid)
560 532
561alive: 533alive:
562 /* Remember the Slave data */ 534 /* Remember the Slave data */
563#if (kDEBUG>=100) 535 smp_debug(100, KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
564 printk(KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
565 cpuid, timeout * 100); 536 cpuid, timeout * 100);
566#endif /* kDEBUG */
567#ifdef ENTRY_SYS_CPUS
568 cpu_data[cpuid].state = STATE_RUNNING;
569#endif
570 return 0; 537 return 0;
571} 538}
572 539
@@ -574,10 +541,6 @@ void __devinit smp_prepare_boot_cpu(void)
574{ 541{
575 int bootstrap_processor=cpu_data[0].cpuid; /* CPU ID of BSP */ 542 int bootstrap_processor=cpu_data[0].cpuid; /* CPU ID of BSP */
576 543
577#ifdef ENTRY_SYS_CPUS
578 cpu_data[0].state = STATE_RUNNING;
579#endif
580
581 /* Setup BSP mappings */ 544 /* Setup BSP mappings */
582 printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor); 545 printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
583 546
@@ -616,101 +579,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
616 return cpu_online(cpu) ? 0 : -ENOSYS; 579 return cpu_online(cpu) ? 0 : -ENOSYS;
617} 580}
618 581
619
620
621#ifdef ENTRY_SYS_CPUS
622/* Code goes along with:
623** entry.s: ENTRY_NAME(sys_cpus) / * 215, for cpu stat * /
624*/
625int sys_cpus(int argc, char **argv)
626{
627 int i,j=0;
628 extern int current_pid(int cpu);
629
630 if( argc > 2 ) {
631 printk("sys_cpus:Only one argument supported\n");
632 return (-1);
633 }
634 if ( argc == 1 ){
635
636#ifdef DUMP_MORE_STATE
637 for_each_online_cpu(i) {
638 int cpus_per_line = 4;
639
640 if (j++ % cpus_per_line)
641 printk(" %3d",i);
642 else
643 printk("\n %3d",i);
644 }
645 printk("\n");
646#else
647 printk("\n 0\n");
648#endif
649 } else if((argc==2) && !(strcmp(argv[1],"-l"))) {
650 printk("\nCPUSTATE TASK CPUNUM CPUID HARDCPU(HPA)\n");
651#ifdef DUMP_MORE_STATE
652 for_each_online_cpu(i) {
653 if (cpu_data[i].cpuid != NO_PROC_ID) {
654 switch(cpu_data[i].state) {
655 case STATE_RENDEZVOUS:
656 printk("RENDEZVS ");
657 break;
658 case STATE_RUNNING:
659 printk((current_pid(i)!=0) ? "RUNNING " : "IDLING ");
660 break;
661 case STATE_STOPPED:
662 printk("STOPPED ");
663 break;
664 case STATE_HALTED:
665 printk("HALTED ");
666 break;
667 default:
668 printk("%08x?", cpu_data[i].state);
669 break;
670 }
671 if(cpu_online(i)) {
672 printk(" %4d",current_pid(i));
673 }
674 printk(" %6d",cpu_number_map(i));
675 printk(" %5d",i);
676 printk(" 0x%lx\n",cpu_data[i].hpa);
677 }
678 }
679#else
680 printk("\n%s %4d 0 0 --------",
681 (current->pid)?"RUNNING ": "IDLING ",current->pid);
682#endif
683 } else if ((argc==2) && !(strcmp(argv[1],"-s"))) {
684#ifdef DUMP_MORE_STATE
685 printk("\nCPUSTATE CPUID\n");
686 for_each_online_cpu(i) {
687 if (cpu_data[i].cpuid != NO_PROC_ID) {
688 switch(cpu_data[i].state) {
689 case STATE_RENDEZVOUS:
690 printk("RENDEZVS");break;
691 case STATE_RUNNING:
692 printk((current_pid(i)!=0) ? "RUNNING " : "IDLING");
693 break;
694 case STATE_STOPPED:
695 printk("STOPPED ");break;
696 case STATE_HALTED:
697 printk("HALTED ");break;
698 default:
699 }
700 printk(" %5d\n",i);
701 }
702 }
703#else
704 printk("\n%s CPU0",(current->pid==0)?"RUNNING ":"IDLING ");
705#endif
706 } else {
707 printk("sys_cpus:Unknown request\n");
708 return (-1);
709 }
710 return 0;
711}
712#endif /* ENTRY_SYS_CPUS */
713
714#ifdef CONFIG_PROC_FS 582#ifdef CONFIG_PROC_FS
715int __init 583int __init
716setup_profiling_timer(unsigned int multiplier) 584setup_profiling_timer(unsigned int multiplier)