1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/sched/hotplug.h>
23#include <linux/smp.h>
24#include <linux/interrupt.h>
25#include <linux/kernel_stat.h>
26#include <linux/delay.h>
27#include <linux/init.h>
28#include <linux/spinlock.h>
29#include <linux/errno.h>
30#include <linux/hardirq.h>
31#include <linux/cpu.h>
32#include <linux/compiler.h>
33#include <linux/pgtable.h>
34
35#include <asm/ptrace.h>
36#include <linux/atomic.h>
37#include <asm/code-patching.h>
38#include <asm/irq.h>
39#include <asm/page.h>
40#include <asm/sections.h>
41#include <asm/io.h>
42#include <asm/prom.h>
43#include <asm/smp.h>
44#include <asm/machdep.h>
45#include <asm/pmac_feature.h>
46#include <asm/time.h>
47#include <asm/mpic.h>
48#include <asm/cacheflush.h>
49#include <asm/keylargo.h>
50#include <asm/pmac_low_i2c.h>
51#include <asm/pmac_pfunc.h>
52#include <asm/inst.h>
53
54#include "pmac.h"
55
56#undef DEBUG
57
58#ifdef DEBUG
59#define DBG(fmt...) udbg_printf(fmt)
60#else
61#define DBG(fmt...)
62#endif
63
64extern void __secondary_start_pmac_0(void);
65
66static void (*pmac_tb_freeze)(int freeze);
67static u64 timebase;
68static int tb_req;
69
70#ifdef CONFIG_PPC_PMAC32_PSURGE
71
72
73
74
75
76
77#define HAMMERHEAD_BASE 0xf8000000
78#define HHEAD_CONFIG 0x90
79#define HHEAD_SEC_INTR 0xc0
80
81
82
83#define PSURGE_PRI_INTR 0xf3019000
84
85
86
87#define PSURGE_START 0xf2800000
88
89
90#define PSURGE_QUAD_REG_ADDR 0xf8800000
91
92#define PSURGE_QUAD_IRQ_SET 0
93#define PSURGE_QUAD_IRQ_CLR 1
94#define PSURGE_QUAD_IRQ_PRIMARY 2
95#define PSURGE_QUAD_CKSTOP_CTL 3
96#define PSURGE_QUAD_PRIMARY_ARB 4
97#define PSURGE_QUAD_BOARD_ID 6
98#define PSURGE_QUAD_WHICH_CPU 7
99#define PSURGE_QUAD_CKSTOP_RDBK 8
100#define PSURGE_QUAD_RESET_CTL 11
101
102#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
103#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
104#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
105#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
106
107
108static volatile u8 __iomem *hhead_base;
109static volatile u8 __iomem *quad_base;
110static volatile u32 __iomem *psurge_pri_intr;
111static volatile u8 __iomem *psurge_sec_intr;
112static volatile u32 __iomem *psurge_start;
113
114
115#define PSURGE_NONE -1
116#define PSURGE_DUAL 0
117#define PSURGE_QUAD_OKEE 1
118#define PSURGE_QUAD_COTTON 2
119#define PSURGE_QUAD_ICEGRASS 3
120
121
122static int psurge_type = PSURGE_NONE;
123
124
125static struct irq_domain *psurge_host;
126int psurge_secondary_virq;
127
128
129
130
131static inline void psurge_set_ipi(int cpu)
132{
133 if (psurge_type == PSURGE_NONE)
134 return;
135 if (cpu == 0)
136 in_be32(psurge_pri_intr);
137 else if (psurge_type == PSURGE_DUAL)
138 out_8(psurge_sec_intr, 0);
139 else
140 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
141}
142
143static inline void psurge_clr_ipi(int cpu)
144{
145 if (cpu > 0) {
146 switch(psurge_type) {
147 case PSURGE_DUAL:
148 out_8(psurge_sec_intr, ~0);
149 case PSURGE_NONE:
150 break;
151 default:
152 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
153 }
154 }
155}
156
157
158
159
160
161
162
163static irqreturn_t psurge_ipi_intr(int irq, void *d)
164{
165 psurge_clr_ipi(smp_processor_id());
166 smp_ipi_demux();
167
168 return IRQ_HANDLED;
169}
170
171static void smp_psurge_cause_ipi(int cpu)
172{
173 psurge_set_ipi(cpu);
174}
175
176static int psurge_host_map(struct irq_domain *h, unsigned int virq,
177 irq_hw_number_t hw)
178{
179 irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
180
181 return 0;
182}
183
184static const struct irq_domain_ops psurge_host_ops = {
185 .map = psurge_host_map,
186};
187
188static int psurge_secondary_ipi_init(void)
189{
190 int rc = -ENOMEM;
191
192 psurge_host = irq_domain_add_nomap(NULL, ~0, &psurge_host_ops, NULL);
193
194 if (psurge_host)
195 psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
196
197 if (psurge_secondary_virq)
198 rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
199 IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL);
200
201 if (rc)
202 pr_err("Failed to setup secondary cpu IPI\n");
203
204 return rc;
205}
206
207
208
209
210
211
212static int __init psurge_quad_probe(void)
213{
214 int type;
215 unsigned int i;
216
217 type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
218 if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
219 || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
220 return PSURGE_DUAL;
221
222
223
224
225 for (i = 0; i < 100; i++) {
226 volatile u32 bogus[8];
227 bogus[(0+i)%8] = 0x00000000;
228 bogus[(1+i)%8] = 0x55555555;
229 bogus[(2+i)%8] = 0xFFFFFFFF;
230 bogus[(3+i)%8] = 0xAAAAAAAA;
231 bogus[(4+i)%8] = 0x33333333;
232 bogus[(5+i)%8] = 0xCCCCCCCC;
233 bogus[(6+i)%8] = 0xCCCCCCCC;
234 bogus[(7+i)%8] = 0x33333333;
235 wmb();
236 asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
237 mb();
238 if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
239 return PSURGE_DUAL;
240 }
241 return type;
242}
243
244static void __init psurge_quad_init(void)
245{
246 int procbits;
247
248 if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
249 procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
250 if (psurge_type == PSURGE_QUAD_ICEGRASS)
251 PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
252 else
253 PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
254 mdelay(33);
255 out_8(psurge_sec_intr, ~0);
256 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
257 PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
258 if (psurge_type != PSURGE_QUAD_ICEGRASS)
259 PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
260 PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
261 mdelay(33);
262 PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
263 mdelay(33);
264 PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
265 mdelay(33);
266}
267
268static void __init smp_psurge_probe(void)
269{
270 int i, ncpus;
271 struct device_node *dn;
272
273
274 if (PVR_VER(mfspr(SPRN_PVR)) == 1)
275 return;
276
277
278
279
280
281
282
283
284
285
286
287 dn = of_find_node_by_name(NULL, "hammerhead");
288 if (dn == NULL)
289 return;
290 of_node_put(dn);
291
292 hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
293 quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
294 psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
295
296 psurge_type = psurge_quad_probe();
297 if (psurge_type != PSURGE_DUAL) {
298 psurge_quad_init();
299
300 ncpus = 4;
301
302 smp_ops->give_timebase = smp_generic_give_timebase;
303 smp_ops->take_timebase = smp_generic_take_timebase;
304 } else {
305 iounmap(quad_base);
306 if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
307
308 iounmap(hhead_base);
309 psurge_type = PSURGE_NONE;
310 return;
311 }
312 ncpus = 2;
313 }
314
315 if (psurge_secondary_ipi_init())
316 return;
317
318 psurge_start = ioremap(PSURGE_START, 4);
319 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
320
321
322
323
324
325
326 if (ncpus > NR_CPUS)
327 ncpus = NR_CPUS;
328 for (i = 1; i < ncpus ; ++i)
329 set_cpu_present(i, true);
330
331 if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
332}
333
334static int __init smp_psurge_kick_cpu(int nr)
335{
336 unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
337 unsigned long a, flags;
338 int i, j;
339
340
341
342
343
344 extern volatile unsigned int cpu_callin_map[NR_CPUS];
345
346
347 for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
348 asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
349 asm volatile("sync");
350
351 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
352
353
354 local_irq_save(flags);
355
356 out_be32(psurge_start, start);
357 mb();
358
359 psurge_set_ipi(nr);
360
361
362
363
364 for (i = 0; i < 2000; ++i)
365 asm volatile("nop" : : : "memory");
366 psurge_clr_ipi(nr);
367
368
369
370
371
372
373 for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) {
374 for (j = 1; j < 10000; j++)
375 asm volatile("nop" : : : "memory");
376 asm volatile("sync" : : : "memory");
377 }
378 if (!cpu_callin_map[nr])
379 goto stuck;
380
381
382 if (psurge_type == PSURGE_DUAL) {
383 while(!tb_req)
384 barrier();
385 tb_req = 0;
386 mb();
387 timebase = get_tb();
388 mb();
389 while (timebase)
390 barrier();
391 mb();
392 }
393 stuck:
394
395 if (psurge_type == PSURGE_DUAL)
396 psurge_set_ipi(1);
397
398 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
399
400 return 0;
401}
402
403static void __init smp_psurge_setup_cpu(int cpu_nr)
404{
405 unsigned long flags = IRQF_PERCPU | IRQF_NO_THREAD;
406 int irq;
407
408 if (cpu_nr != 0 || !psurge_start)
409 return;
410
411
412
413 out_be32(psurge_start, 0x100);
414 irq = irq_create_mapping(NULL, 30);
415 if (request_irq(irq, psurge_ipi_intr, flags, "primary IPI", NULL))
416 printk(KERN_ERR "Couldn't get primary IPI interrupt");
417}
418
419void __init smp_psurge_take_timebase(void)
420{
421 if (psurge_type != PSURGE_DUAL)
422 return;
423
424 tb_req = 1;
425 mb();
426 while (!timebase)
427 barrier();
428 mb();
429 set_tb(timebase >> 32, timebase & 0xffffffff);
430 timebase = 0;
431 mb();
432 set_dec(tb_ticks_per_jiffy/2);
433}
434
435void __init smp_psurge_give_timebase(void)
436{
437
438}
439
440
441struct smp_ops_t psurge_smp_ops = {
442 .message_pass = NULL,
443 .cause_ipi = smp_psurge_cause_ipi,
444 .cause_nmi_ipi = NULL,
445 .probe = smp_psurge_probe,
446 .kick_cpu = smp_psurge_kick_cpu,
447 .setup_cpu = smp_psurge_setup_cpu,
448 .give_timebase = smp_psurge_give_timebase,
449 .take_timebase = smp_psurge_take_timebase,
450};
451#endif
452
453
454
455
456
457
458static void smp_core99_give_timebase(void)
459{
460 unsigned long flags;
461
462 local_irq_save(flags);
463
464 while(!tb_req)
465 barrier();
466 tb_req = 0;
467 (*pmac_tb_freeze)(1);
468 mb();
469 timebase = get_tb();
470 mb();
471 while (timebase)
472 barrier();
473 mb();
474 (*pmac_tb_freeze)(0);
475 mb();
476
477 local_irq_restore(flags);
478}
479
480
481static void smp_core99_take_timebase(void)
482{
483 unsigned long flags;
484
485 local_irq_save(flags);
486
487 tb_req = 1;
488 mb();
489 while (!timebase)
490 barrier();
491 mb();
492 set_tb(timebase >> 32, timebase & 0xffffffff);
493 timebase = 0;
494 mb();
495
496 local_irq_restore(flags);
497}
498
499#ifdef CONFIG_PPC64
500
501
502
503static struct pmac_i2c_bus *pmac_tb_clock_chip_host;
504static u8 pmac_tb_pulsar_addr;
505
506static void smp_core99_cypress_tb_freeze(int freeze)
507{
508 u8 data;
509 int rc;
510
511
512
513
514 pmac_i2c_setmode(pmac_tb_clock_chip_host,
515 pmac_i2c_mode_combined);
516 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
517 0xd0 | pmac_i2c_read,
518 1, 0x81, &data, 1);
519 if (rc != 0)
520 goto bail;
521
522 data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
523
524 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
525 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
526 0xd0 | pmac_i2c_write,
527 1, 0x81, &data, 1);
528
529 bail:
530 if (rc != 0) {
531 printk("Cypress Timebase %s rc: %d\n",
532 freeze ? "freeze" : "unfreeze", rc);
533 panic("Timebase freeze failed !\n");
534 }
535}
536
537
538static void smp_core99_pulsar_tb_freeze(int freeze)
539{
540 u8 data;
541 int rc;
542
543 pmac_i2c_setmode(pmac_tb_clock_chip_host,
544 pmac_i2c_mode_combined);
545 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
546 pmac_tb_pulsar_addr | pmac_i2c_read,
547 1, 0x2e, &data, 1);
548 if (rc != 0)
549 goto bail;
550
551 data = (data & 0x88) | (freeze ? 0x11 : 0x22);
552
553 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
554 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
555 pmac_tb_pulsar_addr | pmac_i2c_write,
556 1, 0x2e, &data, 1);
557 bail:
558 if (rc != 0) {
559 printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
560 freeze ? "freeze" : "unfreeze", rc);
561 panic("Timebase freeze failed !\n");
562 }
563}
564
565static void __init smp_core99_setup_i2c_hwsync(int ncpus)
566{
567 struct device_node *cc = NULL;
568 struct device_node *p;
569 const char *name = NULL;
570 const u32 *reg;
571 int ok;
572
573
574 for_each_node_by_name(cc, "i2c-hwclock") {
575 p = of_get_parent(cc);
576 ok = p && of_device_is_compatible(p, "uni-n-i2c");
577 of_node_put(p);
578 if (!ok)
579 continue;
580
581 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
582 if (pmac_tb_clock_chip_host == NULL)
583 continue;
584 reg = of_get_property(cc, "reg", NULL);
585 if (reg == NULL)
586 continue;
587 switch (*reg) {
588 case 0xd2:
589 if (of_device_is_compatible(cc,"pulsar-legacy-slewing")) {
590 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
591 pmac_tb_pulsar_addr = 0xd2;
592 name = "Pulsar";
593 } else if (of_device_is_compatible(cc, "cy28508")) {
594 pmac_tb_freeze = smp_core99_cypress_tb_freeze;
595 name = "Cypress";
596 }
597 break;
598 case 0xd4:
599 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
600 pmac_tb_pulsar_addr = 0xd4;
601 name = "Pulsar";
602 break;
603 }
604 if (pmac_tb_freeze != NULL)
605 break;
606 }
607 if (pmac_tb_freeze != NULL) {
608
609 if (pmac_i2c_open(pmac_tb_clock_chip_host, 1)) {
610 printk(KERN_ERR "Failed top open i2c bus for clock"
611 " sync, fallback to software sync !\n");
612 goto no_i2c_sync;
613 }
614 printk(KERN_INFO "Processor timebase sync using %s i2c clock\n",
615 name);
616 return;
617 }
618 no_i2c_sync:
619 pmac_tb_freeze = NULL;
620 pmac_tb_clock_chip_host = NULL;
621}
622
623
624
625
626
627
628
629static void smp_core99_pfunc_tb_freeze(int freeze)
630{
631 struct device_node *cpus;
632 struct pmf_args args;
633
634 cpus = of_find_node_by_path("/cpus");
635 BUG_ON(cpus == NULL);
636 args.count = 1;
637 args.u[0].v = !freeze;
638 pmf_call_function(cpus, "cpu-timebase", &args);
639 of_node_put(cpus);
640}
641
642#else
643
644
645
646
647
648static unsigned int core99_tb_gpio;
649
650static void smp_core99_gpio_tb_freeze(int freeze)
651{
652 if (freeze)
653 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
654 else
655 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
656 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
657}
658
659
660#endif
661
662static void core99_init_caches(int cpu)
663{
664#ifndef CONFIG_PPC64
665
666 static long int core99_l2_cache;
667 static long int core99_l3_cache;
668
669 if (!cpu_has_feature(CPU_FTR_L2CR))
670 return;
671
672 if (cpu == 0) {
673 core99_l2_cache = _get_L2CR();
674 printk("CPU0: L2CR is %lx\n", core99_l2_cache);
675 } else {
676 printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
677 _set_L2CR(0);
678 _set_L2CR(core99_l2_cache);
679 printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
680 }
681
682 if (!cpu_has_feature(CPU_FTR_L3CR))
683 return;
684
685 if (cpu == 0){
686 core99_l3_cache = _get_L3CR();
687 printk("CPU0: L3CR is %lx\n", core99_l3_cache);
688 } else {
689 printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
690 _set_L3CR(0);
691 _set_L3CR(core99_l3_cache);
692 printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
693 }
694#endif
695}
696
697static void __init smp_core99_setup(int ncpus)
698{
699#ifdef CONFIG_PPC64
700
701
702 if (of_machine_is_compatible("PowerMac7,2") ||
703 of_machine_is_compatible("PowerMac7,3") ||
704 of_machine_is_compatible("RackMac3,1"))
705 smp_core99_setup_i2c_hwsync(ncpus);
706
707
708 if (pmac_tb_freeze == NULL) {
709 struct device_node *cpus =
710 of_find_node_by_path("/cpus");
711 if (cpus &&
712 of_get_property(cpus, "platform-cpu-timebase", NULL)) {
713 pmac_tb_freeze = smp_core99_pfunc_tb_freeze;
714 printk(KERN_INFO "Processor timebase sync using"
715 " platform function\n");
716 }
717 }
718
719#else
720
721
722 if (pmac_tb_freeze == NULL && !of_machine_is_compatible("MacRISC4")) {
723 struct device_node *cpu;
724 const u32 *tbprop = NULL;
725
726 core99_tb_gpio = KL_GPIO_TB_ENABLE;
727 cpu = of_find_node_by_type(NULL, "cpu");
728 if (cpu != NULL) {
729 tbprop = of_get_property(cpu, "timebase-enable", NULL);
730 if (tbprop)
731 core99_tb_gpio = *tbprop;
732 of_node_put(cpu);
733 }
734 pmac_tb_freeze = smp_core99_gpio_tb_freeze;
735 printk(KERN_INFO "Processor timebase sync using"
736 " GPIO 0x%02x\n", core99_tb_gpio);
737 }
738
739#endif
740
741
742 if (pmac_tb_freeze == NULL) {
743 smp_ops->give_timebase = smp_generic_give_timebase;
744 smp_ops->take_timebase = smp_generic_take_timebase;
745 printk(KERN_INFO "Processor timebase sync using software\n");
746 }
747
748#ifndef CONFIG_PPC64
749 {
750 int i;
751
752
753 for (i = 1; i < ncpus; ++i)
754 set_hard_smp_processor_id(i, i);
755 }
756#endif
757
758
759 if (!of_machine_is_compatible("MacRISC4"))
760 powersave_nap = 0;
761}
762
763static void __init smp_core99_probe(void)
764{
765 struct device_node *cpus;
766 int ncpus = 0;
767
768 if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
769
770
771 for_each_node_by_type(cpus, "cpu")
772 ++ncpus;
773
774 printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
775
776
777 if (ncpus <= 1)
778 return;
779
780
781
782
783 pmac_pfunc_base_install();
784 pmac_i2c_init();
785
786
787 smp_core99_setup(ncpus);
788
789
790 mpic_request_ipis();
791
792
793 core99_init_caches(0);
794}
795
796static int smp_core99_kick_cpu(int nr)
797{
798 unsigned int save_vector;
799 unsigned long target, flags;
800 unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
801
802 if (nr < 0 || nr > 3)
803 return -ENOENT;
804
805 if (ppc_md.progress)
806 ppc_md.progress("smp_core99_kick_cpu", 0x346);
807
808 local_irq_save(flags);
809
810
811 save_vector = *vector;
812
813
814
815
816 target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
817 patch_branch((struct ppc_inst *)vector, target, BRANCH_SET_LINK);
818
819
820 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
821
822
823
824
825
826
827 mdelay(1);
828
829
830 patch_instruction((struct ppc_inst *)vector, ppc_inst(save_vector));
831
832 local_irq_restore(flags);
833 if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
834
835 return 0;
836}
837
838static void smp_core99_setup_cpu(int cpu_nr)
839{
840
841 if (cpu_nr != 0)
842 core99_init_caches(cpu_nr);
843
844
845 mpic_setup_this_cpu();
846}
847
848#ifdef CONFIG_PPC64
849#ifdef CONFIG_HOTPLUG_CPU
850static unsigned int smp_core99_host_open;
851
852static int smp_core99_cpu_prepare(unsigned int cpu)
853{
854 int rc;
855
856
857 if (pmac_tb_clock_chip_host && !smp_core99_host_open) {
858 rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
859 if (rc) {
860 pr_err("Failed to open i2c bus for time sync\n");
861 return notifier_from_errno(rc);
862 }
863 smp_core99_host_open = 1;
864 }
865 return 0;
866}
867
868static int smp_core99_cpu_online(unsigned int cpu)
869{
870
871 if (pmac_tb_clock_chip_host && smp_core99_host_open) {
872 pmac_i2c_close(pmac_tb_clock_chip_host);
873 smp_core99_host_open = 0;
874 }
875 return 0;
876}
877#endif
878
879static void __init smp_core99_bringup_done(void)
880{
881 extern void g5_phy_disable_cpu1(void);
882
883
884 if (pmac_tb_clock_chip_host)
885 pmac_i2c_close(pmac_tb_clock_chip_host);
886
887
888
889
890 if (of_machine_is_compatible("MacRISC4") &&
891 num_online_cpus() < 2) {
892 set_cpu_present(1, false);
893 g5_phy_disable_cpu1();
894 }
895#ifdef CONFIG_HOTPLUG_CPU
896 cpuhp_setup_state_nocalls(CPUHP_POWERPC_PMAC_PREPARE,
897 "powerpc/pmac:prepare", smp_core99_cpu_prepare,
898 NULL);
899 cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "powerpc/pmac:online",
900 smp_core99_cpu_online, NULL);
901#endif
902
903 if (ppc_md.progress)
904 ppc_md.progress("smp_core99_bringup_done", 0x349);
905}
906#endif
907
908#ifdef CONFIG_HOTPLUG_CPU
909
910static int smp_core99_cpu_disable(void)
911{
912 int rc = generic_cpu_disable();
913 if (rc)
914 return rc;
915
916 mpic_cpu_set_priority(0xf);
917
918 return 0;
919}
920
921#ifdef CONFIG_PPC32
922
923static void pmac_cpu_die(void)
924{
925 int cpu = smp_processor_id();
926
927 local_irq_disable();
928 idle_task_exit();
929 pr_debug("CPU%d offline\n", cpu);
930 generic_set_cpu_dead(cpu);
931 smp_wmb();
932 mb();
933 low_cpu_die();
934}
935
936#else
937
938static void pmac_cpu_die(void)
939{
940 int cpu = smp_processor_id();
941
942 local_irq_disable();
943 idle_task_exit();
944
945
946
947
948
949
950
951 printk(KERN_INFO "CPU#%d offline\n", cpu);
952 generic_set_cpu_dead(cpu);
953 smp_wmb();
954
955
956
957
958
959
960
961
962 local_irq_enable();
963
964 while (1) {
965
966 set_dec(0x7fffffff);
967
968
969 power4_idle();
970 }
971}
972
973#endif
974#endif
975
976
977static struct smp_ops_t core99_smp_ops = {
978 .message_pass = smp_mpic_message_pass,
979 .probe = smp_core99_probe,
980#ifdef CONFIG_PPC64
981 .bringup_done = smp_core99_bringup_done,
982#endif
983 .kick_cpu = smp_core99_kick_cpu,
984 .setup_cpu = smp_core99_setup_cpu,
985 .give_timebase = smp_core99_give_timebase,
986 .take_timebase = smp_core99_take_timebase,
987#if defined(CONFIG_HOTPLUG_CPU)
988 .cpu_disable = smp_core99_cpu_disable,
989 .cpu_die = generic_cpu_die,
990#endif
991};
992
993void __init pmac_setup_smp(void)
994{
995 struct device_node *np;
996
997
998 np = of_find_node_by_name(NULL, "uni-n");
999 if (!np)
1000 np = of_find_node_by_name(NULL, "u3");
1001 if (!np)
1002 np = of_find_node_by_name(NULL, "u4");
1003 if (np) {
1004 of_node_put(np);
1005 smp_ops = &core99_smp_ops;
1006 }
1007#ifdef CONFIG_PPC_PMAC32_PSURGE
1008 else {
1009
1010
1011
1012
1013
1014 int cpu;
1015
1016 for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
1017 set_cpu_possible(cpu, true);
1018 smp_ops = &psurge_smp_ops;
1019 }
1020#endif
1021
1022#ifdef CONFIG_HOTPLUG_CPU
1023 ppc_md.cpu_die = pmac_cpu_die;
1024#endif
1025}
1026
1027
1028