Michael Ellerman | 0332c2d | 2006-12-05 17:52:36 +1100 | [diff] [blame] | 1 | /* |
| 2 | * pseries CPU Hotplug infrastructure. |
| 3 | * |
Michael Ellerman | 04da6af | 2006-12-05 17:52:37 +1100 | [diff] [blame^] | 4 | * Split out from arch/powerpc/platforms/pseries/setup.c and |
| 5 | * arch/powerpc/kernel/rtas.c |
Michael Ellerman | 0332c2d | 2006-12-05 17:52:36 +1100 | [diff] [blame] | 6 | * |
| 7 | * Peter Bergner, IBM March 2001. |
| 8 | * Copyright (C) 2001 IBM. |
| 9 | * |
| 10 | * Copyright (C) 2006 Michael Ellerman, IBM Corporation |
| 11 | * |
| 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version |
| 15 | * 2 of the License, or (at your option) any later version. |
| 16 | */ |
| 17 | |
| 18 | #include <linux/kernel.h> |
| 19 | #include <linux/delay.h> |
| 20 | #include <linux/cpu.h> |
| 21 | #include <asm/system.h> |
| 22 | #include <asm/prom.h> |
| 23 | #include <asm/rtas.h> |
| 24 | #include <asm/firmware.h> |
| 25 | #include <asm/machdep.h> |
| 26 | #include <asm/vdso_datapage.h> |
| 27 | #include <asm/pSeries_reconfig.h> |
| 28 | #include "xics.h" |
| 29 | |
| 30 | /* This version can't take the spinlock, because it never returns */ |
| 31 | static struct rtas_args rtas_stop_self_args = { |
| 32 | .token = RTAS_UNKNOWN_SERVICE, |
| 33 | .nargs = 0, |
| 34 | .nret = 1, |
| 35 | .rets = &rtas_stop_self_args.args[0], |
| 36 | }; |
| 37 | |
Michael Ellerman | 04da6af | 2006-12-05 17:52:37 +1100 | [diff] [blame^] | 38 | static void rtas_stop_self(void) |
Michael Ellerman | 0332c2d | 2006-12-05 17:52:36 +1100 | [diff] [blame] | 39 | { |
| 40 | struct rtas_args *args = &rtas_stop_self_args; |
| 41 | |
| 42 | local_irq_disable(); |
| 43 | |
| 44 | BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); |
| 45 | |
| 46 | printk("cpu %u (hwid %u) Ready to die...\n", |
| 47 | smp_processor_id(), hard_smp_processor_id()); |
| 48 | enter_rtas(__pa(args)); |
| 49 | |
| 50 | panic("Alas, I survived.\n"); |
| 51 | } |
| 52 | |
Michael Ellerman | 04da6af | 2006-12-05 17:52:37 +1100 | [diff] [blame^] | 53 | static void pSeries_mach_cpu_die(void) |
| 54 | { |
| 55 | local_irq_disable(); |
| 56 | idle_task_exit(); |
| 57 | xics_teardown_cpu(0); |
| 58 | rtas_stop_self(); |
| 59 | /* Should never get here... */ |
| 60 | BUG(); |
| 61 | for(;;); |
| 62 | } |
| 63 | |
Michael Ellerman | 0332c2d | 2006-12-05 17:52:36 +1100 | [diff] [blame] | 64 | static int __init pseries_cpu_hotplug_init(void) |
| 65 | { |
| 66 | rtas_stop_self_args.token = rtas_token("stop-self"); |
| 67 | |
Michael Ellerman | 04da6af | 2006-12-05 17:52:37 +1100 | [diff] [blame^] | 68 | ppc_md.cpu_die = pSeries_mach_cpu_die; |
| 69 | |
Michael Ellerman | 0332c2d | 2006-12-05 17:52:36 +1100 | [diff] [blame] | 70 | return 0; |
| 71 | } |
| 72 | arch_initcall(pseries_cpu_hotplug_init); |