diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 16:47:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 16:47:21 -0400 |
commit | 7f6c69dcf40a227b8c98e5619367269b427164d7 (patch) | |
tree | 416b47150be16466ed88bb4f6e4abdc1fad7754c | |
parent | 1e5ad9a3b9b78767a2eb1345201e46f41f9457ef (diff) | |
parent | e56a727b023d40d1adf660168883f30f2e6abe0a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
* git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
[CPUFREQ] Make acpi-cpufreq more robust against BIOS freq changes behind our back.
[CPUFREQ] change cpu freq tables to per_cpu variables
[CPUFREQ] fix show_trans_table
[CPUFREQ] Warn when cpufreq_register_notifier called before pure initcalls
[CPUFREQ] Refactor locking in cpufreq_add_dev
[CPUFREQ] more CodingStyle
[CPUFREQ] CodingStyle
[CPUFREQ] Slightly shorten the error paths of cpufreq_suspend/cpufreq_resume
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 10 | ||||
-rw-r--r-- | drivers/acpi/processor_thermal.c | 30 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 129 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 6 |
4 files changed, 88 insertions, 87 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index e2d870de837c..8db8f73503b3 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -339,6 +339,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) | |||
339 | { | 339 | { |
340 | struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu); | 340 | struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu); |
341 | unsigned int freq; | 341 | unsigned int freq; |
342 | unsigned int cached_freq; | ||
342 | 343 | ||
343 | dprintk("get_cur_freq_on_cpu (%d)\n", cpu); | 344 | dprintk("get_cur_freq_on_cpu (%d)\n", cpu); |
344 | 345 | ||
@@ -347,7 +348,16 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) | |||
347 | return 0; | 348 | return 0; |
348 | } | 349 | } |
349 | 350 | ||
351 | cached_freq = data->freq_table[data->acpi_data->state].frequency; | ||
350 | freq = extract_freq(get_cur_val(&cpumask_of_cpu(cpu)), data); | 352 | freq = extract_freq(get_cur_val(&cpumask_of_cpu(cpu)), data); |
353 | if (freq != cached_freq) { | ||
354 | /* | ||
355 | * The dreaded BIOS frequency change behind our back. | ||
356 | * Force set the frequency on next target call. | ||
357 | */ | ||
358 | data->resume = 1; | ||
359 | } | ||
360 | |||
351 | dprintk("cur freq = %u\n", freq); | 361 | dprintk("cur freq = %u\n", freq); |
352 | 362 | ||
353 | return freq; | 363 | return freq; |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 9cb43f52f7b6..649ae99b9216 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -97,7 +97,7 @@ static int acpi_processor_apply_limit(struct acpi_processor *pr) | |||
97 | #define CPUFREQ_THERMAL_MIN_STEP 0 | 97 | #define CPUFREQ_THERMAL_MIN_STEP 0 |
98 | #define CPUFREQ_THERMAL_MAX_STEP 3 | 98 | #define CPUFREQ_THERMAL_MAX_STEP 3 |
99 | 99 | ||
100 | static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS]; | 100 | static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); |
101 | static unsigned int acpi_thermal_cpufreq_is_init = 0; | 101 | static unsigned int acpi_thermal_cpufreq_is_init = 0; |
102 | 102 | ||
103 | static int cpu_has_cpufreq(unsigned int cpu) | 103 | static int cpu_has_cpufreq(unsigned int cpu) |
@@ -113,9 +113,9 @@ static int acpi_thermal_cpufreq_increase(unsigned int cpu) | |||
113 | if (!cpu_has_cpufreq(cpu)) | 113 | if (!cpu_has_cpufreq(cpu)) |
114 | return -ENODEV; | 114 | return -ENODEV; |
115 | 115 | ||
116 | if (cpufreq_thermal_reduction_pctg[cpu] < | 116 | if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) < |
117 | CPUFREQ_THERMAL_MAX_STEP) { | 117 | CPUFREQ_THERMAL_MAX_STEP) { |
118 | cpufreq_thermal_reduction_pctg[cpu]++; | 118 | per_cpu(cpufreq_thermal_reduction_pctg, cpu)++; |
119 | cpufreq_update_policy(cpu); | 119 | cpufreq_update_policy(cpu); |
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
@@ -128,14 +128,14 @@ static int acpi_thermal_cpufreq_decrease(unsigned int cpu) | |||
128 | if (!cpu_has_cpufreq(cpu)) | 128 | if (!cpu_has_cpufreq(cpu)) |
129 | return -ENODEV; | 129 | return -ENODEV; |
130 | 130 | ||
131 | if (cpufreq_thermal_reduction_pctg[cpu] > | 131 | if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) > |
132 | (CPUFREQ_THERMAL_MIN_STEP + 1)) | 132 | (CPUFREQ_THERMAL_MIN_STEP + 1)) |
133 | cpufreq_thermal_reduction_pctg[cpu]--; | 133 | per_cpu(cpufreq_thermal_reduction_pctg, cpu)--; |
134 | else | 134 | else |
135 | cpufreq_thermal_reduction_pctg[cpu] = 0; | 135 | per_cpu(cpufreq_thermal_reduction_pctg, cpu) = 0; |
136 | cpufreq_update_policy(cpu); | 136 | cpufreq_update_policy(cpu); |
137 | /* We reached max freq again and can leave passive mode */ | 137 | /* We reached max freq again and can leave passive mode */ |
138 | return !cpufreq_thermal_reduction_pctg[cpu]; | 138 | return !per_cpu(cpufreq_thermal_reduction_pctg, cpu); |
139 | } | 139 | } |
140 | 140 | ||
141 | static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, | 141 | static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, |
@@ -147,9 +147,10 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, | |||
147 | if (event != CPUFREQ_ADJUST) | 147 | if (event != CPUFREQ_ADJUST) |
148 | goto out; | 148 | goto out; |
149 | 149 | ||
150 | max_freq = | 150 | max_freq = ( |
151 | (policy->cpuinfo.max_freq * | 151 | policy->cpuinfo.max_freq * |
152 | (100 - cpufreq_thermal_reduction_pctg[policy->cpu] * 20)) / 100; | 152 | (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) |
153 | ) / 100; | ||
153 | 154 | ||
154 | cpufreq_verify_within_limits(policy, 0, max_freq); | 155 | cpufreq_verify_within_limits(policy, 0, max_freq); |
155 | 156 | ||
@@ -174,7 +175,7 @@ static int cpufreq_get_cur_state(unsigned int cpu) | |||
174 | if (!cpu_has_cpufreq(cpu)) | 175 | if (!cpu_has_cpufreq(cpu)) |
175 | return 0; | 176 | return 0; |
176 | 177 | ||
177 | return cpufreq_thermal_reduction_pctg[cpu]; | 178 | return per_cpu(cpufreq_thermal_reduction_pctg, cpu); |
178 | } | 179 | } |
179 | 180 | ||
180 | static int cpufreq_set_cur_state(unsigned int cpu, int state) | 181 | static int cpufreq_set_cur_state(unsigned int cpu, int state) |
@@ -182,7 +183,7 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
182 | if (!cpu_has_cpufreq(cpu)) | 183 | if (!cpu_has_cpufreq(cpu)) |
183 | return 0; | 184 | return 0; |
184 | 185 | ||
185 | cpufreq_thermal_reduction_pctg[cpu] = state; | 186 | per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; |
186 | cpufreq_update_policy(cpu); | 187 | cpufreq_update_policy(cpu); |
187 | return 0; | 188 | return 0; |
188 | } | 189 | } |
@@ -191,8 +192,9 @@ void acpi_thermal_cpufreq_init(void) | |||
191 | { | 192 | { |
192 | int i; | 193 | int i; |
193 | 194 | ||
194 | for (i = 0; i < NR_CPUS; i++) | 195 | for (i = 0; i < nr_cpu_ids; i++) |
195 | cpufreq_thermal_reduction_pctg[i] = 0; | 196 | if (cpu_present(i)) |
197 | per_cpu(cpufreq_thermal_reduction_pctg, i) = 0; | ||
196 | 198 | ||
197 | i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, | 199 | i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, |
198 | CPUFREQ_POLICY_NOTIFIER); | 200 | CPUFREQ_POLICY_NOTIFIER); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 35a26a3e5f68..d3575f5ec6d2 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -118,9 +118,11 @@ static void handle_update(struct work_struct *work); | |||
118 | static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); | 118 | static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); |
119 | static struct srcu_notifier_head cpufreq_transition_notifier_list; | 119 | static struct srcu_notifier_head cpufreq_transition_notifier_list; |
120 | 120 | ||
121 | static bool init_cpufreq_transition_notifier_list_called; | ||
121 | static int __init init_cpufreq_transition_notifier_list(void) | 122 | static int __init init_cpufreq_transition_notifier_list(void) |
122 | { | 123 | { |
123 | srcu_init_notifier_head(&cpufreq_transition_notifier_list); | 124 | srcu_init_notifier_head(&cpufreq_transition_notifier_list); |
125 | init_cpufreq_transition_notifier_list_called = true; | ||
124 | return 0; | 126 | return 0; |
125 | } | 127 | } |
126 | pure_initcall(init_cpufreq_transition_notifier_list); | 128 | pure_initcall(init_cpufreq_transition_notifier_list); |
@@ -216,7 +218,7 @@ static void cpufreq_debug_disable_ratelimit(void) | |||
216 | } | 218 | } |
217 | 219 | ||
218 | void cpufreq_debug_printk(unsigned int type, const char *prefix, | 220 | void cpufreq_debug_printk(unsigned int type, const char *prefix, |
219 | const char *fmt, ...) | 221 | const char *fmt, ...) |
220 | { | 222 | { |
221 | char s[256]; | 223 | char s[256]; |
222 | va_list args; | 224 | va_list args; |
@@ -378,7 +380,7 @@ static struct cpufreq_governor *__find_governor(const char *str_governor) | |||
378 | /** | 380 | /** |
379 | * cpufreq_parse_governor - parse a governor string | 381 | * cpufreq_parse_governor - parse a governor string |
380 | */ | 382 | */ |
381 | static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, | 383 | static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, |
382 | struct cpufreq_governor **governor) | 384 | struct cpufreq_governor **governor) |
383 | { | 385 | { |
384 | int err = -EINVAL; | 386 | int err = -EINVAL; |
@@ -446,7 +448,7 @@ extern struct sysdev_class cpu_sysdev_class; | |||
446 | 448 | ||
447 | #define show_one(file_name, object) \ | 449 | #define show_one(file_name, object) \ |
448 | static ssize_t show_##file_name \ | 450 | static ssize_t show_##file_name \ |
449 | (struct cpufreq_policy * policy, char *buf) \ | 451 | (struct cpufreq_policy *policy, char *buf) \ |
450 | { \ | 452 | { \ |
451 | return sprintf (buf, "%u\n", policy->object); \ | 453 | return sprintf (buf, "%u\n", policy->object); \ |
452 | } | 454 | } |
@@ -465,7 +467,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, | |||
465 | */ | 467 | */ |
466 | #define store_one(file_name, object) \ | 468 | #define store_one(file_name, object) \ |
467 | static ssize_t store_##file_name \ | 469 | static ssize_t store_##file_name \ |
468 | (struct cpufreq_policy * policy, const char *buf, size_t count) \ | 470 | (struct cpufreq_policy *policy, const char *buf, size_t count) \ |
469 | { \ | 471 | { \ |
470 | unsigned int ret = -EINVAL; \ | 472 | unsigned int ret = -EINVAL; \ |
471 | struct cpufreq_policy new_policy; \ | 473 | struct cpufreq_policy new_policy; \ |
@@ -490,8 +492,8 @@ store_one(scaling_max_freq,max); | |||
490 | /** | 492 | /** |
491 | * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware | 493 | * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware |
492 | */ | 494 | */ |
493 | static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy, | 495 | static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, |
494 | char *buf) | 496 | char *buf) |
495 | { | 497 | { |
496 | unsigned int cur_freq = __cpufreq_get(policy->cpu); | 498 | unsigned int cur_freq = __cpufreq_get(policy->cpu); |
497 | if (!cur_freq) | 499 | if (!cur_freq) |
@@ -503,8 +505,7 @@ static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy, | |||
503 | /** | 505 | /** |
504 | * show_scaling_governor - show the current policy for the specified CPU | 506 | * show_scaling_governor - show the current policy for the specified CPU |
505 | */ | 507 | */ |
506 | static ssize_t show_scaling_governor (struct cpufreq_policy * policy, | 508 | static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) |
507 | char *buf) | ||
508 | { | 509 | { |
509 | if(policy->policy == CPUFREQ_POLICY_POWERSAVE) | 510 | if(policy->policy == CPUFREQ_POLICY_POWERSAVE) |
510 | return sprintf(buf, "powersave\n"); | 511 | return sprintf(buf, "powersave\n"); |
@@ -519,8 +520,8 @@ static ssize_t show_scaling_governor (struct cpufreq_policy * policy, | |||
519 | /** | 520 | /** |
520 | * store_scaling_governor - store policy for the specified CPU | 521 | * store_scaling_governor - store policy for the specified CPU |
521 | */ | 522 | */ |
522 | static ssize_t store_scaling_governor (struct cpufreq_policy * policy, | 523 | static ssize_t store_scaling_governor(struct cpufreq_policy *policy, |
523 | const char *buf, size_t count) | 524 | const char *buf, size_t count) |
524 | { | 525 | { |
525 | unsigned int ret = -EINVAL; | 526 | unsigned int ret = -EINVAL; |
526 | char str_governor[16]; | 527 | char str_governor[16]; |
@@ -554,7 +555,7 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy, | |||
554 | /** | 555 | /** |
555 | * show_scaling_driver - show the cpufreq driver currently loaded | 556 | * show_scaling_driver - show the cpufreq driver currently loaded |
556 | */ | 557 | */ |
557 | static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf) | 558 | static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf) |
558 | { | 559 | { |
559 | return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name); | 560 | return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name); |
560 | } | 561 | } |
@@ -562,8 +563,8 @@ static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf) | |||
562 | /** | 563 | /** |
563 | * show_scaling_available_governors - show the available CPUfreq governors | 564 | * show_scaling_available_governors - show the available CPUfreq governors |
564 | */ | 565 | */ |
565 | static ssize_t show_scaling_available_governors (struct cpufreq_policy *policy, | 566 | static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, |
566 | char *buf) | 567 | char *buf) |
567 | { | 568 | { |
568 | ssize_t i = 0; | 569 | ssize_t i = 0; |
569 | struct cpufreq_governor *t; | 570 | struct cpufreq_governor *t; |
@@ -585,7 +586,7 @@ out: | |||
585 | /** | 586 | /** |
586 | * show_affected_cpus - show the CPUs affected by each transition | 587 | * show_affected_cpus - show the CPUs affected by each transition |
587 | */ | 588 | */ |
588 | static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf) | 589 | static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) |
589 | { | 590 | { |
590 | ssize_t i = 0; | 591 | ssize_t i = 0; |
591 | unsigned int cpu; | 592 | unsigned int cpu; |
@@ -602,7 +603,7 @@ static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf) | |||
602 | } | 603 | } |
603 | 604 | ||
604 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | 605 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, |
605 | const char *buf, size_t count) | 606 | const char *buf, size_t count) |
606 | { | 607 | { |
607 | unsigned int freq = 0; | 608 | unsigned int freq = 0; |
608 | unsigned int ret; | 609 | unsigned int ret; |
@@ -651,7 +652,7 @@ define_one_rw(scaling_max_freq); | |||
651 | define_one_rw(scaling_governor); | 652 | define_one_rw(scaling_governor); |
652 | define_one_rw(scaling_setspeed); | 653 | define_one_rw(scaling_setspeed); |
653 | 654 | ||
654 | static struct attribute * default_attrs[] = { | 655 | static struct attribute *default_attrs[] = { |
655 | &cpuinfo_min_freq.attr, | 656 | &cpuinfo_min_freq.attr, |
656 | &cpuinfo_max_freq.attr, | 657 | &cpuinfo_max_freq.attr, |
657 | &scaling_min_freq.attr, | 658 | &scaling_min_freq.attr, |
@@ -667,10 +668,10 @@ static struct attribute * default_attrs[] = { | |||
667 | #define to_policy(k) container_of(k,struct cpufreq_policy,kobj) | 668 | #define to_policy(k) container_of(k,struct cpufreq_policy,kobj) |
668 | #define to_attr(a) container_of(a,struct freq_attr,attr) | 669 | #define to_attr(a) container_of(a,struct freq_attr,attr) |
669 | 670 | ||
670 | static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf) | 671 | static ssize_t show(struct kobject *kobj, struct attribute *attr ,char *buf) |
671 | { | 672 | { |
672 | struct cpufreq_policy * policy = to_policy(kobj); | 673 | struct cpufreq_policy *policy = to_policy(kobj); |
673 | struct freq_attr * fattr = to_attr(attr); | 674 | struct freq_attr *fattr = to_attr(attr); |
674 | ssize_t ret = -EINVAL; | 675 | ssize_t ret = -EINVAL; |
675 | policy = cpufreq_cpu_get(policy->cpu); | 676 | policy = cpufreq_cpu_get(policy->cpu); |
676 | if (!policy) | 677 | if (!policy) |
@@ -691,11 +692,11 @@ no_policy: | |||
691 | return ret; | 692 | return ret; |
692 | } | 693 | } |
693 | 694 | ||
694 | static ssize_t store(struct kobject * kobj, struct attribute * attr, | 695 | static ssize_t store(struct kobject *kobj, struct attribute *attr, |
695 | const char * buf, size_t count) | 696 | const char *buf, size_t count) |
696 | { | 697 | { |
697 | struct cpufreq_policy * policy = to_policy(kobj); | 698 | struct cpufreq_policy *policy = to_policy(kobj); |
698 | struct freq_attr * fattr = to_attr(attr); | 699 | struct freq_attr *fattr = to_attr(attr); |
699 | ssize_t ret = -EINVAL; | 700 | ssize_t ret = -EINVAL; |
700 | policy = cpufreq_cpu_get(policy->cpu); | 701 | policy = cpufreq_cpu_get(policy->cpu); |
701 | if (!policy) | 702 | if (!policy) |
@@ -716,9 +717,9 @@ no_policy: | |||
716 | return ret; | 717 | return ret; |
717 | } | 718 | } |
718 | 719 | ||
719 | static void cpufreq_sysfs_release(struct kobject * kobj) | 720 | static void cpufreq_sysfs_release(struct kobject *kobj) |
720 | { | 721 | { |
721 | struct cpufreq_policy * policy = to_policy(kobj); | 722 | struct cpufreq_policy *policy = to_policy(kobj); |
722 | dprintk("last reference is dropped\n"); | 723 | dprintk("last reference is dropped\n"); |
723 | complete(&policy->kobj_unregister); | 724 | complete(&policy->kobj_unregister); |
724 | } | 725 | } |
@@ -740,7 +741,7 @@ static struct kobj_type ktype_cpufreq = { | |||
740 | * | 741 | * |
741 | * Adds the cpufreq interface for a CPU device. | 742 | * Adds the cpufreq interface for a CPU device. |
742 | */ | 743 | */ |
743 | static int cpufreq_add_dev (struct sys_device * sys_dev) | 744 | static int cpufreq_add_dev(struct sys_device *sys_dev) |
744 | { | 745 | { |
745 | unsigned int cpu = sys_dev->id; | 746 | unsigned int cpu = sys_dev->id; |
746 | int ret = 0; | 747 | int ret = 0; |
@@ -800,7 +801,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
800 | ret = cpufreq_driver->init(policy); | 801 | ret = cpufreq_driver->init(policy); |
801 | if (ret) { | 802 | if (ret) { |
802 | dprintk("initialization failed\n"); | 803 | dprintk("initialization failed\n"); |
803 | unlock_policy_rwsem_write(cpu); | ||
804 | goto err_out; | 804 | goto err_out; |
805 | } | 805 | } |
806 | policy->user_policy.min = policy->cpuinfo.min_freq; | 806 | policy->user_policy.min = policy->cpuinfo.min_freq; |
@@ -823,7 +823,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
823 | /* check for existing affected CPUs. They may not be aware | 823 | /* check for existing affected CPUs. They may not be aware |
824 | * of it due to CPU Hotplug. | 824 | * of it due to CPU Hotplug. |
825 | */ | 825 | */ |
826 | managed_policy = cpufreq_cpu_get(j); | 826 | managed_policy = cpufreq_cpu_get(j); // FIXME: Where is this released? What about error paths? |
827 | if (unlikely(managed_policy)) { | 827 | if (unlikely(managed_policy)) { |
828 | 828 | ||
829 | /* Set proper policy_cpu */ | 829 | /* Set proper policy_cpu */ |
@@ -842,14 +842,11 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
842 | ret = sysfs_create_link(&sys_dev->kobj, | 842 | ret = sysfs_create_link(&sys_dev->kobj, |
843 | &managed_policy->kobj, | 843 | &managed_policy->kobj, |
844 | "cpufreq"); | 844 | "cpufreq"); |
845 | if (ret) { | 845 | if (ret) |
846 | unlock_policy_rwsem_write(cpu); | ||
847 | goto err_out_driver_exit; | 846 | goto err_out_driver_exit; |
848 | } | ||
849 | 847 | ||
850 | cpufreq_debug_enable_ratelimit(); | 848 | cpufreq_debug_enable_ratelimit(); |
851 | ret = 0; | 849 | ret = 0; |
852 | unlock_policy_rwsem_write(cpu); | ||
853 | goto err_out_driver_exit; /* call driver->exit() */ | 850 | goto err_out_driver_exit; /* call driver->exit() */ |
854 | } | 851 | } |
855 | } | 852 | } |
@@ -859,33 +856,26 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
859 | /* prepare interface data */ | 856 | /* prepare interface data */ |
860 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, | 857 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, |
861 | "cpufreq"); | 858 | "cpufreq"); |
862 | if (ret) { | 859 | if (ret) |
863 | unlock_policy_rwsem_write(cpu); | ||
864 | goto err_out_driver_exit; | 860 | goto err_out_driver_exit; |
865 | } | 861 | |
866 | /* set up files for this cpu device */ | 862 | /* set up files for this cpu device */ |
867 | drv_attr = cpufreq_driver->attr; | 863 | drv_attr = cpufreq_driver->attr; |
868 | while ((drv_attr) && (*drv_attr)) { | 864 | while ((drv_attr) && (*drv_attr)) { |
869 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | 865 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); |
870 | if (ret) { | 866 | if (ret) |
871 | unlock_policy_rwsem_write(cpu); | ||
872 | goto err_out_driver_exit; | 867 | goto err_out_driver_exit; |
873 | } | ||
874 | drv_attr++; | 868 | drv_attr++; |
875 | } | 869 | } |
876 | if (cpufreq_driver->get){ | 870 | if (cpufreq_driver->get) { |
877 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); | 871 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); |
878 | if (ret) { | 872 | if (ret) |
879 | unlock_policy_rwsem_write(cpu); | ||
880 | goto err_out_driver_exit; | 873 | goto err_out_driver_exit; |
881 | } | ||
882 | } | 874 | } |
883 | if (cpufreq_driver->target){ | 875 | if (cpufreq_driver->target) { |
884 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | 876 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |
885 | if (ret) { | 877 | if (ret) |
886 | unlock_policy_rwsem_write(cpu); | ||
887 | goto err_out_driver_exit; | 878 | goto err_out_driver_exit; |
888 | } | ||
889 | } | 879 | } |
890 | 880 | ||
891 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 881 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
@@ -907,10 +897,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
907 | cpu_sys_dev = get_cpu_sysdev(j); | 897 | cpu_sys_dev = get_cpu_sysdev(j); |
908 | ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, | 898 | ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, |
909 | "cpufreq"); | 899 | "cpufreq"); |
910 | if (ret) { | 900 | if (ret) |
911 | unlock_policy_rwsem_write(cpu); | ||
912 | goto err_out_unregister; | 901 | goto err_out_unregister; |
913 | } | ||
914 | } | 902 | } |
915 | 903 | ||
916 | policy->governor = NULL; /* to assure that the starting sequence is | 904 | policy->governor = NULL; /* to assure that the starting sequence is |
@@ -950,6 +938,7 @@ err_out_driver_exit: | |||
950 | cpufreq_driver->exit(policy); | 938 | cpufreq_driver->exit(policy); |
951 | 939 | ||
952 | err_out: | 940 | err_out: |
941 | unlock_policy_rwsem_write(cpu); | ||
953 | kfree(policy); | 942 | kfree(policy); |
954 | 943 | ||
955 | nomem_out: | 944 | nomem_out: |
@@ -967,7 +956,7 @@ module_out: | |||
967 | * Caller should already have policy_rwsem in write mode for this CPU. | 956 | * Caller should already have policy_rwsem in write mode for this CPU. |
968 | * This routine frees the rwsem before returning. | 957 | * This routine frees the rwsem before returning. |
969 | */ | 958 | */ |
970 | static int __cpufreq_remove_dev (struct sys_device * sys_dev) | 959 | static int __cpufreq_remove_dev(struct sys_device *sys_dev) |
971 | { | 960 | { |
972 | unsigned int cpu = sys_dev->id; | 961 | unsigned int cpu = sys_dev->id; |
973 | unsigned long flags; | 962 | unsigned long flags; |
@@ -1071,7 +1060,7 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) | |||
1071 | } | 1060 | } |
1072 | 1061 | ||
1073 | 1062 | ||
1074 | static int cpufreq_remove_dev (struct sys_device * sys_dev) | 1063 | static int cpufreq_remove_dev(struct sys_device *sys_dev) |
1075 | { | 1064 | { |
1076 | unsigned int cpu = sys_dev->id; | 1065 | unsigned int cpu = sys_dev->id; |
1077 | int retval; | 1066 | int retval; |
@@ -1138,7 +1127,7 @@ unsigned int cpufreq_quick_get(unsigned int cpu) | |||
1138 | cpufreq_cpu_put(policy); | 1127 | cpufreq_cpu_put(policy); |
1139 | } | 1128 | } |
1140 | 1129 | ||
1141 | return (ret_freq); | 1130 | return ret_freq; |
1142 | } | 1131 | } |
1143 | EXPORT_SYMBOL(cpufreq_quick_get); | 1132 | EXPORT_SYMBOL(cpufreq_quick_get); |
1144 | 1133 | ||
@@ -1149,7 +1138,7 @@ static unsigned int __cpufreq_get(unsigned int cpu) | |||
1149 | unsigned int ret_freq = 0; | 1138 | unsigned int ret_freq = 0; |
1150 | 1139 | ||
1151 | if (!cpufreq_driver->get) | 1140 | if (!cpufreq_driver->get) |
1152 | return (ret_freq); | 1141 | return ret_freq; |
1153 | 1142 | ||
1154 | ret_freq = cpufreq_driver->get(cpu); | 1143 | ret_freq = cpufreq_driver->get(cpu); |
1155 | 1144 | ||
@@ -1163,7 +1152,7 @@ static unsigned int __cpufreq_get(unsigned int cpu) | |||
1163 | } | 1152 | } |
1164 | } | 1153 | } |
1165 | 1154 | ||
1166 | return (ret_freq); | 1155 | return ret_freq; |
1167 | } | 1156 | } |
1168 | 1157 | ||
1169 | /** | 1158 | /** |
@@ -1190,7 +1179,7 @@ unsigned int cpufreq_get(unsigned int cpu) | |||
1190 | out_policy: | 1179 | out_policy: |
1191 | cpufreq_cpu_put(policy); | 1180 | cpufreq_cpu_put(policy); |
1192 | out: | 1181 | out: |
1193 | return (ret_freq); | 1182 | return ret_freq; |
1194 | } | 1183 | } |
1195 | EXPORT_SYMBOL(cpufreq_get); | 1184 | EXPORT_SYMBOL(cpufreq_get); |
1196 | 1185 | ||
@@ -1199,7 +1188,7 @@ EXPORT_SYMBOL(cpufreq_get); | |||
1199 | * cpufreq_suspend - let the low level driver prepare for suspend | 1188 | * cpufreq_suspend - let the low level driver prepare for suspend |
1200 | */ | 1189 | */ |
1201 | 1190 | ||
1202 | static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) | 1191 | static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg) |
1203 | { | 1192 | { |
1204 | int cpu = sysdev->id; | 1193 | int cpu = sysdev->id; |
1205 | int ret = 0; | 1194 | int ret = 0; |
@@ -1221,22 +1210,18 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) | |||
1221 | return -EINVAL; | 1210 | return -EINVAL; |
1222 | 1211 | ||
1223 | /* only handle each CPU group once */ | 1212 | /* only handle each CPU group once */ |
1224 | if (unlikely(cpu_policy->cpu != cpu)) { | 1213 | if (unlikely(cpu_policy->cpu != cpu)) |
1225 | cpufreq_cpu_put(cpu_policy); | 1214 | goto out; |
1226 | return 0; | ||
1227 | } | ||
1228 | 1215 | ||
1229 | if (cpufreq_driver->suspend) { | 1216 | if (cpufreq_driver->suspend) { |
1230 | ret = cpufreq_driver->suspend(cpu_policy, pmsg); | 1217 | ret = cpufreq_driver->suspend(cpu_policy, pmsg); |
1231 | if (ret) { | 1218 | if (ret) { |
1232 | printk(KERN_ERR "cpufreq: suspend failed in ->suspend " | 1219 | printk(KERN_ERR "cpufreq: suspend failed in ->suspend " |
1233 | "step on CPU %u\n", cpu_policy->cpu); | 1220 | "step on CPU %u\n", cpu_policy->cpu); |
1234 | cpufreq_cpu_put(cpu_policy); | 1221 | goto out; |
1235 | return ret; | ||
1236 | } | 1222 | } |
1237 | } | 1223 | } |
1238 | 1224 | ||
1239 | |||
1240 | if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS) | 1225 | if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS) |
1241 | goto out; | 1226 | goto out; |
1242 | 1227 | ||
@@ -1270,7 +1255,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) | |||
1270 | 1255 | ||
1271 | out: | 1256 | out: |
1272 | cpufreq_cpu_put(cpu_policy); | 1257 | cpufreq_cpu_put(cpu_policy); |
1273 | return 0; | 1258 | return ret; |
1274 | } | 1259 | } |
1275 | 1260 | ||
1276 | /** | 1261 | /** |
@@ -1281,7 +1266,7 @@ out: | |||
1281 | * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are | 1266 | * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are |
1282 | * restored. | 1267 | * restored. |
1283 | */ | 1268 | */ |
1284 | static int cpufreq_resume(struct sys_device * sysdev) | 1269 | static int cpufreq_resume(struct sys_device *sysdev) |
1285 | { | 1270 | { |
1286 | int cpu = sysdev->id; | 1271 | int cpu = sysdev->id; |
1287 | int ret = 0; | 1272 | int ret = 0; |
@@ -1302,18 +1287,15 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
1302 | return -EINVAL; | 1287 | return -EINVAL; |
1303 | 1288 | ||
1304 | /* only handle each CPU group once */ | 1289 | /* only handle each CPU group once */ |
1305 | if (unlikely(cpu_policy->cpu != cpu)) { | 1290 | if (unlikely(cpu_policy->cpu != cpu)) |
1306 | cpufreq_cpu_put(cpu_policy); | 1291 | goto fail; |
1307 | return 0; | ||
1308 | } | ||
1309 | 1292 | ||
1310 | if (cpufreq_driver->resume) { | 1293 | if (cpufreq_driver->resume) { |
1311 | ret = cpufreq_driver->resume(cpu_policy); | 1294 | ret = cpufreq_driver->resume(cpu_policy); |
1312 | if (ret) { | 1295 | if (ret) { |
1313 | printk(KERN_ERR "cpufreq: resume failed in ->resume " | 1296 | printk(KERN_ERR "cpufreq: resume failed in ->resume " |
1314 | "step on CPU %u\n", cpu_policy->cpu); | 1297 | "step on CPU %u\n", cpu_policy->cpu); |
1315 | cpufreq_cpu_put(cpu_policy); | 1298 | goto fail; |
1316 | return ret; | ||
1317 | } | 1299 | } |
1318 | } | 1300 | } |
1319 | 1301 | ||
@@ -1353,6 +1335,7 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
1353 | 1335 | ||
1354 | out: | 1336 | out: |
1355 | schedule_work(&cpu_policy->update); | 1337 | schedule_work(&cpu_policy->update); |
1338 | fail: | ||
1356 | cpufreq_cpu_put(cpu_policy); | 1339 | cpufreq_cpu_put(cpu_policy); |
1357 | return ret; | 1340 | return ret; |
1358 | } | 1341 | } |
@@ -1386,6 +1369,8 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) | |||
1386 | { | 1369 | { |
1387 | int ret; | 1370 | int ret; |
1388 | 1371 | ||
1372 | WARN_ON(!init_cpufreq_transition_notifier_list_called); | ||
1373 | |||
1389 | switch (list) { | 1374 | switch (list) { |
1390 | case CPUFREQ_TRANSITION_NOTIFIER: | 1375 | case CPUFREQ_TRANSITION_NOTIFIER: |
1391 | ret = srcu_notifier_chain_register( | 1376 | ret = srcu_notifier_chain_register( |
@@ -1848,7 +1833,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
1848 | cpufreq_debug_enable_ratelimit(); | 1833 | cpufreq_debug_enable_ratelimit(); |
1849 | } | 1834 | } |
1850 | 1835 | ||
1851 | return (ret); | 1836 | return ret; |
1852 | } | 1837 | } |
1853 | EXPORT_SYMBOL_GPL(cpufreq_register_driver); | 1838 | EXPORT_SYMBOL_GPL(cpufreq_register_driver); |
1854 | 1839 | ||
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 070421a5480e..ef09e069433b 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -114,7 +114,7 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) | |||
114 | stat->freq_table[i]); | 114 | stat->freq_table[i]); |
115 | } | 115 | } |
116 | if (len >= PAGE_SIZE) | 116 | if (len >= PAGE_SIZE) |
117 | return len; | 117 | return PAGE_SIZE; |
118 | 118 | ||
119 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 119 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
120 | 120 | ||
@@ -131,8 +131,12 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) | |||
131 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", | 131 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", |
132 | stat->trans_table[i*stat->max_state+j]); | 132 | stat->trans_table[i*stat->max_state+j]); |
133 | } | 133 | } |
134 | if (len >= PAGE_SIZE) | ||
135 | break; | ||
134 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 136 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
135 | } | 137 | } |
138 | if (len >= PAGE_SIZE) | ||
139 | return PAGE_SIZE; | ||
136 | return len; | 140 | return len; |
137 | } | 141 | } |
138 | CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table); | 142 | CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table); |