diff options
author | Hans-Joachim Picht <hans@linux.vnet.ibm.com> | 2009-06-16 10:30:52 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-06-16 10:31:22 +0200 |
commit | 155af2f95f905c830688dd0ca7c7cac4107334fd (patch) | |
tree | 4304a39e713d1594903e838830c4029715cc7a2a /arch/s390/kernel/smp.c | |
parent | c369527f18f8560bd3580be2676cb55b54b02ee6 (diff) | |
download | kernel_samsung_smdk4412-155af2f95f905c830688dd0ca7c7cac4107334fd.zip kernel_samsung_smdk4412-155af2f95f905c830688dd0ca7c7cac4107334fd.tar.gz kernel_samsung_smdk4412-155af2f95f905c830688dd0ca7c7cac4107334fd.tar.bz2 |
[S390] s390: hibernation support for s390
This patch introduces the hibernation backend support to the
s390 architecture. Now it is possible to suspend a mainframe Linux
guest using the following command:
echo disk > /sys/power/state
Signed-off-by: Hans-Joachim Picht <hans@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index cc8c484..fd8e311 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1,7 +1,7 @@ /* * arch/s390/kernel/smp.c * - * Copyright IBM Corp. 1999,2007 + * Copyright IBM Corp. 1999, 2009 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Martin Schwidefsky (schwidefsky@de.ibm.com) * Heiko Carstens (heiko.carstens@de.ibm.com) @@ -1031,6 +1031,42 @@ out: static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show, dispatching_store); +/* + * If the resume kernel runs on another cpu than the suspended kernel, + * we have to switch the cpu IDs in the logical map. + */ +void smp_switch_boot_cpu_in_resume(u32 resume_phys_cpu_id, + struct _lowcore *suspend_lowcore) +{ + int cpu, suspend_cpu_id, resume_cpu_id; + u32 suspend_phys_cpu_id; + + suspend_phys_cpu_id = __cpu_logical_map[suspend_lowcore->cpu_nr]; + suspend_cpu_id = suspend_lowcore->cpu_nr; + + for_each_present_cpu(cpu) { + if (__cpu_logical_map[cpu] == resume_phys_cpu_id) { + resume_cpu_id = cpu; + goto found; + } + } + panic("Could not find resume cpu in logical map.\n"); + +found: + printk("Resume cpu ID: %i/%i\n", resume_phys_cpu_id, resume_cpu_id); + printk("Suspend cpu ID: %i/%i\n", suspend_phys_cpu_id, suspend_cpu_id); + + __cpu_logical_map[resume_cpu_id] = suspend_phys_cpu_id; + __cpu_logical_map[suspend_cpu_id] = resume_phys_cpu_id; + + lowcore_ptr[suspend_cpu_id]->cpu_addr = resume_phys_cpu_id; +} + +u32 smp_get_phys_cpu_id(void) +{ + return __cpu_logical_map[smp_processor_id()]; +} + static int __init topology_init(void) { int cpu; |