/* * 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(raw_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); }