.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * SMP support for power macintosh. |
---|
3 | 4 | * |
---|
.. | .. |
---|
15 | 16 | * |
---|
16 | 17 | * Support for DayStar quad CPU cards |
---|
17 | 18 | * Copyright (C) XLR8, Inc. 1994-2000 |
---|
18 | | - * |
---|
19 | | - * This program is free software; you can redistribute it and/or |
---|
20 | | - * modify it under the terms of the GNU General Public License |
---|
21 | | - * as published by the Free Software Foundation; either version |
---|
22 | | - * 2 of the License, or (at your option) any later version. |
---|
23 | 19 | */ |
---|
24 | 20 | #include <linux/kernel.h> |
---|
25 | 21 | #include <linux/sched.h> |
---|
.. | .. |
---|
34 | 30 | #include <linux/hardirq.h> |
---|
35 | 31 | #include <linux/cpu.h> |
---|
36 | 32 | #include <linux/compiler.h> |
---|
| 33 | +#include <linux/pgtable.h> |
---|
37 | 34 | |
---|
38 | 35 | #include <asm/ptrace.h> |
---|
39 | 36 | #include <linux/atomic.h> |
---|
40 | 37 | #include <asm/code-patching.h> |
---|
41 | 38 | #include <asm/irq.h> |
---|
42 | 39 | #include <asm/page.h> |
---|
43 | | -#include <asm/pgtable.h> |
---|
44 | 40 | #include <asm/sections.h> |
---|
45 | 41 | #include <asm/io.h> |
---|
46 | 42 | #include <asm/prom.h> |
---|
.. | .. |
---|
53 | 49 | #include <asm/keylargo.h> |
---|
54 | 50 | #include <asm/pmac_low_i2c.h> |
---|
55 | 51 | #include <asm/pmac_pfunc.h> |
---|
| 52 | +#include <asm/inst.h> |
---|
56 | 53 | |
---|
57 | 54 | #include "pmac.h" |
---|
58 | 55 | |
---|
.. | .. |
---|
273 | 270 | int i, ncpus; |
---|
274 | 271 | struct device_node *dn; |
---|
275 | 272 | |
---|
276 | | - /* We don't do SMP on the PPC601 -- paulus */ |
---|
277 | | - if (PVR_VER(mfspr(SPRN_PVR)) == 1) |
---|
278 | | - return; |
---|
279 | | - |
---|
280 | 273 | /* |
---|
281 | 274 | * The powersurge cpu board can be used in the generation |
---|
282 | 275 | * of powermacs that have a socket for an upgradeable cpu card, |
---|
.. | .. |
---|
403 | 396 | return 0; |
---|
404 | 397 | } |
---|
405 | 398 | |
---|
406 | | -static struct irqaction psurge_irqaction = { |
---|
407 | | - .handler = psurge_ipi_intr, |
---|
408 | | - .flags = IRQF_PERCPU | IRQF_NO_THREAD, |
---|
409 | | - .name = "primary IPI", |
---|
410 | | -}; |
---|
411 | | - |
---|
412 | 399 | static void __init smp_psurge_setup_cpu(int cpu_nr) |
---|
413 | 400 | { |
---|
| 401 | + unsigned long flags = IRQF_PERCPU | IRQF_NO_THREAD; |
---|
| 402 | + int irq; |
---|
| 403 | + |
---|
414 | 404 | if (cpu_nr != 0 || !psurge_start) |
---|
415 | 405 | return; |
---|
416 | 406 | |
---|
417 | 407 | /* reset the entry point so if we get another intr we won't |
---|
418 | 408 | * try to startup again */ |
---|
419 | 409 | out_be32(psurge_start, 0x100); |
---|
420 | | - if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction)) |
---|
| 410 | + irq = irq_create_mapping(NULL, 30); |
---|
| 411 | + if (request_irq(irq, psurge_ipi_intr, flags, "primary IPI", NULL)) |
---|
421 | 412 | printk(KERN_ERR "Couldn't get primary IPI interrupt"); |
---|
422 | 413 | } |
---|
423 | 414 | |
---|
.. | .. |
---|
664 | 655 | |
---|
665 | 656 | #endif /* !CONFIG_PPC64 */ |
---|
666 | 657 | |
---|
667 | | -/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ |
---|
668 | | -volatile static long int core99_l2_cache; |
---|
669 | | -volatile static long int core99_l3_cache; |
---|
670 | | - |
---|
671 | 658 | static void core99_init_caches(int cpu) |
---|
672 | 659 | { |
---|
673 | 660 | #ifndef CONFIG_PPC64 |
---|
| 661 | + /* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ |
---|
| 662 | + static long int core99_l2_cache; |
---|
| 663 | + static long int core99_l3_cache; |
---|
| 664 | + |
---|
674 | 665 | if (!cpu_has_feature(CPU_FTR_L2CR)) |
---|
675 | 666 | return; |
---|
676 | 667 | |
---|
.. | .. |
---|
819 | 810 | * b __secondary_start_pmac_0 + nr*8 |
---|
820 | 811 | */ |
---|
821 | 812 | target = (unsigned long) __secondary_start_pmac_0 + nr * 8; |
---|
822 | | - patch_branch(vector, target, BRANCH_SET_LINK); |
---|
| 813 | + patch_branch((struct ppc_inst *)vector, target, BRANCH_SET_LINK); |
---|
823 | 814 | |
---|
824 | 815 | /* Put some life in our friend */ |
---|
825 | 816 | pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); |
---|
.. | .. |
---|
832 | 823 | mdelay(1); |
---|
833 | 824 | |
---|
834 | 825 | /* Restore our exception vector */ |
---|
835 | | - *vector = save_vector; |
---|
836 | | - flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); |
---|
| 826 | + patch_instruction((struct ppc_inst *)vector, ppc_inst(save_vector)); |
---|
837 | 827 | |
---|
838 | 828 | local_irq_restore(flags); |
---|
839 | 829 | if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); |
---|
.. | .. |
---|
921 | 911 | |
---|
922 | 912 | mpic_cpu_set_priority(0xf); |
---|
923 | 913 | |
---|
| 914 | + cleanup_cpu_mmu_context(); |
---|
| 915 | + |
---|
924 | 916 | return 0; |
---|
925 | 917 | } |
---|
926 | 918 | |
---|
927 | 919 | #ifdef CONFIG_PPC32 |
---|
928 | 920 | |
---|
929 | | -static void pmac_cpu_die(void) |
---|
| 921 | +static void pmac_cpu_offline_self(void) |
---|
930 | 922 | { |
---|
931 | 923 | int cpu = smp_processor_id(); |
---|
932 | 924 | |
---|
.. | .. |
---|
936 | 928 | generic_set_cpu_dead(cpu); |
---|
937 | 929 | smp_wmb(); |
---|
938 | 930 | mb(); |
---|
939 | | - low_cpu_die(); |
---|
| 931 | + low_cpu_offline_self(); |
---|
940 | 932 | } |
---|
941 | 933 | |
---|
942 | 934 | #else /* CONFIG_PPC32 */ |
---|
943 | 935 | |
---|
944 | | -static void pmac_cpu_die(void) |
---|
| 936 | +static void pmac_cpu_offline_self(void) |
---|
945 | 937 | { |
---|
946 | 938 | int cpu = smp_processor_id(); |
---|
947 | 939 | |
---|
.. | .. |
---|
1026 | 1018 | #endif /* CONFIG_PPC_PMAC32_PSURGE */ |
---|
1027 | 1019 | |
---|
1028 | 1020 | #ifdef CONFIG_HOTPLUG_CPU |
---|
1029 | | - ppc_md.cpu_die = pmac_cpu_die; |
---|
| 1021 | + smp_ops->cpu_offline_self = pmac_cpu_offline_self; |
---|
1030 | 1022 | #endif |
---|
1031 | 1023 | } |
---|
1032 | 1024 | |
---|