| .. | .. |
|---|
| 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 | |
|---|