Consolidate code in processor_idle(). Only symbols "exported" are _init(), _exit() and _cst_has_changed(). Signed-off-by: Dominik Brodowski --- drivers/acpi/processor_core.c | 69 ------------------------ drivers/acpi/processor_idle.c | 117 +++++++++++++++++++++++++++++++++++++++--- include/acpi/processor.h | 10 +-- 3 files changed, 115 insertions(+), 81 deletions(-) Index: linux-2.6.10-rc3+bk-acpi/drivers/acpi/processor_core.c =================================================================== --- linux-2.6.10-rc3+bk-acpi.orig/drivers/acpi/processor_core.c 2004-12-14 13:14:15.292876296 +0100 +++ linux-2.6.10-rc3+bk-acpi/drivers/acpi/processor_core.c 2004-12-14 13:14:53.871540092 +0100 @@ -64,7 +64,6 @@ #define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define ACPI_PROCESSOR_DEVICE_NAME "Processor" #define ACPI_PROCESSOR_FILE_INFO "info" -#define ACPI_PROCESSOR_FILE_POWER "power" #define ACPI_PROCESSOR_FILE_THROTTLING "throttling" #define ACPI_PROCESSOR_FILE_LIMIT "limit" #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 @@ -116,7 +115,6 @@ struct acpi_processor *processors[NR_CPUS]; struct acpi_processor_errata errata; -void (*pm_idle_save)(void); /* -------------------------------------------------------------------------- @@ -325,19 +323,6 @@ entry->owner = THIS_MODULE; } - /* 'power' [R] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_POWER)); - else { - entry->proc_fops = &acpi_processor_power_fops; - entry->data = acpi_driver_data(device); - entry->owner = THIS_MODULE; - } - /* 'throttling' [R/W] */ entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); @@ -378,7 +363,6 @@ if (acpi_device_dir(device)) { remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,acpi_device_dir(device)); - remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device)); remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, acpi_device_dir(device)); remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device)); @@ -527,15 +511,6 @@ request_region(pr->throttling.address, 6, "ACPI CPU throttle"); } - if (!errata.smp && (pr->id == 0) && acpi_fadt.cst_cnt) { - status = acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Notifying BIOS of _CST ability failed\n")); - } - } - - acpi_processor_get_power_info(pr); #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr); #endif @@ -551,7 +526,6 @@ { int result = 0; acpi_status status = AE_OK; - u32 i = 0; struct acpi_processor *pr; ACPI_FUNCTION_TRACE("acpi_processor_start"); @@ -579,23 +553,7 @@ "Error installing device notify handler\n")); } - /* - * Install the idle handler if processor power management is supported. - * Note that we use previously set idle handler will be used on - * platforms that only support C1. - */ - if ((pr->flags.power) && (!boot_option_idle_override)) { - printk(KERN_INFO PREFIX "%s [%s] (supports", - acpi_device_name(device), acpi_device_bid(device)); - for (i = 1; i < ACPI_C_STATE_COUNT; i++) - if (pr->power.states[i].valid) - printk(" C%d", i); - printk(")\n"); - if (pr->id == 0) { - pm_idle_save = pm_idle; - pm_idle = acpi_processor_idle; - } - } + acpi_processor_power_init(pr, device); if (pr->flags.throttling) { printk(KERN_INFO PREFIX "%s [%s] (supports", @@ -698,16 +656,7 @@ return_VALUE(-EINVAL); } - /* Unregister the idle handler when processor #0 is removed. */ - if (pr->id == 0) { - pm_idle = pm_idle_save; - /* - * We are about to unload the current idle thread pm callback - * (pm_idle), Wait for all processors to update cached/local - * copies of pm_idle before proceeding. - */ - synchronize_kernel(); - } + acpi_processor_power_exit(pr, device); status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, acpi_processor_notify); @@ -725,16 +674,6 @@ return_VALUE(0); } -static struct dmi_system_id __initdata processor_dmi_table[] = { - { no_c2c3, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }}, - { no_c2c3, "Medion 41700", { - DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), - DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }}, - {}, -}; - #ifdef CONFIG_ACPI_HOTPLUG_CPU /**************************************************************************** * Acpi processor hotplug support * @@ -1019,10 +958,6 @@ acpi_processor_ppc_init(); - dmi_check_system(processor_dmi_table); - if (max_cstate < ACPI_C_STATES_MAX) - printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", max_cstate); - return_VALUE(0); } Index: linux-2.6.10-rc3+bk-acpi/drivers/acpi/processor_idle.c =================================================================== --- linux-2.6.10-rc3+bk-acpi.orig/drivers/acpi/processor_idle.c 2004-12-14 13:13:36.286377712 +0100 +++ linux-2.6.10-rc3+bk-acpi/drivers/acpi/processor_idle.c 2004-12-14 13:14:53.873539810 +0100 @@ -48,10 +48,13 @@ #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME ("acpi_processor") +#define ACPI_PROCESSOR_FILE_POWER "power" + #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ +static void (*pm_idle_save)(void); module_param_named(max_cstate, max_cstate, uint, 0); /* -------------------------------------------------------------------------- @@ -64,7 +67,7 @@ * * To skip this limit, boot/load with a large max_cstate limit. */ -int no_c2c3(struct dmi_system_id *id) +static int no_c2c3(struct dmi_system_id *id) { if (max_cstate > ACPI_C_STATES_MAX) return 0; @@ -80,6 +83,17 @@ +static struct dmi_system_id __initdata processor_power_dmi_table[] = { + { no_c2c3, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }}, + { no_c2c3, "Medion 41700", { + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }}, + {}, +}; + + static inline u32 ticks_elapsed ( u32 t1, @@ -136,7 +150,7 @@ } -void acpi_processor_idle (void) +static void acpi_processor_idle (void) { struct acpi_processor *pr = NULL; struct acpi_processor_cx *cx = NULL; @@ -730,7 +744,7 @@ return (working); } -int acpi_processor_get_power_info ( +static int acpi_processor_get_power_info ( struct acpi_processor *pr) { unsigned int i; @@ -791,16 +805,17 @@ return_VALUE(-ENODEV); } + if (!pr->flags.power_setup_done) + return_VALUE(-ENODEV); + /* Fall back to the default idle loop */ pm_idle = pm_idle_save; - pm_idle_save = NULL; + synchronize_kernel(); pr->flags.power = 0; result = acpi_processor_get_power_info(pr); - if (pr->flags.power == 1) { - pm_idle_save = pm_idle; + if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) pm_idle = acpi_processor_idle; - } return_VALUE(result); } @@ -879,10 +894,96 @@ PDE(inode)->data); } -struct file_operations acpi_processor_power_fops = { +static struct file_operations acpi_processor_power_fops = { .open = acpi_processor_power_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; + +int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) +{ + acpi_status status = 0; + static int first_run = 0; + struct proc_dir_entry *entry = NULL; + unsigned int i; + + ACPI_FUNCTION_TRACE("acpi_processor_power_init"); + + if (!first_run) { + dmi_check_system(processor_power_dmi_table); + if (max_cstate < ACPI_C_STATES_MAX) + printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", max_cstate); + first_run++; + } + + if (!errata.smp && (pr->id == 0) && acpi_fadt.cst_cnt) { + status = acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Notifying BIOS of _CST ability failed\n")); + } + } + + acpi_processor_get_power_info(pr); + + /* + * Install the idle handler if processor power management is supported. + * Note that we use previously set idle handler will be used on + * platforms that only support C1. + */ + if ((pr->flags.power) && (!boot_option_idle_override)) { + printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); + for (i = 1; i <= pr->power.count; i++) + if (pr->power.states[i].valid) + printk(" %d[C%d]", i, pr->power.states[i].type); + printk(")\n"); + + if (pr->id == 0) { + pm_idle_save = pm_idle; + pm_idle = acpi_processor_idle; + } + } + + /* 'power' [R] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_POWER)); + else { + entry->proc_fops = &acpi_processor_power_fops; + entry->data = acpi_driver_data(device); + entry->owner = THIS_MODULE; + } + + pr->flags.power_setup_done = 1; + + return_VALUE(0); +} + +int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device) +{ + ACPI_FUNCTION_TRACE("acpi_processor_power_exit"); + + pr->flags.power_setup_done = 0; + + if (acpi_device_dir(device)) + remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device)); + + /* Unregister the idle handler when processor #0 is removed. */ + if (pr->id == 0) { + pm_idle = pm_idle_save; + + /* + * We are about to unload the current idle thread pm callback + * (pm_idle), Wait for all processors to update cached/local + * copies of pm_idle before proceeding. + */ + synchronize_kernel(); + } + + return_VALUE(0); +} Index: linux-2.6.10-rc3+bk-acpi/include/acpi/processor.h =================================================================== --- linux-2.6.10-rc3+bk-acpi.orig/include/acpi/processor.h 2004-12-14 13:13:36.287377571 +0100 +++ linux-2.6.10-rc3+bk-acpi/include/acpi/processor.h 2004-12-14 13:14:53.873539810 +0100 @@ -135,7 +135,7 @@ u8 bm_control:1; u8 bm_check:1; u8 has_cst:1; - u8 reserved:2; + u8 power_setup_done:1; }; struct acpi_processor { @@ -210,12 +210,10 @@ extern struct file_operations acpi_processor_throttling_fops; /* in processor_idle.c */ -struct dmi_system_id; -void acpi_processor_idle (void); -int acpi_processor_get_power_info (struct acpi_processor *pr); -extern struct file_operations acpi_processor_power_fops; -int no_c2c3(struct dmi_system_id *id); +int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device); int acpi_processor_cst_has_changed (struct acpi_processor *pr); +int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device); + /* in processor_thermal.c */ int acpi_processor_get_limit_info (struct acpi_processor *pr);