diff options
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 116 |
1 files changed, 65 insertions, 51 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 57a3853a55fb..f941efd9b836 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -619,50 +619,52 @@ static struct cpufreq_governor *find_governor(const char *str_governor) | |||
| 619 | return NULL; | 619 | return NULL; |
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | static int cpufreq_parse_policy(char *str_governor, | ||
| 623 | struct cpufreq_policy *policy) | ||
| 624 | { | ||
| 625 | if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { | ||
| 626 | policy->policy = CPUFREQ_POLICY_PERFORMANCE; | ||
| 627 | return 0; | ||
| 628 | } | ||
| 629 | if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { | ||
| 630 | policy->policy = CPUFREQ_POLICY_POWERSAVE; | ||
| 631 | return 0; | ||
| 632 | } | ||
| 633 | return -EINVAL; | ||
| 634 | } | ||
| 635 | |||
| 622 | /** | 636 | /** |
| 623 | * cpufreq_parse_governor - parse a governor string | 637 | * cpufreq_parse_governor - parse a governor string only for !setpolicy |
| 624 | */ | 638 | */ |
| 625 | static int cpufreq_parse_governor(char *str_governor, | 639 | static int cpufreq_parse_governor(char *str_governor, |
| 626 | struct cpufreq_policy *policy) | 640 | struct cpufreq_policy *policy) |
| 627 | { | 641 | { |
| 628 | if (cpufreq_driver->setpolicy) { | 642 | struct cpufreq_governor *t; |
| 629 | if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { | ||
| 630 | policy->policy = CPUFREQ_POLICY_PERFORMANCE; | ||
| 631 | return 0; | ||
| 632 | } | ||
| 633 | |||
| 634 | if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { | ||
| 635 | policy->policy = CPUFREQ_POLICY_POWERSAVE; | ||
| 636 | return 0; | ||
| 637 | } | ||
| 638 | } else { | ||
| 639 | struct cpufreq_governor *t; | ||
| 640 | 643 | ||
| 641 | mutex_lock(&cpufreq_governor_mutex); | 644 | mutex_lock(&cpufreq_governor_mutex); |
| 642 | 645 | ||
| 643 | t = find_governor(str_governor); | 646 | t = find_governor(str_governor); |
| 644 | if (!t) { | 647 | if (!t) { |
| 645 | int ret; | 648 | int ret; |
| 646 | 649 | ||
| 647 | mutex_unlock(&cpufreq_governor_mutex); | 650 | mutex_unlock(&cpufreq_governor_mutex); |
| 648 | 651 | ||
| 649 | ret = request_module("cpufreq_%s", str_governor); | 652 | ret = request_module("cpufreq_%s", str_governor); |
| 650 | if (ret) | 653 | if (ret) |
| 651 | return -EINVAL; | 654 | return -EINVAL; |
| 652 | 655 | ||
| 653 | mutex_lock(&cpufreq_governor_mutex); | 656 | mutex_lock(&cpufreq_governor_mutex); |
| 654 | 657 | ||
| 655 | t = find_governor(str_governor); | 658 | t = find_governor(str_governor); |
| 656 | } | 659 | } |
| 657 | if (t && !try_module_get(t->owner)) | 660 | if (t && !try_module_get(t->owner)) |
| 658 | t = NULL; | 661 | t = NULL; |
| 659 | 662 | ||
| 660 | mutex_unlock(&cpufreq_governor_mutex); | 663 | mutex_unlock(&cpufreq_governor_mutex); |
| 661 | 664 | ||
| 662 | if (t) { | 665 | if (t) { |
| 663 | policy->governor = t; | 666 | policy->governor = t; |
| 664 | return 0; | 667 | return 0; |
| 665 | } | ||
| 666 | } | 668 | } |
| 667 | 669 | ||
| 668 | return -EINVAL; | 670 | return -EINVAL; |
| @@ -784,8 +786,13 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, | |||
| 784 | if (ret != 1) | 786 | if (ret != 1) |
| 785 | return -EINVAL; | 787 | return -EINVAL; |
| 786 | 788 | ||
| 787 | if (cpufreq_parse_governor(str_governor, &new_policy)) | 789 | if (cpufreq_driver->setpolicy) { |
| 788 | return -EINVAL; | 790 | if (cpufreq_parse_policy(str_governor, &new_policy)) |
| 791 | return -EINVAL; | ||
| 792 | } else { | ||
| 793 | if (cpufreq_parse_governor(str_governor, &new_policy)) | ||
| 794 | return -EINVAL; | ||
| 795 | } | ||
| 789 | 796 | ||
| 790 | ret = cpufreq_set_policy(policy, &new_policy); | 797 | ret = cpufreq_set_policy(policy, &new_policy); |
| 791 | 798 | ||
| @@ -1051,32 +1058,39 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void) | |||
| 1051 | 1058 | ||
| 1052 | static int cpufreq_init_policy(struct cpufreq_policy *policy) | 1059 | static int cpufreq_init_policy(struct cpufreq_policy *policy) |
| 1053 | { | 1060 | { |
| 1054 | struct cpufreq_governor *gov = NULL; | 1061 | struct cpufreq_governor *gov = NULL, *def_gov = NULL; |
| 1055 | struct cpufreq_policy new_policy; | 1062 | struct cpufreq_policy new_policy; |
| 1056 | 1063 | ||
| 1057 | memcpy(&new_policy, policy, sizeof(*policy)); | 1064 | memcpy(&new_policy, policy, sizeof(*policy)); |
| 1058 | 1065 | ||
| 1059 | /* Update governor of new_policy to the governor used before hotplug */ | 1066 | def_gov = cpufreq_default_governor(); |
| 1060 | gov = find_governor(policy->last_governor); | 1067 | |
| 1061 | if (gov) { | 1068 | if (has_target()) { |
| 1062 | pr_debug("Restoring governor %s for cpu %d\n", | 1069 | /* |
| 1070 | * Update governor of new_policy to the governor used before | ||
| 1071 | * hotplug | ||
| 1072 | */ | ||
| 1073 | gov = find_governor(policy->last_governor); | ||
| 1074 | if (gov) { | ||
| 1075 | pr_debug("Restoring governor %s for cpu %d\n", | ||
| 1063 | policy->governor->name, policy->cpu); | 1076 | policy->governor->name, policy->cpu); |
| 1077 | } else { | ||
| 1078 | if (!def_gov) | ||
| 1079 | return -ENODATA; | ||
| 1080 | gov = def_gov; | ||
| 1081 | } | ||
| 1082 | new_policy.governor = gov; | ||
| 1064 | } else { | 1083 | } else { |
| 1065 | gov = cpufreq_default_governor(); | 1084 | /* Use the default policy if there is no last_policy. */ |
| 1066 | if (!gov) | 1085 | if (policy->last_policy) { |
| 1067 | return -ENODATA; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | new_policy.governor = gov; | ||
| 1071 | |||
| 1072 | /* Use the default policy if there is no last_policy. */ | ||
| 1073 | if (cpufreq_driver->setpolicy) { | ||
| 1074 | if (policy->last_policy) | ||
| 1075 | new_policy.policy = policy->last_policy; | 1086 | new_policy.policy = policy->last_policy; |
| 1076 | else | 1087 | } else { |
| 1077 | cpufreq_parse_governor(gov->name, &new_policy); | 1088 | if (!def_gov) |
| 1089 | return -ENODATA; | ||
| 1090 | cpufreq_parse_policy(def_gov->name, &new_policy); | ||
| 1091 | } | ||
| 1078 | } | 1092 | } |
| 1079 | /* set default policy */ | 1093 | |
| 1080 | return cpufreq_set_policy(policy, &new_policy); | 1094 | return cpufreq_set_policy(policy, &new_policy); |
| 1081 | } | 1095 | } |
| 1082 | 1096 | ||
