diff options
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/elanfreq.c | 42 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k6.c | 41 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 30 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 5 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 147 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_performance.c | 4 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_powersave.c | 4 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_userspace.c | 4 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 7 | ||||
| -rw-r--r-- | include/linux/tick.h | 2 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 11 |
12 files changed, 204 insertions, 106 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index dd097b835839..c24c4a487b7c 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -256,7 +256,8 @@ static u32 get_cur_val(const cpumask_t *mask) | |||
| 256 | * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and | 256 | * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and |
| 257 | * no meaning should be associated with absolute values of these MSRs. | 257 | * no meaning should be associated with absolute values of these MSRs. |
| 258 | */ | 258 | */ |
| 259 | static unsigned int get_measured_perf(unsigned int cpu) | 259 | static unsigned int get_measured_perf(struct cpufreq_policy *policy, |
| 260 | unsigned int cpu) | ||
| 260 | { | 261 | { |
| 261 | union { | 262 | union { |
| 262 | struct { | 263 | struct { |
| @@ -326,7 +327,7 @@ static unsigned int get_measured_perf(unsigned int cpu) | |||
| 326 | 327 | ||
| 327 | #endif | 328 | #endif |
| 328 | 329 | ||
| 329 | retval = per_cpu(drv_data, cpu)->max_freq * perf_percent / 100; | 330 | retval = per_cpu(drv_data, policy->cpu)->max_freq * perf_percent / 100; |
| 330 | 331 | ||
| 331 | put_cpu(); | 332 | put_cpu(); |
| 332 | set_cpus_allowed_ptr(current, &saved_mask); | 333 | set_cpus_allowed_ptr(current, &saved_mask); |
| @@ -785,7 +786,11 @@ static int __init acpi_cpufreq_init(void) | |||
| 785 | if (ret) | 786 | if (ret) |
| 786 | return ret; | 787 | return ret; |
| 787 | 788 | ||
| 788 | return cpufreq_register_driver(&acpi_cpufreq_driver); | 789 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); |
| 790 | if (ret) | ||
| 791 | free_percpu(acpi_perf_data); | ||
| 792 | |||
| 793 | return ret; | ||
| 789 | } | 794 | } |
| 790 | 795 | ||
| 791 | static void __exit acpi_cpufreq_exit(void) | 796 | static void __exit acpi_cpufreq_exit(void) |
| @@ -795,8 +800,6 @@ static void __exit acpi_cpufreq_exit(void) | |||
| 795 | cpufreq_unregister_driver(&acpi_cpufreq_driver); | 800 | cpufreq_unregister_driver(&acpi_cpufreq_driver); |
| 796 | 801 | ||
| 797 | free_percpu(acpi_perf_data); | 802 | free_percpu(acpi_perf_data); |
| 798 | |||
| 799 | return; | ||
| 800 | } | 803 | } |
| 801 | 804 | ||
| 802 | module_param(acpi_pstate_strict, uint, 0644); | 805 | module_param(acpi_pstate_strict, uint, 0644); |
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c index e4a4bf870e94..fe613c93b366 100644 --- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | #include <linux/cpufreq.h> | 25 | #include <linux/cpufreq.h> |
| 26 | 26 | ||
| 27 | #include <asm/msr.h> | 27 | #include <asm/msr.h> |
| 28 | #include <asm/timex.h> | 28 | #include <linux/timex.h> |
| 29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
| 30 | 30 | ||
| 31 | #define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ | 31 | #define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ |
| 32 | #define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ | 32 | #define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ |
| @@ -82,7 +82,7 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) | |||
| 82 | u8 clockspeed_reg; /* Clock Speed Register */ | 82 | u8 clockspeed_reg; /* Clock Speed Register */ |
| 83 | 83 | ||
| 84 | local_irq_disable(); | 84 | local_irq_disable(); |
| 85 | outb_p(0x80,REG_CSCIR); | 85 | outb_p(0x80, REG_CSCIR); |
| 86 | clockspeed_reg = inb_p(REG_CSCDR); | 86 | clockspeed_reg = inb_p(REG_CSCDR); |
| 87 | local_irq_enable(); | 87 | local_irq_enable(); |
| 88 | 88 | ||
| @@ -98,10 +98,10 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /* 33 MHz is not 32 MHz... */ | 100 | /* 33 MHz is not 32 MHz... */ |
| 101 | if ((clockspeed_reg & 0xE0)==0xA0) | 101 | if ((clockspeed_reg & 0xE0) == 0xA0) |
| 102 | return 33000; | 102 | return 33000; |
| 103 | 103 | ||
| 104 | return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000); | 104 | return (1<<((clockspeed_reg & 0xE0) >> 5)) * 1000; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | 107 | ||
| @@ -117,7 +117,7 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) | |||
| 117 | * There is no return value. | 117 | * There is no return value. |
| 118 | */ | 118 | */ |
| 119 | 119 | ||
| 120 | static void elanfreq_set_cpu_state (unsigned int state) | 120 | static void elanfreq_set_cpu_state(unsigned int state) |
| 121 | { | 121 | { |
| 122 | struct cpufreq_freqs freqs; | 122 | struct cpufreq_freqs freqs; |
| 123 | 123 | ||
| @@ -144,20 +144,20 @@ static void elanfreq_set_cpu_state (unsigned int state) | |||
| 144 | */ | 144 | */ |
| 145 | 145 | ||
| 146 | local_irq_disable(); | 146 | local_irq_disable(); |
| 147 | outb_p(0x40,REG_CSCIR); /* Disable hyperspeed mode */ | 147 | outb_p(0x40, REG_CSCIR); /* Disable hyperspeed mode */ |
| 148 | outb_p(0x00,REG_CSCDR); | 148 | outb_p(0x00, REG_CSCDR); |
| 149 | local_irq_enable(); /* wait till internal pipelines and */ | 149 | local_irq_enable(); /* wait till internal pipelines and */ |
| 150 | udelay(1000); /* buffers have cleaned up */ | 150 | udelay(1000); /* buffers have cleaned up */ |
| 151 | 151 | ||
| 152 | local_irq_disable(); | 152 | local_irq_disable(); |
| 153 | 153 | ||
| 154 | /* now, set the CPU clock speed register (0x80) */ | 154 | /* now, set the CPU clock speed register (0x80) */ |
| 155 | outb_p(0x80,REG_CSCIR); | 155 | outb_p(0x80, REG_CSCIR); |
| 156 | outb_p(elan_multiplier[state].val80h,REG_CSCDR); | 156 | outb_p(elan_multiplier[state].val80h, REG_CSCDR); |
| 157 | 157 | ||
| 158 | /* now, the hyperspeed bit in PMU Force Mode Register (0x40) */ | 158 | /* now, the hyperspeed bit in PMU Force Mode Register (0x40) */ |
| 159 | outb_p(0x40,REG_CSCIR); | 159 | outb_p(0x40, REG_CSCIR); |
| 160 | outb_p(elan_multiplier[state].val40h,REG_CSCDR); | 160 | outb_p(elan_multiplier[state].val40h, REG_CSCDR); |
| 161 | udelay(10000); | 161 | udelay(10000); |
| 162 | local_irq_enable(); | 162 | local_irq_enable(); |
| 163 | 163 | ||
| @@ -173,12 +173,12 @@ static void elanfreq_set_cpu_state (unsigned int state) | |||
| 173 | * for the hardware supported by the driver. | 173 | * for the hardware supported by the driver. |
| 174 | */ | 174 | */ |
| 175 | 175 | ||
| 176 | static int elanfreq_verify (struct cpufreq_policy *policy) | 176 | static int elanfreq_verify(struct cpufreq_policy *policy) |
| 177 | { | 177 | { |
| 178 | return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); | 178 | return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | static int elanfreq_target (struct cpufreq_policy *policy, | 181 | static int elanfreq_target(struct cpufreq_policy *policy, |
| 182 | unsigned int target_freq, | 182 | unsigned int target_freq, |
| 183 | unsigned int relation) | 183 | unsigned int relation) |
| 184 | { | 184 | { |
| @@ -205,7 +205,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
| 205 | 205 | ||
| 206 | /* capability check */ | 206 | /* capability check */ |
| 207 | if ((c->x86_vendor != X86_VENDOR_AMD) || | 207 | if ((c->x86_vendor != X86_VENDOR_AMD) || |
| 208 | (c->x86 != 4) || (c->x86_model!=10)) | 208 | (c->x86 != 4) || (c->x86_model != 10)) |
| 209 | return -ENODEV; | 209 | return -ENODEV; |
| 210 | 210 | ||
| 211 | /* max freq */ | 211 | /* max freq */ |
| @@ -213,7 +213,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
| 213 | max_freq = elanfreq_get_cpu_frequency(0); | 213 | max_freq = elanfreq_get_cpu_frequency(0); |
| 214 | 214 | ||
| 215 | /* table init */ | 215 | /* table init */ |
| 216 | for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { | 216 | for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { |
| 217 | if (elanfreq_table[i].frequency > max_freq) | 217 | if (elanfreq_table[i].frequency > max_freq) |
| 218 | elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 218 | elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
| 219 | } | 219 | } |
| @@ -224,7 +224,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
| 224 | 224 | ||
| 225 | result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table); | 225 | result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table); |
| 226 | if (result) | 226 | if (result) |
| 227 | return (result); | 227 | return result; |
| 228 | 228 | ||
| 229 | cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); | 229 | cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); |
| 230 | return 0; | 230 | return 0; |
| @@ -260,7 +260,7 @@ __setup("elanfreq=", elanfreq_setup); | |||
| 260 | #endif | 260 | #endif |
| 261 | 261 | ||
| 262 | 262 | ||
| 263 | static struct freq_attr* elanfreq_attr[] = { | 263 | static struct freq_attr *elanfreq_attr[] = { |
| 264 | &cpufreq_freq_attr_scaling_available_freqs, | 264 | &cpufreq_freq_attr_scaling_available_freqs, |
| 265 | NULL, | 265 | NULL, |
| 266 | }; | 266 | }; |
| @@ -284,9 +284,9 @@ static int __init elanfreq_init(void) | |||
| 284 | 284 | ||
| 285 | /* Test if we have the right hardware */ | 285 | /* Test if we have the right hardware */ |
| 286 | if ((c->x86_vendor != X86_VENDOR_AMD) || | 286 | if ((c->x86_vendor != X86_VENDOR_AMD) || |
| 287 | (c->x86 != 4) || (c->x86_model!=10)) { | 287 | (c->x86 != 4) || (c->x86_model != 10)) { |
| 288 | printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); | 288 | printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); |
| 289 | return -ENODEV; | 289 | return -ENODEV; |
| 290 | } | 290 | } |
| 291 | return cpufreq_register_driver(&elanfreq_driver); | 291 | return cpufreq_register_driver(&elanfreq_driver); |
| 292 | } | 292 | } |
| @@ -298,7 +298,7 @@ static void __exit elanfreq_exit(void) | |||
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | 300 | ||
| 301 | module_param (max_freq, int, 0444); | 301 | module_param(max_freq, int, 0444); |
| 302 | 302 | ||
| 303 | MODULE_LICENSE("GPL"); | 303 | MODULE_LICENSE("GPL"); |
| 304 | MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>"); | 304 | MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>"); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index eb9b62b0830c..b5ced806a316 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c | |||
| @@ -15,12 +15,11 @@ | |||
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | 16 | ||
| 17 | #include <asm/msr.h> | 17 | #include <asm/msr.h> |
| 18 | #include <asm/timex.h> | 18 | #include <linux/timex.h> |
| 19 | #include <asm/io.h> | 19 | #include <linux/io.h> |
| 20 | 20 | ||
| 21 | 21 | #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long | |
| 22 | #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long | 22 | as it is unused */ |
| 23 | as it is unused */ | ||
| 24 | 23 | ||
| 25 | static unsigned int busfreq; /* FSB, in 10 kHz */ | 24 | static unsigned int busfreq; /* FSB, in 10 kHz */ |
| 26 | static unsigned int max_multiplier; | 25 | static unsigned int max_multiplier; |
| @@ -53,7 +52,7 @@ static int powernow_k6_get_cpu_multiplier(void) | |||
| 53 | 52 | ||
| 54 | msrval = POWERNOW_IOPORT + 0x1; | 53 | msrval = POWERNOW_IOPORT + 0x1; |
| 55 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | 54 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ |
| 56 | invalue=inl(POWERNOW_IOPORT + 0x8); | 55 | invalue = inl(POWERNOW_IOPORT + 0x8); |
| 57 | msrval = POWERNOW_IOPORT + 0x0; | 56 | msrval = POWERNOW_IOPORT + 0x0; |
| 58 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ | 57 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ |
| 59 | 58 | ||
| @@ -67,9 +66,9 @@ static int powernow_k6_get_cpu_multiplier(void) | |||
| 67 | * | 66 | * |
| 68 | * Tries to change the PowerNow! multiplier | 67 | * Tries to change the PowerNow! multiplier |
| 69 | */ | 68 | */ |
| 70 | static void powernow_k6_set_state (unsigned int best_i) | 69 | static void powernow_k6_set_state(unsigned int best_i) |
| 71 | { | 70 | { |
| 72 | unsigned long outvalue=0, invalue=0; | 71 | unsigned long outvalue = 0, invalue = 0; |
| 73 | unsigned long msrval; | 72 | unsigned long msrval; |
| 74 | struct cpufreq_freqs freqs; | 73 | struct cpufreq_freqs freqs; |
| 75 | 74 | ||
| @@ -90,10 +89,10 @@ static void powernow_k6_set_state (unsigned int best_i) | |||
| 90 | 89 | ||
| 91 | msrval = POWERNOW_IOPORT + 0x1; | 90 | msrval = POWERNOW_IOPORT + 0x1; |
| 92 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | 91 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ |
| 93 | invalue=inl(POWERNOW_IOPORT + 0x8); | 92 | invalue = inl(POWERNOW_IOPORT + 0x8); |
| 94 | invalue = invalue & 0xf; | 93 | invalue = invalue & 0xf; |
| 95 | outvalue = outvalue | invalue; | 94 | outvalue = outvalue | invalue; |
| 96 | outl(outvalue ,(POWERNOW_IOPORT + 0x8)); | 95 | outl(outvalue , (POWERNOW_IOPORT + 0x8)); |
| 97 | msrval = POWERNOW_IOPORT + 0x0; | 96 | msrval = POWERNOW_IOPORT + 0x0; |
| 98 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ | 97 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ |
| 99 | 98 | ||
| @@ -124,7 +123,7 @@ static int powernow_k6_verify(struct cpufreq_policy *policy) | |||
| 124 | * | 123 | * |
| 125 | * sets a new CPUFreq policy | 124 | * sets a new CPUFreq policy |
| 126 | */ | 125 | */ |
| 127 | static int powernow_k6_target (struct cpufreq_policy *policy, | 126 | static int powernow_k6_target(struct cpufreq_policy *policy, |
| 128 | unsigned int target_freq, | 127 | unsigned int target_freq, |
| 129 | unsigned int relation) | 128 | unsigned int relation) |
| 130 | { | 129 | { |
| @@ -152,7 +151,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
| 152 | busfreq = cpu_khz / max_multiplier; | 151 | busfreq = cpu_khz / max_multiplier; |
| 153 | 152 | ||
| 154 | /* table init */ | 153 | /* table init */ |
| 155 | for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | 154 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { |
| 156 | if (clock_ratio[i].index > max_multiplier) | 155 | if (clock_ratio[i].index > max_multiplier) |
| 157 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; | 156 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; |
| 158 | else | 157 | else |
| @@ -165,7 +164,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
| 165 | 164 | ||
| 166 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); | 165 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); |
| 167 | if (result) | 166 | if (result) |
| 168 | return (result); | 167 | return result; |
| 169 | 168 | ||
| 170 | cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu); | 169 | cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu); |
| 171 | 170 | ||
| @@ -176,8 +175,8 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
| 176 | static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) | 175 | static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) |
| 177 | { | 176 | { |
| 178 | unsigned int i; | 177 | unsigned int i; |
| 179 | for (i=0; i<8; i++) { | 178 | for (i = 0; i < 8; i++) { |
| 180 | if (i==max_multiplier) | 179 | if (i == max_multiplier) |
| 181 | powernow_k6_set_state(i); | 180 | powernow_k6_set_state(i); |
| 182 | } | 181 | } |
| 183 | cpufreq_frequency_table_put_attr(policy->cpu); | 182 | cpufreq_frequency_table_put_attr(policy->cpu); |
| @@ -189,7 +188,7 @@ static unsigned int powernow_k6_get(unsigned int cpu) | |||
| 189 | return busfreq * powernow_k6_get_cpu_multiplier(); | 188 | return busfreq * powernow_k6_get_cpu_multiplier(); |
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | static struct freq_attr* powernow_k6_attr[] = { | 191 | static struct freq_attr *powernow_k6_attr[] = { |
| 193 | &cpufreq_freq_attr_scaling_available_freqs, | 192 | &cpufreq_freq_attr_scaling_available_freqs, |
| 194 | NULL, | 193 | NULL, |
| 195 | }; | 194 | }; |
| @@ -227,7 +226,7 @@ static int __init powernow_k6_init(void) | |||
| 227 | } | 226 | } |
| 228 | 227 | ||
| 229 | if (cpufreq_register_driver(&powernow_k6_driver)) { | 228 | if (cpufreq_register_driver(&powernow_k6_driver)) { |
| 230 | release_region (POWERNOW_IOPORT, 16); | 229 | release_region(POWERNOW_IOPORT, 16); |
| 231 | return -EINVAL; | 230 | return -EINVAL; |
| 232 | } | 231 | } |
| 233 | 232 | ||
| @@ -243,13 +242,13 @@ static int __init powernow_k6_init(void) | |||
| 243 | static void __exit powernow_k6_exit(void) | 242 | static void __exit powernow_k6_exit(void) |
| 244 | { | 243 | { |
| 245 | cpufreq_unregister_driver(&powernow_k6_driver); | 244 | cpufreq_unregister_driver(&powernow_k6_driver); |
| 246 | release_region (POWERNOW_IOPORT, 16); | 245 | release_region(POWERNOW_IOPORT, 16); |
| 247 | } | 246 | } |
| 248 | 247 | ||
| 249 | 248 | ||
| 250 | MODULE_AUTHOR ("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>"); | 249 | MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>"); |
| 251 | MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); | 250 | MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); |
| 252 | MODULE_LICENSE ("GPL"); | 251 | MODULE_LICENSE("GPL"); |
| 253 | 252 | ||
| 254 | module_init(powernow_k6_init); | 253 | module_init(powernow_k6_init); |
| 255 | module_exit(powernow_k6_exit); | 254 | module_exit(powernow_k6_exit); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8a67f16987db..31d6f535a79d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -1467,25 +1467,27 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, | |||
| 1467 | unsigned int target_freq, | 1467 | unsigned int target_freq, |
| 1468 | unsigned int relation) | 1468 | unsigned int relation) |
| 1469 | { | 1469 | { |
| 1470 | int ret; | 1470 | int ret = -EINVAL; |
| 1471 | 1471 | ||
| 1472 | policy = cpufreq_cpu_get(policy->cpu); | 1472 | policy = cpufreq_cpu_get(policy->cpu); |
| 1473 | if (!policy) | 1473 | if (!policy) |
| 1474 | return -EINVAL; | 1474 | goto no_policy; |
| 1475 | 1475 | ||
| 1476 | if (unlikely(lock_policy_rwsem_write(policy->cpu))) | 1476 | if (unlikely(lock_policy_rwsem_write(policy->cpu))) |
| 1477 | return -EINVAL; | 1477 | goto fail; |
| 1478 | 1478 | ||
| 1479 | ret = __cpufreq_driver_target(policy, target_freq, relation); | 1479 | ret = __cpufreq_driver_target(policy, target_freq, relation); |
| 1480 | 1480 | ||
| 1481 | unlock_policy_rwsem_write(policy->cpu); | 1481 | unlock_policy_rwsem_write(policy->cpu); |
| 1482 | 1482 | ||
| 1483 | fail: | ||
| 1483 | cpufreq_cpu_put(policy); | 1484 | cpufreq_cpu_put(policy); |
| 1485 | no_policy: | ||
| 1484 | return ret; | 1486 | return ret; |
| 1485 | } | 1487 | } |
| 1486 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); | 1488 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); |
| 1487 | 1489 | ||
| 1488 | int __cpufreq_driver_getavg(struct cpufreq_policy *policy) | 1490 | int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) |
| 1489 | { | 1491 | { |
| 1490 | int ret = 0; | 1492 | int ret = 0; |
| 1491 | 1493 | ||
| @@ -1493,8 +1495,8 @@ int __cpufreq_driver_getavg(struct cpufreq_policy *policy) | |||
| 1493 | if (!policy) | 1495 | if (!policy) |
| 1494 | return -EINVAL; | 1496 | return -EINVAL; |
| 1495 | 1497 | ||
| 1496 | if (cpu_online(policy->cpu) && cpufreq_driver->getavg) | 1498 | if (cpu_online(cpu) && cpufreq_driver->getavg) |
| 1497 | ret = cpufreq_driver->getavg(policy->cpu); | 1499 | ret = cpufreq_driver->getavg(policy, cpu); |
| 1498 | 1500 | ||
| 1499 | cpufreq_cpu_put(policy); | 1501 | cpufreq_cpu_put(policy); |
| 1500 | return ret; | 1502 | return ret; |
| @@ -1717,13 +1719,17 @@ int cpufreq_update_policy(unsigned int cpu) | |||
| 1717 | { | 1719 | { |
| 1718 | struct cpufreq_policy *data = cpufreq_cpu_get(cpu); | 1720 | struct cpufreq_policy *data = cpufreq_cpu_get(cpu); |
| 1719 | struct cpufreq_policy policy; | 1721 | struct cpufreq_policy policy; |
| 1720 | int ret = 0; | 1722 | int ret; |
| 1721 | 1723 | ||
| 1722 | if (!data) | 1724 | if (!data) { |
| 1723 | return -ENODEV; | 1725 | ret = -ENODEV; |
| 1726 | goto no_policy; | ||
| 1727 | } | ||
| 1724 | 1728 | ||
| 1725 | if (unlikely(lock_policy_rwsem_write(cpu))) | 1729 | if (unlikely(lock_policy_rwsem_write(cpu))) { |
| 1726 | return -EINVAL; | 1730 | ret = -EINVAL; |
| 1731 | goto fail; | ||
| 1732 | } | ||
| 1727 | 1733 | ||
| 1728 | dprintk("updating policy for CPU %u\n", cpu); | 1734 | dprintk("updating policy for CPU %u\n", cpu); |
| 1729 | memcpy(&policy, data, sizeof(struct cpufreq_policy)); | 1735 | memcpy(&policy, data, sizeof(struct cpufreq_policy)); |
| @@ -1750,7 +1756,9 @@ int cpufreq_update_policy(unsigned int cpu) | |||
| 1750 | 1756 | ||
| 1751 | unlock_policy_rwsem_write(cpu); | 1757 | unlock_policy_rwsem_write(cpu); |
| 1752 | 1758 | ||
| 1759 | fail: | ||
| 1753 | cpufreq_cpu_put(data); | 1760 | cpufreq_cpu_put(data); |
| 1761 | no_policy: | ||
| 1754 | return ret; | 1762 | return ret; |
| 1755 | } | 1763 | } |
| 1756 | EXPORT_SYMBOL(cpufreq_update_policy); | 1764 | EXPORT_SYMBOL(cpufreq_update_policy); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index ac0bbf2d234f..e2657837d954 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
| @@ -460,6 +460,7 @@ static void do_dbs_timer(struct work_struct *work) | |||
| 460 | 460 | ||
| 461 | static inline void dbs_timer_init(void) | 461 | static inline void dbs_timer_init(void) |
| 462 | { | 462 | { |
| 463 | init_timer_deferrable(&dbs_work.timer); | ||
| 463 | schedule_delayed_work(&dbs_work, | 464 | schedule_delayed_work(&dbs_work, |
| 464 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 465 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
| 465 | return; | 466 | return; |
| @@ -575,13 +576,15 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 575 | return 0; | 576 | return 0; |
| 576 | } | 577 | } |
| 577 | 578 | ||
| 579 | #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE | ||
| 580 | static | ||
| 581 | #endif | ||
| 578 | struct cpufreq_governor cpufreq_gov_conservative = { | 582 | struct cpufreq_governor cpufreq_gov_conservative = { |
| 579 | .name = "conservative", | 583 | .name = "conservative", |
| 580 | .governor = cpufreq_governor_dbs, | 584 | .governor = cpufreq_governor_dbs, |
| 581 | .max_transition_latency = TRANSITION_LATENCY_LIMIT, | 585 | .max_transition_latency = TRANSITION_LATENCY_LIMIT, |
| 582 | .owner = THIS_MODULE, | 586 | .owner = THIS_MODULE, |
| 583 | }; | 587 | }; |
| 584 | EXPORT_SYMBOL(cpufreq_gov_conservative); | ||
| 585 | 588 | ||
| 586 | static int __init cpufreq_gov_dbs_init(void) | 589 | static int __init cpufreq_gov_dbs_init(void) |
| 587 | { | 590 | { |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 33855cb3cf16..2ab3c12b88af 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
| @@ -18,13 +18,19 @@ | |||
| 18 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
| 19 | #include <linux/kernel_stat.h> | 19 | #include <linux/kernel_stat.h> |
| 20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
| 21 | #include <linux/hrtimer.h> | ||
| 22 | #include <linux/tick.h> | ||
| 23 | #include <linux/ktime.h> | ||
| 21 | 24 | ||
| 22 | /* | 25 | /* |
| 23 | * dbs is used in this file as a shortform for demandbased switching | 26 | * dbs is used in this file as a shortform for demandbased switching |
| 24 | * It helps to keep variable names smaller, simpler | 27 | * It helps to keep variable names smaller, simpler |
| 25 | */ | 28 | */ |
| 26 | 29 | ||
| 30 | #define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10) | ||
| 27 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | 31 | #define DEF_FREQUENCY_UP_THRESHOLD (80) |
| 32 | #define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3) | ||
| 33 | #define MICRO_FREQUENCY_UP_THRESHOLD (95) | ||
| 28 | #define MIN_FREQUENCY_UP_THRESHOLD (11) | 34 | #define MIN_FREQUENCY_UP_THRESHOLD (11) |
| 29 | #define MAX_FREQUENCY_UP_THRESHOLD (100) | 35 | #define MAX_FREQUENCY_UP_THRESHOLD (100) |
| 30 | 36 | ||
| @@ -57,6 +63,7 @@ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; | |||
| 57 | struct cpu_dbs_info_s { | 63 | struct cpu_dbs_info_s { |
| 58 | cputime64_t prev_cpu_idle; | 64 | cputime64_t prev_cpu_idle; |
| 59 | cputime64_t prev_cpu_wall; | 65 | cputime64_t prev_cpu_wall; |
| 66 | cputime64_t prev_cpu_nice; | ||
| 60 | struct cpufreq_policy *cur_policy; | 67 | struct cpufreq_policy *cur_policy; |
| 61 | struct delayed_work work; | 68 | struct delayed_work work; |
| 62 | struct cpufreq_frequency_table *freq_table; | 69 | struct cpufreq_frequency_table *freq_table; |
| @@ -86,21 +93,24 @@ static struct workqueue_struct *kondemand_wq; | |||
| 86 | static struct dbs_tuners { | 93 | static struct dbs_tuners { |
| 87 | unsigned int sampling_rate; | 94 | unsigned int sampling_rate; |
| 88 | unsigned int up_threshold; | 95 | unsigned int up_threshold; |
| 96 | unsigned int down_differential; | ||
| 89 | unsigned int ignore_nice; | 97 | unsigned int ignore_nice; |
| 90 | unsigned int powersave_bias; | 98 | unsigned int powersave_bias; |
| 91 | } dbs_tuners_ins = { | 99 | } dbs_tuners_ins = { |
| 92 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 100 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
| 101 | .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL, | ||
| 93 | .ignore_nice = 0, | 102 | .ignore_nice = 0, |
| 94 | .powersave_bias = 0, | 103 | .powersave_bias = 0, |
| 95 | }; | 104 | }; |
| 96 | 105 | ||
| 97 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu) | 106 | static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, |
| 107 | cputime64_t *wall) | ||
| 98 | { | 108 | { |
| 99 | cputime64_t idle_time; | 109 | cputime64_t idle_time; |
| 100 | cputime64_t cur_jiffies; | 110 | cputime64_t cur_wall_time; |
| 101 | cputime64_t busy_time; | 111 | cputime64_t busy_time; |
| 102 | 112 | ||
| 103 | cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); | 113 | cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); |
| 104 | busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user, | 114 | busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user, |
| 105 | kstat_cpu(cpu).cpustat.system); | 115 | kstat_cpu(cpu).cpustat.system); |
| 106 | 116 | ||
| @@ -113,7 +123,37 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu) | |||
| 113 | kstat_cpu(cpu).cpustat.nice); | 123 | kstat_cpu(cpu).cpustat.nice); |
| 114 | } | 124 | } |
| 115 | 125 | ||
| 116 | idle_time = cputime64_sub(cur_jiffies, busy_time); | 126 | idle_time = cputime64_sub(cur_wall_time, busy_time); |
| 127 | if (wall) | ||
| 128 | *wall = cur_wall_time; | ||
| 129 | |||
| 130 | return idle_time; | ||
| 131 | } | ||
| 132 | |||
| 133 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | ||
| 134 | { | ||
| 135 | u64 idle_time = get_cpu_idle_time_us(cpu, wall); | ||
| 136 | |||
| 137 | if (idle_time == -1ULL) | ||
| 138 | return get_cpu_idle_time_jiffy(cpu, wall); | ||
| 139 | |||
| 140 | if (dbs_tuners_ins.ignore_nice) { | ||
| 141 | cputime64_t cur_nice; | ||
| 142 | unsigned long cur_nice_jiffies; | ||
| 143 | struct cpu_dbs_info_s *dbs_info; | ||
| 144 | |||
| 145 | dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
| 146 | cur_nice = cputime64_sub(kstat_cpu(cpu).cpustat.nice, | ||
| 147 | dbs_info->prev_cpu_nice); | ||
| 148 | /* | ||
| 149 | * Assumption: nice time between sampling periods will be | ||
| 150 | * less than 2^32 jiffies for 32 bit sys | ||
| 151 | */ | ||
| 152 | cur_nice_jiffies = (unsigned long) | ||
| 153 | cputime64_to_jiffies64(cur_nice); | ||
| 154 | dbs_info->prev_cpu_nice = kstat_cpu(cpu).cpustat.nice; | ||
| 155 | return idle_time + jiffies_to_usecs(cur_nice_jiffies); | ||
| 156 | } | ||
| 117 | return idle_time; | 157 | return idle_time; |
| 118 | } | 158 | } |
| 119 | 159 | ||
| @@ -277,8 +317,8 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
| 277 | for_each_online_cpu(j) { | 317 | for_each_online_cpu(j) { |
| 278 | struct cpu_dbs_info_s *dbs_info; | 318 | struct cpu_dbs_info_s *dbs_info; |
| 279 | dbs_info = &per_cpu(cpu_dbs_info, j); | 319 | dbs_info = &per_cpu(cpu_dbs_info, j); |
| 280 | dbs_info->prev_cpu_idle = get_cpu_idle_time(j); | 320 | dbs_info->prev_cpu_idle = get_cpu_idle_time(j, |
| 281 | dbs_info->prev_cpu_wall = get_jiffies_64(); | 321 | &dbs_info->prev_cpu_wall); |
| 282 | } | 322 | } |
| 283 | mutex_unlock(&dbs_mutex); | 323 | mutex_unlock(&dbs_mutex); |
| 284 | 324 | ||
| @@ -334,9 +374,7 @@ static struct attribute_group dbs_attr_group = { | |||
| 334 | 374 | ||
| 335 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | 375 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
| 336 | { | 376 | { |
| 337 | unsigned int idle_ticks, total_ticks; | 377 | unsigned int max_load_freq; |
| 338 | unsigned int load = 0; | ||
| 339 | cputime64_t cur_jiffies; | ||
| 340 | 378 | ||
| 341 | struct cpufreq_policy *policy; | 379 | struct cpufreq_policy *policy; |
| 342 | unsigned int j; | 380 | unsigned int j; |
| @@ -346,13 +384,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 346 | 384 | ||
| 347 | this_dbs_info->freq_lo = 0; | 385 | this_dbs_info->freq_lo = 0; |
| 348 | policy = this_dbs_info->cur_policy; | 386 | policy = this_dbs_info->cur_policy; |
| 349 | cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); | ||
| 350 | total_ticks = (unsigned int) cputime64_sub(cur_jiffies, | ||
| 351 | this_dbs_info->prev_cpu_wall); | ||
| 352 | this_dbs_info->prev_cpu_wall = get_jiffies_64(); | ||
| 353 | 387 | ||
| 354 | if (!total_ticks) | ||
| 355 | return; | ||
| 356 | /* | 388 | /* |
| 357 | * Every sampling_rate, we check, if current idle time is less | 389 | * Every sampling_rate, we check, if current idle time is less |
| 358 | * than 20% (default), then we try to increase frequency | 390 | * than 20% (default), then we try to increase frequency |
| @@ -365,27 +397,44 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 365 | * 5% (default) of current frequency | 397 | * 5% (default) of current frequency |
| 366 | */ | 398 | */ |
| 367 | 399 | ||
| 368 | /* Get Idle Time */ | 400 | /* Get Absolute Load - in terms of freq */ |
| 369 | idle_ticks = UINT_MAX; | 401 | max_load_freq = 0; |
| 402 | |||
| 370 | for_each_cpu_mask_nr(j, policy->cpus) { | 403 | for_each_cpu_mask_nr(j, policy->cpus) { |
| 371 | cputime64_t total_idle_ticks; | ||
| 372 | unsigned int tmp_idle_ticks; | ||
| 373 | struct cpu_dbs_info_s *j_dbs_info; | 404 | struct cpu_dbs_info_s *j_dbs_info; |
| 405 | cputime64_t cur_wall_time, cur_idle_time; | ||
| 406 | unsigned int idle_time, wall_time; | ||
| 407 | unsigned int load, load_freq; | ||
| 408 | int freq_avg; | ||
| 374 | 409 | ||
| 375 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 410 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
| 376 | total_idle_ticks = get_cpu_idle_time(j); | 411 | |
| 377 | tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks, | 412 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); |
| 413 | |||
| 414 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, | ||
| 415 | j_dbs_info->prev_cpu_wall); | ||
| 416 | j_dbs_info->prev_cpu_wall = cur_wall_time; | ||
| 417 | |||
| 418 | idle_time = (unsigned int) cputime64_sub(cur_idle_time, | ||
| 378 | j_dbs_info->prev_cpu_idle); | 419 | j_dbs_info->prev_cpu_idle); |
| 379 | j_dbs_info->prev_cpu_idle = total_idle_ticks; | 420 | j_dbs_info->prev_cpu_idle = cur_idle_time; |
| 421 | |||
| 422 | if (unlikely(!wall_time || wall_time < idle_time)) | ||
| 423 | continue; | ||
| 424 | |||
| 425 | load = 100 * (wall_time - idle_time) / wall_time; | ||
| 426 | |||
| 427 | freq_avg = __cpufreq_driver_getavg(policy, j); | ||
| 428 | if (freq_avg <= 0) | ||
| 429 | freq_avg = policy->cur; | ||
| 380 | 430 | ||
| 381 | if (tmp_idle_ticks < idle_ticks) | 431 | load_freq = load * freq_avg; |
| 382 | idle_ticks = tmp_idle_ticks; | 432 | if (load_freq > max_load_freq) |
| 433 | max_load_freq = load_freq; | ||
| 383 | } | 434 | } |
| 384 | if (likely(total_ticks > idle_ticks)) | ||
| 385 | load = (100 * (total_ticks - idle_ticks)) / total_ticks; | ||
| 386 | 435 | ||
| 387 | /* Check for frequency increase */ | 436 | /* Check for frequency increase */ |
| 388 | if (load > dbs_tuners_ins.up_threshold) { | 437 | if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) { |
| 389 | /* if we are already at full speed then break out early */ | 438 | /* if we are already at full speed then break out early */ |
| 390 | if (!dbs_tuners_ins.powersave_bias) { | 439 | if (!dbs_tuners_ins.powersave_bias) { |
| 391 | if (policy->cur == policy->max) | 440 | if (policy->cur == policy->max) |
| @@ -412,15 +461,13 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 412 | * can support the current CPU usage without triggering the up | 461 | * can support the current CPU usage without triggering the up |
| 413 | * policy. To be safe, we focus 10 points under the threshold. | 462 | * policy. To be safe, we focus 10 points under the threshold. |
| 414 | */ | 463 | */ |
| 415 | if (load < (dbs_tuners_ins.up_threshold - 10)) { | 464 | if (max_load_freq < |
| 416 | unsigned int freq_next, freq_cur; | 465 | (dbs_tuners_ins.up_threshold - dbs_tuners_ins.down_differential) * |
| 417 | 466 | policy->cur) { | |
| 418 | freq_cur = __cpufreq_driver_getavg(policy); | 467 | unsigned int freq_next; |
| 419 | if (!freq_cur) | 468 | freq_next = max_load_freq / |
| 420 | freq_cur = policy->cur; | 469 | (dbs_tuners_ins.up_threshold - |
| 421 | 470 | dbs_tuners_ins.down_differential); | |
| 422 | freq_next = (freq_cur * load) / | ||
| 423 | (dbs_tuners_ins.up_threshold - 10); | ||
| 424 | 471 | ||
| 425 | if (!dbs_tuners_ins.powersave_bias) { | 472 | if (!dbs_tuners_ins.powersave_bias) { |
| 426 | __cpufreq_driver_target(policy, freq_next, | 473 | __cpufreq_driver_target(policy, freq_next, |
| @@ -526,8 +573,8 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 526 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 573 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
| 527 | j_dbs_info->cur_policy = policy; | 574 | j_dbs_info->cur_policy = policy; |
| 528 | 575 | ||
| 529 | j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j); | 576 | j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, |
| 530 | j_dbs_info->prev_cpu_wall = get_jiffies_64(); | 577 | &j_dbs_info->prev_cpu_wall); |
| 531 | } | 578 | } |
| 532 | this_dbs_info->cpu = cpu; | 579 | this_dbs_info->cpu = cpu; |
| 533 | /* | 580 | /* |
| @@ -579,22 +626,42 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 579 | return 0; | 626 | return 0; |
| 580 | } | 627 | } |
| 581 | 628 | ||
| 629 | #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND | ||
| 630 | static | ||
| 631 | #endif | ||
| 582 | struct cpufreq_governor cpufreq_gov_ondemand = { | 632 | struct cpufreq_governor cpufreq_gov_ondemand = { |
| 583 | .name = "ondemand", | 633 | .name = "ondemand", |
| 584 | .governor = cpufreq_governor_dbs, | 634 | .governor = cpufreq_governor_dbs, |
| 585 | .max_transition_latency = TRANSITION_LATENCY_LIMIT, | 635 | .max_transition_latency = TRANSITION_LATENCY_LIMIT, |
| 586 | .owner = THIS_MODULE, | 636 | .owner = THIS_MODULE, |
| 587 | }; | 637 | }; |
| 588 | EXPORT_SYMBOL(cpufreq_gov_ondemand); | ||
| 589 | 638 | ||
| 590 | static int __init cpufreq_gov_dbs_init(void) | 639 | static int __init cpufreq_gov_dbs_init(void) |
| 591 | { | 640 | { |
| 641 | int err; | ||
| 642 | cputime64_t wall; | ||
| 643 | u64 idle_time; | ||
| 644 | int cpu = get_cpu(); | ||
| 645 | |||
| 646 | idle_time = get_cpu_idle_time_us(cpu, &wall); | ||
| 647 | put_cpu(); | ||
| 648 | if (idle_time != -1ULL) { | ||
| 649 | /* Idle micro accounting is supported. Use finer thresholds */ | ||
| 650 | dbs_tuners_ins.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; | ||
| 651 | dbs_tuners_ins.down_differential = | ||
| 652 | MICRO_FREQUENCY_DOWN_DIFFERENTIAL; | ||
| 653 | } | ||
| 654 | |||
| 592 | kondemand_wq = create_workqueue("kondemand"); | 655 | kondemand_wq = create_workqueue("kondemand"); |
| 593 | if (!kondemand_wq) { | 656 | if (!kondemand_wq) { |
| 594 | printk(KERN_ERR "Creation of kondemand failed\n"); | 657 | printk(KERN_ERR "Creation of kondemand failed\n"); |
| 595 | return -EFAULT; | 658 | return -EFAULT; |
| 596 | } | 659 | } |
| 597 | return cpufreq_register_governor(&cpufreq_gov_ondemand); | 660 | err = cpufreq_register_governor(&cpufreq_gov_ondemand); |
| 661 | if (err) | ||
| 662 | destroy_workqueue(kondemand_wq); | ||
| 663 | |||
| 664 | return err; | ||
| 598 | } | 665 | } |
| 599 | 666 | ||
| 600 | static void __exit cpufreq_gov_dbs_exit(void) | 667 | static void __exit cpufreq_gov_dbs_exit(void) |
diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index e8e1451ef1c1..7e2e515087f8 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c | |||
| @@ -36,12 +36,14 @@ static int cpufreq_governor_performance(struct cpufreq_policy *policy, | |||
| 36 | return 0; | 36 | return 0; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | #ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE_MODULE | ||
| 40 | static | ||
| 41 | #endif | ||
| 39 | struct cpufreq_governor cpufreq_gov_performance = { | 42 | struct cpufreq_governor cpufreq_gov_performance = { |
| 40 | .name = "performance", | 43 | .name = "performance", |
| 41 | .governor = cpufreq_governor_performance, | 44 | .governor = cpufreq_governor_performance, |
| 42 | .owner = THIS_MODULE, | 45 | .owner = THIS_MODULE, |
| 43 | }; | 46 | }; |
| 44 | EXPORT_SYMBOL(cpufreq_gov_performance); | ||
| 45 | 47 | ||
| 46 | 48 | ||
| 47 | static int __init cpufreq_gov_performance_init(void) | 49 | static int __init cpufreq_gov_performance_init(void) |
diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index 88d2f44fba48..e6db5faf3eb1 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c | |||
| @@ -35,12 +35,14 @@ static int cpufreq_governor_powersave(struct cpufreq_policy *policy, | |||
| 35 | return 0; | 35 | return 0; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE | ||
| 39 | static | ||
| 40 | #endif | ||
| 38 | struct cpufreq_governor cpufreq_gov_powersave = { | 41 | struct cpufreq_governor cpufreq_gov_powersave = { |
| 39 | .name = "powersave", | 42 | .name = "powersave", |
| 40 | .governor = cpufreq_governor_powersave, | 43 | .governor = cpufreq_governor_powersave, |
| 41 | .owner = THIS_MODULE, | 44 | .owner = THIS_MODULE, |
| 42 | }; | 45 | }; |
| 43 | EXPORT_SYMBOL(cpufreq_gov_powersave); | ||
| 44 | 46 | ||
| 45 | static int __init cpufreq_gov_powersave_init(void) | 47 | static int __init cpufreq_gov_powersave_init(void) |
| 46 | { | 48 | { |
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 32244aa7cc0c..1442bbada053 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c | |||
| @@ -187,6 +187,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, | |||
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | 189 | ||
| 190 | #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE | ||
| 191 | static | ||
| 192 | #endif | ||
| 190 | struct cpufreq_governor cpufreq_gov_userspace = { | 193 | struct cpufreq_governor cpufreq_gov_userspace = { |
| 191 | .name = "userspace", | 194 | .name = "userspace", |
| 192 | .governor = cpufreq_governor_userspace, | 195 | .governor = cpufreq_governor_userspace, |
| @@ -194,7 +197,6 @@ struct cpufreq_governor cpufreq_gov_userspace = { | |||
| 194 | .show_setspeed = show_speed, | 197 | .show_setspeed = show_speed, |
| 195 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
| 196 | }; | 199 | }; |
| 197 | EXPORT_SYMBOL(cpufreq_gov_userspace); | ||
| 198 | 200 | ||
| 199 | static int __init cpufreq_gov_userspace_init(void) | 201 | static int __init cpufreq_gov_userspace_init(void) |
| 200 | { | 202 | { |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 6fd5668aa572..1ee608fd7b77 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -187,7 +187,8 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
| 187 | unsigned int relation); | 187 | unsigned int relation); |
| 188 | 188 | ||
| 189 | 189 | ||
| 190 | extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy); | 190 | extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy, |
| 191 | unsigned int cpu); | ||
| 191 | 192 | ||
| 192 | int cpufreq_register_governor(struct cpufreq_governor *governor); | 193 | int cpufreq_register_governor(struct cpufreq_governor *governor); |
| 193 | void cpufreq_unregister_governor(struct cpufreq_governor *governor); | 194 | void cpufreq_unregister_governor(struct cpufreq_governor *governor); |
| @@ -226,7 +227,9 @@ struct cpufreq_driver { | |||
| 226 | unsigned int (*get) (unsigned int cpu); | 227 | unsigned int (*get) (unsigned int cpu); |
| 227 | 228 | ||
| 228 | /* optional */ | 229 | /* optional */ |
| 229 | unsigned int (*getavg) (unsigned int cpu); | 230 | unsigned int (*getavg) (struct cpufreq_policy *policy, |
| 231 | unsigned int cpu); | ||
| 232 | |||
| 230 | int (*exit) (struct cpufreq_policy *policy); | 233 | int (*exit) (struct cpufreq_policy *policy); |
| 231 | int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); | 234 | int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); |
| 232 | int (*resume) (struct cpufreq_policy *policy); | 235 | int (*resume) (struct cpufreq_policy *policy); |
diff --git a/include/linux/tick.h b/include/linux/tick.h index 8cf8cfe2cc97..98921a3e1aa8 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
| @@ -126,7 +126,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void) | |||
| 126 | return len; | 126 | return len; |
| 127 | } | 127 | } |
| 128 | static inline void tick_nohz_stop_idle(int cpu) { } | 128 | static inline void tick_nohz_stop_idle(int cpu) { } |
| 129 | static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return 0; } | 129 | static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } |
| 130 | # endif /* !NO_HZ */ | 130 | # endif /* !NO_HZ */ |
| 131 | 131 | ||
| 132 | #endif | 132 | #endif |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index cb02324bdb88..a4d219398167 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/profile.h> | 20 | #include <linux/profile.h> |
| 21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 22 | #include <linux/tick.h> | 22 | #include <linux/tick.h> |
| 23 | #include <linux/module.h> | ||
| 23 | 24 | ||
| 24 | #include <asm/irq_regs.h> | 25 | #include <asm/irq_regs.h> |
| 25 | 26 | ||
| @@ -190,9 +191,17 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | |||
| 190 | { | 191 | { |
| 191 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 192 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
| 192 | 193 | ||
| 193 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | 194 | if (!tick_nohz_enabled) |
| 195 | return -1; | ||
| 196 | |||
| 197 | if (ts->idle_active) | ||
| 198 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | ||
| 199 | else | ||
| 200 | *last_update_time = ktime_to_us(ktime_get()); | ||
| 201 | |||
| 194 | return ktime_to_us(ts->idle_sleeptime); | 202 | return ktime_to_us(ts->idle_sleeptime); |
| 195 | } | 203 | } |
| 204 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); | ||
| 196 | 205 | ||
| 197 | /** | 206 | /** |
| 198 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task | 207 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task |
