forked from Minki/linux
5a72e04df5
Using CPU hotplug to support suspend/resume SMP. Both S3 and S4 use disable/enable_nonboot_cpus API. The S4 part is based on Pavel's original S4 SMP patch. Signed-off-by: Li Shaohua<shaohua.li@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
65 lines
1.3 KiB
C
65 lines
1.3 KiB
C
/*
|
|
* drivers/power/smp.c - Functions for stopping other CPUs.
|
|
*
|
|
* Copyright 2004 Pavel Machek <pavel@suse.cz>
|
|
* Copyright (C) 2002-2003 Nigel Cunningham <ncunningham@clear.net.nz>
|
|
*
|
|
* This file is released under the GPLv2.
|
|
*/
|
|
|
|
#undef DEBUG
|
|
|
|
#include <linux/smp_lock.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/suspend.h>
|
|
#include <linux/module.h>
|
|
#include <linux/cpu.h>
|
|
#include <asm/atomic.h>
|
|
#include <asm/tlbflush.h>
|
|
|
|
/* This is protected by pm_sem semaphore */
|
|
static cpumask_t frozen_cpus;
|
|
|
|
void disable_nonboot_cpus(void)
|
|
{
|
|
int cpu, error;
|
|
|
|
error = 0;
|
|
cpus_clear(frozen_cpus);
|
|
printk("Freezing cpus ...\n");
|
|
for_each_online_cpu(cpu) {
|
|
if (cpu == 0)
|
|
continue;
|
|
error = cpu_down(cpu);
|
|
if (!error) {
|
|
cpu_set(cpu, frozen_cpus);
|
|
printk("CPU%d is down\n", cpu);
|
|
continue;
|
|
}
|
|
printk("Error taking cpu %d down: %d\n", cpu, error);
|
|
}
|
|
BUG_ON(smp_processor_id() != 0);
|
|
if (error)
|
|
panic("cpus not sleeping");
|
|
}
|
|
|
|
void enable_nonboot_cpus(void)
|
|
{
|
|
int cpu, error;
|
|
|
|
printk("Thawing cpus ...\n");
|
|
for_each_cpu_mask(cpu, frozen_cpus) {
|
|
error = smp_prepare_cpu(cpu);
|
|
if (!error)
|
|
error = cpu_up(cpu);
|
|
if (!error) {
|
|
printk("CPU%d is up\n", cpu);
|
|
continue;
|
|
}
|
|
printk("Error taking cpu %d up: %d\n", cpu, error);
|
|
panic("Not enough cpus");
|
|
}
|
|
cpus_clear(frozen_cpus);
|
|
}
|
|
|