Commit 3d92baa9 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Len Brown

[ACPI] make # of performance states dynamic

from Dominik Brodowski
parent 959a91bd
...@@ -53,7 +53,7 @@ MODULE_LICENSE("GPL"); ...@@ -53,7 +53,7 @@ MODULE_LICENSE("GPL");
struct cpufreq_acpi_io { struct cpufreq_acpi_io {
struct acpi_processor_performance acpi_data; struct acpi_processor_performance acpi_data;
struct cpufreq_frequency_table freq_table[ACPI_PROCESSOR_MAX_PERFORMANCE]; struct cpufreq_frequency_table *freq_table;
}; };
static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS];
...@@ -263,6 +263,7 @@ acpi_cpufreq_cpu_init ( ...@@ -263,6 +263,7 @@ acpi_cpufreq_cpu_init (
/* capability check */ /* capability check */
if (data->acpi_data.state_count <= 1) { if (data->acpi_data.state_count <= 1) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No P-States\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No P-States\n"));
result = -ENODEV;
goto err_unreg; goto err_unreg;
} }
if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) ||
...@@ -270,6 +271,14 @@ acpi_cpufreq_cpu_init ( ...@@ -270,6 +271,14 @@ acpi_cpufreq_cpu_init (
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported address space [%d, %d]\n", ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported address space [%d, %d]\n",
(u32) (data->acpi_data.control_register.space_id), (u32) (data->acpi_data.control_register.space_id),
(u32) (data->acpi_data.status_register.space_id))); (u32) (data->acpi_data.status_register.space_id)));
result = -ENODEV;
goto err_unreg;
}
/* alloc freq_table */
data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1), GFP_KERNEL);
if (!data->freq_table) {
result = -ENOMEM;
goto err_unreg; goto err_unreg;
} }
...@@ -298,6 +307,10 @@ acpi_cpufreq_cpu_init ( ...@@ -298,6 +307,10 @@ acpi_cpufreq_cpu_init (
} }
result = cpufreq_frequency_table_cpuinfo(policy, &data->freq_table[0]); result = cpufreq_frequency_table_cpuinfo(policy, &data->freq_table[0]);
if (result) {
goto err_freqfree;
}
printk(KERN_INFO "cpufreq: CPU%u - ACPI performance management activated.\n", printk(KERN_INFO "cpufreq: CPU%u - ACPI performance management activated.\n",
cpu); cpu);
...@@ -310,6 +323,8 @@ acpi_cpufreq_cpu_init ( ...@@ -310,6 +323,8 @@ acpi_cpufreq_cpu_init (
return_VALUE(result); return_VALUE(result);
err_freqfree:
kfree(data->freq_table);
err_unreg: err_unreg:
acpi_processor_unregister_performance(&data->acpi_data, cpu); acpi_processor_unregister_performance(&data->acpi_data, cpu);
err_free: err_free:
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* TBD: * TBD:
* 1. Make # power/performance states dynamic. * 1. Make # power states dynamic.
* 2. Support duty_cycle values that span bit 4. * 2. Support duty_cycle values that span bit 4.
* 3. Optimize by having scheduler determine business instead of * 3. Optimize by having scheduler determine business instead of
* having us try to calculate it here. * having us try to calculate it here.
...@@ -986,14 +986,12 @@ acpi_processor_get_performance_states ( ...@@ -986,14 +986,12 @@ acpi_processor_get_performance_states (
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
pss->package.count)); pss->package.count));
if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) { pr->performance->state_count = pss->package.count;
pr->performance->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE; pr->performance->states = kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, GFP_KERNEL);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, if (!pr->performance->states) {
"Limiting number of states to max (%d)\n", result = -ENOMEM;
ACPI_PROCESSOR_MAX_PERFORMANCE)); goto end;
} }
else
pr->performance->state_count = pss->package.count;
for (i = 0; i < pr->performance->state_count; i++) { for (i = 0; i < pr->performance->state_count; i++) {
...@@ -1009,6 +1007,7 @@ acpi_processor_get_performance_states ( ...@@ -1009,6 +1007,7 @@ acpi_processor_get_performance_states (
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
result = -EFAULT; result = -EFAULT;
kfree(pr->performance->states);
goto end; goto end;
} }
...@@ -1025,6 +1024,7 @@ acpi_processor_get_performance_states ( ...@@ -1025,6 +1024,7 @@ acpi_processor_get_performance_states (
if (!px->core_frequency) { if (!px->core_frequency) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "core_frequency is 0\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "core_frequency is 0\n"));
result = -EFAULT; result = -EFAULT;
kfree(pr->performance->states);
goto end; goto end;
} }
} }
...@@ -1281,6 +1281,7 @@ acpi_processor_unregister_performance ( ...@@ -1281,6 +1281,7 @@ acpi_processor_unregister_performance (
return_VOID; return_VOID;
} }
kfree(pr->performance->states);
pr->performance = NULL; pr->performance = NULL;
acpi_cpufreq_remove_file(pr); acpi_cpufreq_remove_file(pr);
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#define ACPI_PROCESSOR_MAX_C2_LATENCY 100 #define ACPI_PROCESSOR_MAX_C2_LATENCY 100
#define ACPI_PROCESSOR_MAX_C3_LATENCY 1000 #define ACPI_PROCESSOR_MAX_C3_LATENCY 1000
#define ACPI_PROCESSOR_MAX_PERFORMANCE 8
#define ACPI_PROCESSOR_MAX_THROTTLING 16 #define ACPI_PROCESSOR_MAX_THROTTLING 16
#define ACPI_PROCESSOR_MAX_THROTTLE 250 /* 25% */ #define ACPI_PROCESSOR_MAX_THROTTLE 250 /* 25% */
#define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4 #define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4
...@@ -75,7 +73,7 @@ struct acpi_processor_performance { ...@@ -75,7 +73,7 @@ struct acpi_processor_performance {
struct acpi_pct_register control_register; struct acpi_pct_register control_register;
struct acpi_pct_register status_register; struct acpi_pct_register status_register;
unsigned int state_count; unsigned int state_count;
struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; struct acpi_processor_px *states;
/* the _PDC objects passed by the driver, if any */ /* the _PDC objects passed by the driver, if any */
struct acpi_object_list *pdc; struct acpi_object_list *pdc;
......
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