summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2004-12-21 15:03:07 -0500
committerLen Brown <lenb@dhcppc3.>2004-12-21 15:03:07 -0500
commitddbcdbbde697c9d72a030f2bfaea3ae353ffe72e (patch)
tree6732a54833138106297a8a9ae9ad34063d0d522e
parent6e4aea02e6e148720716412a84117dd647cb431c (diff)
[ACPI] Consolidate code in processor_idle().
Only symbols "exported" are _init(), _exit() and _cst_has_changed() Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.de> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/processor_core.c69
-rw-r--r--drivers/acpi/processor_idle.c117
-rw-r--r--include/acpi/processor.h10
3 files changed, 115 insertions, 81 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 0819fd3d164b..e517a11dc9c6 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -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 file_operations acpi_processor_info_fops = {
struct acpi_processor *processors[NR_CPUS];
struct acpi_processor_errata errata;
-void (*pm_idle_save)(void);
/* --------------------------------------------------------------------------
@@ -325,19 +323,6 @@ acpi_processor_add_fs (
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 @@ acpi_processor_remove_fs (
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 @@ acpi_processor_get_info (
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 @@ acpi_processor_start(
{
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 @@ acpi_processor_start(
"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 @@ acpi_processor_remove (
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 @@ acpi_processor_remove (
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_init (void)
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);
}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 5ca0c957ed68..ed37633c3d71 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -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 @@ module_param_named(max_cstate, max_cstate, uint, 0);
*
* 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 @@ 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
ticks_elapsed (
u32 t1,
@@ -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_cx *cx = NULL;
@@ -730,7 +744,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
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 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr)
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 @@ static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
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);
+}
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 97e86952dbe5..f501eefd8976 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -135,7 +135,7 @@ struct acpi_processor_flags {
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 @@ ssize_t acpi_processor_write_throttling (
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);