]> git.hungrycats.org Git - linux/commitdiff
[ACPI] make # of performance states dynamic
authorDominik Brodowski <linux@dominikbrodowski.de>
Fri, 30 Jan 2004 16:56:37 +0000 (11:56 -0500)
committerLen Brown <lenb@dhcppc3.>
Fri, 30 Jan 2004 16:56:37 +0000 (11:56 -0500)
from Dominik Brodowski

arch/i386/kernel/cpu/cpufreq/acpi.c
drivers/acpi/processor.c
include/acpi/processor.h

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