2005-04-17 02:20:36 +04:00
/*
* 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>
2005-06-26 01:55:06 +04:00
# include <linux/cpu.h>
2005-04-17 02:20:36 +04:00
# include <asm/atomic.h>
# include <asm/tlbflush.h>
2005-06-26 01:55:06 +04:00
/* This is protected by pm_sem semaphore */
static cpumask_t frozen_cpus ;
2005-04-17 02:20:36 +04:00
void disable_nonboot_cpus ( void )
{
2005-06-26 01:55:06 +04:00
int cpu , error ;
2005-04-17 02:20:36 +04:00
2005-06-26 01:55:06 +04:00
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 ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-27 22:43:41 +04:00
BUG_ON ( raw_smp_processor_id ( ) ! = 0 ) ;
2005-06-26 01:55:06 +04:00
if ( error )
panic ( " cpus not sleeping " ) ;
2005-04-17 02:20:36 +04:00
}
void enable_nonboot_cpus ( void )
{
2005-06-26 01:55:06 +04:00
int cpu , error ;
2005-04-17 02:20:36 +04:00
2005-06-26 01:55:06 +04:00
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 ) ;
2005-04-17 02:20:36 +04:00
}