2008-01-30 13:32:54 +01:00
/*
* sleep . c - x86 - specific ACPI sleep support .
*
* Copyright ( C ) 2001 - 2003 Patrick Mochel
* Copyright ( C ) 2001 - 2003 Pavel Machek < pavel @ suse . cz >
*/
# include <linux/acpi.h>
# include <linux/bootmem.h>
# include <linux/dmi.h>
# include <linux/cpumask.h>
# include <asm/smp.h>
/* address in low memory of the wakeup routine. */
2008-02-22 23:11:39 +01:00
unsigned long acpi_wakeup_address ;
2008-01-30 13:32:54 +01:00
unsigned long acpi_realmode_flags ;
extern char wakeup_start , wakeup_end ;
extern unsigned long acpi_copy_wakeup_routine ( unsigned long ) ;
/**
* acpi_save_state_mem - save kernel state
*
* Create an identity mapped page table and copy the wakeup routine to
* low memory .
*/
int acpi_save_state_mem ( void )
{
if ( ! acpi_wakeup_address ) {
printk ( KERN_ERR " Could not allocate memory during boot, S3 disabled \n " ) ;
return - ENOMEM ;
}
memcpy ( ( void * ) acpi_wakeup_address , & wakeup_start ,
& wakeup_end - & wakeup_start ) ;
acpi_copy_wakeup_routine ( acpi_wakeup_address ) ;
return 0 ;
}
/*
* acpi_restore_state - undo effects of acpi_save_state_mem
*/
void acpi_restore_state_mem ( void )
{
}
/**
* acpi_reserve_bootmem - do _very_ early ACPI initialisation
*
* We allocate a page from the first 1 MB of memory for the wakeup
* routine for when we come back from a sleep state . The
* runtime allocator allows specification of < 16 MB pages , but not
* < 1 MB pages .
*/
void __init acpi_reserve_bootmem ( void )
{
if ( ( & wakeup_end - & wakeup_start ) > PAGE_SIZE * 2 ) {
printk ( KERN_ERR
" ACPI: Wakeup code way too big, S3 disabled. \n " ) ;
return ;
}
acpi_wakeup_address = ( unsigned long ) alloc_bootmem_low ( PAGE_SIZE * 2 ) ;
if ( ! acpi_wakeup_address )
printk ( KERN_ERR " ACPI: Cannot allocate lowmem, S3 disabled. \n " ) ;
}
static int __init acpi_sleep_setup ( char * str )
{
while ( ( str ! = NULL ) & & ( * str ! = ' \0 ' ) ) {
if ( strncmp ( str , " s3_bios " , 7 ) = = 0 )
acpi_realmode_flags | = 1 ;
if ( strncmp ( str , " s3_mode " , 7 ) = = 0 )
acpi_realmode_flags | = 2 ;
if ( strncmp ( str , " s3_beep " , 7 ) = = 0 )
acpi_realmode_flags | = 4 ;
str = strchr ( str , ' , ' ) ;
if ( str ! = NULL )
str + = strspn ( str , " , \t " ) ;
}
return 1 ;
}
__setup ( " acpi_sleep= " , acpi_sleep_setup ) ;