Commit ddbcdbbd authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] Consolidate code in processor_idle().

Only symbols "exported" are _init(), _exit() and _cst_has_changed()
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.de>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 6e4aea02
...@@ -64,7 +64,6 @@ ...@@ -64,7 +64,6 @@
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" #define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
#define ACPI_PROCESSOR_DEVICE_NAME "Processor" #define ACPI_PROCESSOR_DEVICE_NAME "Processor"
#define ACPI_PROCESSOR_FILE_INFO "info" #define ACPI_PROCESSOR_FILE_INFO "info"
#define ACPI_PROCESSOR_FILE_POWER "power"
#define ACPI_PROCESSOR_FILE_THROTTLING "throttling" #define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
#define ACPI_PROCESSOR_FILE_LIMIT "limit" #define ACPI_PROCESSOR_FILE_LIMIT "limit"
#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
...@@ -116,7 +115,6 @@ struct file_operations acpi_processor_info_fops = { ...@@ -116,7 +115,6 @@ struct file_operations acpi_processor_info_fops = {
struct acpi_processor *processors[NR_CPUS]; struct acpi_processor *processors[NR_CPUS];
struct acpi_processor_errata errata; struct acpi_processor_errata errata;
void (*pm_idle_save)(void);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
...@@ -325,19 +323,6 @@ acpi_processor_add_fs ( ...@@ -325,19 +323,6 @@ acpi_processor_add_fs (
entry->owner = THIS_MODULE; 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] */ /* 'throttling' [R/W] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
...@@ -378,7 +363,6 @@ acpi_processor_remove_fs ( ...@@ -378,7 +363,6 @@ acpi_processor_remove_fs (
if (acpi_device_dir(device)) { if (acpi_device_dir(device)) {
remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,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, remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
acpi_device_dir(device)); acpi_device_dir(device));
remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device)); remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device));
...@@ -527,15 +511,6 @@ acpi_processor_get_info ( ...@@ -527,15 +511,6 @@ acpi_processor_get_info (
request_region(pr->throttling.address, 6, "ACPI CPU throttle"); 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 #ifdef CONFIG_CPU_FREQ
acpi_processor_ppc_has_changed(pr); acpi_processor_ppc_has_changed(pr);
#endif #endif
...@@ -551,7 +526,6 @@ acpi_processor_start( ...@@ -551,7 +526,6 @@ acpi_processor_start(
{ {
int result = 0; int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 i = 0;
struct acpi_processor *pr; struct acpi_processor *pr;
ACPI_FUNCTION_TRACE("acpi_processor_start"); ACPI_FUNCTION_TRACE("acpi_processor_start");
...@@ -579,23 +553,7 @@ acpi_processor_start( ...@@ -579,23 +553,7 @@ acpi_processor_start(
"Error installing device notify handler\n")); "Error installing device notify handler\n"));
} }
/* acpi_processor_power_init(pr, device);
* 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;
}
}
if (pr->flags.throttling) { if (pr->flags.throttling) {
printk(KERN_INFO PREFIX "%s [%s] (supports", printk(KERN_INFO PREFIX "%s [%s] (supports",
...@@ -698,16 +656,7 @@ acpi_processor_remove ( ...@@ -698,16 +656,7 @@ acpi_processor_remove (
return_VALUE(-EINVAL); return_VALUE(-EINVAL);
} }
/* Unregister the idle handler when processor #0 is removed. */ acpi_processor_power_exit(pr, device);
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();
}
status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
acpi_processor_notify); acpi_processor_notify);
...@@ -725,16 +674,6 @@ acpi_processor_remove ( ...@@ -725,16 +674,6 @@ acpi_processor_remove (
return_VALUE(0); 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 #ifdef CONFIG_ACPI_HOTPLUG_CPU
/**************************************************************************** /****************************************************************************
* Acpi processor hotplug support * * Acpi processor hotplug support *
...@@ -1019,10 +958,6 @@ acpi_processor_init (void) ...@@ -1019,10 +958,6 @@ acpi_processor_init (void)
acpi_processor_ppc_init(); 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); return_VALUE(0);
} }
......
...@@ -48,10 +48,13 @@ ...@@ -48,10 +48,13 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT #define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME ("acpi_processor") 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 US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
#define C3_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); module_param_named(max_cstate, max_cstate, uint, 0);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
...@@ -64,7 +67,7 @@ module_param_named(max_cstate, max_cstate, uint, 0); ...@@ -64,7 +67,7 @@ module_param_named(max_cstate, max_cstate, uint, 0);
* *
* To skip this limit, boot/load with a large max_cstate limit. * 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) if (max_cstate > ACPI_C_STATES_MAX)
return 0; return 0;
...@@ -80,6 +83,17 @@ int no_c2c3(struct dmi_system_id *id) ...@@ -80,6 +83,17 @@ int no_c2c3(struct dmi_system_id *id)
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 static inline u32
ticks_elapsed ( ticks_elapsed (
u32 t1, u32 t1,
...@@ -136,7 +150,7 @@ acpi_processor_power_activate ( ...@@ -136,7 +150,7 @@ acpi_processor_power_activate (
} }
void acpi_processor_idle (void) static void acpi_processor_idle (void)
{ {
struct acpi_processor *pr = NULL; struct acpi_processor *pr = NULL;
struct acpi_processor_cx *cx = NULL; struct acpi_processor_cx *cx = NULL;
...@@ -730,7 +744,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) ...@@ -730,7 +744,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
return (working); return (working);
} }
int acpi_processor_get_power_info ( static int acpi_processor_get_power_info (
struct acpi_processor *pr) struct acpi_processor *pr)
{ {
unsigned int i; unsigned int i;
...@@ -791,16 +805,17 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr) ...@@ -791,16 +805,17 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr)
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
if (!pr->flags.power_setup_done)
return_VALUE(-ENODEV);
/* Fall back to the default idle loop */ /* Fall back to the default idle loop */
pm_idle = pm_idle_save; pm_idle = pm_idle_save;
pm_idle_save = NULL; synchronize_kernel();
pr->flags.power = 0; pr->flags.power = 0;
result = acpi_processor_get_power_info(pr); result = acpi_processor_get_power_info(pr);
if (pr->flags.power == 1) { if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
pm_idle_save = pm_idle;
pm_idle = acpi_processor_idle; pm_idle = acpi_processor_idle;
}
return_VALUE(result); return_VALUE(result);
} }
...@@ -879,10 +894,96 @@ static int acpi_processor_power_open_fs(struct inode *inode, struct file *file) ...@@ -879,10 +894,96 @@ static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
PDE(inode)->data); PDE(inode)->data);
} }
struct file_operations acpi_processor_power_fops = { static struct file_operations acpi_processor_power_fops = {
.open = acpi_processor_power_open_fs, .open = acpi_processor_power_open_fs,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .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);
}
...@@ -135,7 +135,7 @@ struct acpi_processor_flags { ...@@ -135,7 +135,7 @@ struct acpi_processor_flags {
u8 bm_control:1; u8 bm_control:1;
u8 bm_check:1; u8 bm_check:1;
u8 has_cst:1; u8 has_cst:1;
u8 reserved:2; u8 power_setup_done:1;
}; };
struct acpi_processor { struct acpi_processor {
...@@ -210,12 +210,10 @@ ssize_t acpi_processor_write_throttling ( ...@@ -210,12 +210,10 @@ ssize_t acpi_processor_write_throttling (
extern struct file_operations acpi_processor_throttling_fops; extern struct file_operations acpi_processor_throttling_fops;
/* in processor_idle.c */ /* in processor_idle.c */
struct dmi_system_id; int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device);
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_cst_has_changed (struct acpi_processor *pr); 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 */ /* in processor_thermal.c */
int acpi_processor_get_limit_info (struct acpi_processor *pr); int acpi_processor_get_limit_info (struct acpi_processor *pr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment