aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/kernel/smp.c24
-rw-r--r--arch/sparc/kernel/time_64.c28
-rw-r--r--arch/x86/kernel/cpu/intel_epb.c22
-rw-r--r--arch/x86/kernel/tsc.c2
-rw-r--r--arch/x86/kvm/x86.c31
-rw-r--r--drivers/base/power/domain.c8
-rw-r--r--drivers/cpufreq/cpufreq.c140
-rw-r--r--drivers/soc/imx/gpc.c13
-rw-r--r--include/linux/cpufreq.h14
-rw-r--r--include/linux/pm_domain.h4
11 files changed, 183 insertions, 105 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0d31d2b58d8c..ee6cf4d1010c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4133,7 +4133,9 @@ F: Documentation/admin-guide/pm/intel_pstate.rst
4133F: Documentation/cpu-freq/ 4133F: Documentation/cpu-freq/
4134F: Documentation/devicetree/bindings/cpufreq/ 4134F: Documentation/devicetree/bindings/cpufreq/
4135F: drivers/cpufreq/ 4135F: drivers/cpufreq/
4136F: kernel/sched/cpufreq*.c
4136F: include/linux/cpufreq.h 4137F: include/linux/cpufreq.h
4138F: include/linux/sched/cpufreq.h
4137F: tools/testing/selftests/cpufreq/ 4139F: tools/testing/selftests/cpufreq/
4138 4140
4139CPU FREQUENCY DRIVERS - ARM BIG LITTLE 4141CPU FREQUENCY DRIVERS - ARM BIG LITTLE
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index c93fe0f256de..ebc53804d57b 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -758,15 +758,20 @@ static int cpufreq_callback(struct notifier_block *nb,
758 unsigned long val, void *data) 758 unsigned long val, void *data)
759{ 759{
760 struct cpufreq_freqs *freq = data; 760 struct cpufreq_freqs *freq = data;
761 int cpu = freq->cpu; 761 struct cpumask *cpus = freq->policy->cpus;
762 int cpu, first = cpumask_first(cpus);
763 unsigned int lpj;
762 764
763 if (freq->flags & CPUFREQ_CONST_LOOPS) 765 if (freq->flags & CPUFREQ_CONST_LOOPS)
764 return NOTIFY_OK; 766 return NOTIFY_OK;
765 767
766 if (!per_cpu(l_p_j_ref, cpu)) { 768 if (!per_cpu(l_p_j_ref, first)) {
767 per_cpu(l_p_j_ref, cpu) = 769 for_each_cpu(cpu, cpus) {
768 per_cpu(cpu_data, cpu).loops_per_jiffy; 770 per_cpu(l_p_j_ref, cpu) =
769 per_cpu(l_p_j_ref_freq, cpu) = freq->old; 771 per_cpu(cpu_data, cpu).loops_per_jiffy;
772 per_cpu(l_p_j_ref_freq, cpu) = freq->old;
773 }
774
770 if (!global_l_p_j_ref) { 775 if (!global_l_p_j_ref) {
771 global_l_p_j_ref = loops_per_jiffy; 776 global_l_p_j_ref = loops_per_jiffy;
772 global_l_p_j_ref_freq = freq->old; 777 global_l_p_j_ref_freq = freq->old;
@@ -778,10 +783,11 @@ static int cpufreq_callback(struct notifier_block *nb,
778 loops_per_jiffy = cpufreq_scale(global_l_p_j_ref, 783 loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
779 global_l_p_j_ref_freq, 784 global_l_p_j_ref_freq,
780 freq->new); 785 freq->new);
781 per_cpu(cpu_data, cpu).loops_per_jiffy = 786
782 cpufreq_scale(per_cpu(l_p_j_ref, cpu), 787 lpj = cpufreq_scale(per_cpu(l_p_j_ref, first),
783 per_cpu(l_p_j_ref_freq, cpu), 788 per_cpu(l_p_j_ref_freq, first), freq->new);
784 freq->new); 789 for_each_cpu(cpu, cpus)
790 per_cpu(cpu_data, cpu).loops_per_jiffy = lpj;
785 } 791 }
786 return NOTIFY_OK; 792 return NOTIFY_OK;
787} 793}
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 3eb77943ce12..89fb05f90609 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -653,19 +653,23 @@ static int sparc64_cpufreq_notifier(struct notifier_block *nb, unsigned long val
653 void *data) 653 void *data)
654{ 654{
655 struct cpufreq_freqs *freq = data; 655 struct cpufreq_freqs *freq = data;
656 unsigned int cpu = freq->cpu; 656 unsigned int cpu;
657 struct freq_table *ft = &per_cpu(sparc64_freq_table, cpu); 657 struct freq_table *ft;
658 658
659 if (!ft->ref_freq) { 659 for_each_cpu(cpu, freq->policy->cpus) {
660 ft->ref_freq = freq->old; 660 ft = &per_cpu(sparc64_freq_table, cpu);
661 ft->clock_tick_ref = cpu_data(cpu).clock_tick; 661
662 } 662 if (!ft->ref_freq) {
663 if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || 663 ft->ref_freq = freq->old;
664 (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { 664 ft->clock_tick_ref = cpu_data(cpu).clock_tick;
665 cpu_data(cpu).clock_tick = 665 }
666 cpufreq_scale(ft->clock_tick_ref, 666
667 ft->ref_freq, 667 if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
668 freq->new); 668 (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
669 cpu_data(cpu).clock_tick =
670 cpufreq_scale(ft->clock_tick_ref, ft->ref_freq,
671 freq->new);
672 }
669 } 673 }
670 674
671 return 0; 675 return 0;
diff --git a/arch/x86/kernel/cpu/intel_epb.c b/arch/x86/kernel/cpu/intel_epb.c
index f4dd73396f28..ebb14a26f117 100644
--- a/arch/x86/kernel/cpu/intel_epb.c
+++ b/arch/x86/kernel/cpu/intel_epb.c
@@ -97,6 +97,7 @@ static void intel_epb_restore(void)
97 wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val); 97 wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val);
98} 98}
99 99
100#ifdef CONFIG_PM
100static struct syscore_ops intel_epb_syscore_ops = { 101static struct syscore_ops intel_epb_syscore_ops = {
101 .suspend = intel_epb_save, 102 .suspend = intel_epb_save,
102 .resume = intel_epb_restore, 103 .resume = intel_epb_restore,
@@ -193,6 +194,25 @@ static int intel_epb_offline(unsigned int cpu)
193 return 0; 194 return 0;
194} 195}
195 196
197static inline void register_intel_ebp_syscore_ops(void)
198{
199 register_syscore_ops(&intel_epb_syscore_ops);
200}
201#else /* !CONFIG_PM */
202static int intel_epb_online(unsigned int cpu)
203{
204 intel_epb_restore();
205 return 0;
206}
207
208static int intel_epb_offline(unsigned int cpu)
209{
210 return intel_epb_save();
211}
212
213static inline void register_intel_ebp_syscore_ops(void) {}
214#endif
215
196static __init int intel_epb_init(void) 216static __init int intel_epb_init(void)
197{ 217{
198 int ret; 218 int ret;
@@ -206,7 +226,7 @@ static __init int intel_epb_init(void)
206 if (ret < 0) 226 if (ret < 0)
207 goto err_out_online; 227 goto err_out_online;
208 228
209 register_syscore_ops(&intel_epb_syscore_ops); 229 register_intel_ebp_syscore_ops();
210 return 0; 230 return 0;
211 231
212err_out_online: 232err_out_online:
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 15b5e98a86f9..356dfc555a27 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -979,7 +979,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
979 if (!(freq->flags & CPUFREQ_CONST_LOOPS)) 979 if (!(freq->flags & CPUFREQ_CONST_LOOPS))
980 mark_tsc_unstable("cpufreq changes"); 980 mark_tsc_unstable("cpufreq changes");
981 981
982 set_cyc2ns_scale(tsc_khz, freq->cpu, rdtsc()); 982 set_cyc2ns_scale(tsc_khz, freq->policy->cpu, rdtsc());
983 } 983 }
984 984
985 return 0; 985 return 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d75bb97b983c..b9591abde62a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6698,10 +6698,8 @@ static void kvm_hyperv_tsc_notifier(void)
6698} 6698}
6699#endif 6699#endif
6700 6700
6701static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 6701static void __kvmclock_cpufreq_notifier(struct cpufreq_freqs *freq, int cpu)
6702 void *data)
6703{ 6702{
6704 struct cpufreq_freqs *freq = data;
6705 struct kvm *kvm; 6703 struct kvm *kvm;
6706 struct kvm_vcpu *vcpu; 6704 struct kvm_vcpu *vcpu;
6707 int i, send_ipi = 0; 6705 int i, send_ipi = 0;
@@ -6745,17 +6743,12 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
6745 * 6743 *
6746 */ 6744 */
6747 6745
6748 if (val == CPUFREQ_PRECHANGE && freq->old > freq->new) 6746 smp_call_function_single(cpu, tsc_khz_changed, freq, 1);
6749 return 0;
6750 if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
6751 return 0;
6752
6753 smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1);
6754 6747
6755 spin_lock(&kvm_lock); 6748 spin_lock(&kvm_lock);
6756 list_for_each_entry(kvm, &vm_list, vm_list) { 6749 list_for_each_entry(kvm, &vm_list, vm_list) {
6757 kvm_for_each_vcpu(i, vcpu, kvm) { 6750 kvm_for_each_vcpu(i, vcpu, kvm) {
6758 if (vcpu->cpu != freq->cpu) 6751 if (vcpu->cpu != cpu)
6759 continue; 6752 continue;
6760 kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); 6753 kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
6761 if (vcpu->cpu != smp_processor_id()) 6754 if (vcpu->cpu != smp_processor_id())
@@ -6777,8 +6770,24 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
6777 * guest context is entered kvmclock will be updated, 6770 * guest context is entered kvmclock will be updated,
6778 * so the guest will not see stale values. 6771 * so the guest will not see stale values.
6779 */ 6772 */
6780 smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1); 6773 smp_call_function_single(cpu, tsc_khz_changed, freq, 1);
6781 } 6774 }
6775}
6776
6777static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
6778 void *data)
6779{
6780 struct cpufreq_freqs *freq = data;
6781 int cpu;
6782
6783 if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
6784 return 0;
6785 if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
6786 return 0;
6787
6788 for_each_cpu(cpu, freq->policy->cpus)
6789 __kvmclock_cpufreq_notifier(freq, cpu);
6790
6782 return 0; 6791 return 0;
6783} 6792}
6784 6793
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7a6aa2318915..33c30c1e6a30 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -128,6 +128,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
128#define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) 128#define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
129#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP) 129#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
130#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN) 130#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
131#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
131 132
132static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, 133static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
133 const struct generic_pm_domain *genpd) 134 const struct generic_pm_domain *genpd)
@@ -515,7 +516,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
515 * (1) The domain is configured as always on. 516 * (1) The domain is configured as always on.
516 * (2) When the domain has a subdomain being powered on. 517 * (2) When the domain has a subdomain being powered on.
517 */ 518 */
518 if (genpd_is_always_on(genpd) || atomic_read(&genpd->sd_count) > 0) 519 if (genpd_is_always_on(genpd) ||
520 genpd_is_rpm_always_on(genpd) ||
521 atomic_read(&genpd->sd_count) > 0)
519 return -EBUSY; 522 return -EBUSY;
520 523
521 list_for_each_entry(pdd, &genpd->dev_list, list_node) { 524 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
@@ -1812,7 +1815,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
1812 } 1815 }
1813 1816
1814 /* Always-on domains must be powered on at initialization. */ 1817 /* Always-on domains must be powered on at initialization. */
1815 if (genpd_is_always_on(genpd) && !genpd_status_on(genpd)) 1818 if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) &&
1819 !genpd_status_on(genpd))
1816 return -EINVAL; 1820 return -EINVAL;
1817 1821
1818 if (genpd_is_cpu_domain(genpd) && 1822 if (genpd_is_cpu_domain(genpd) &&
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index db779b650fce..85ff958e01f1 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -340,11 +340,14 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy,
340 struct cpufreq_freqs *freqs, 340 struct cpufreq_freqs *freqs,
341 unsigned int state) 341 unsigned int state)
342{ 342{
343 int cpu;
344
343 BUG_ON(irqs_disabled()); 345 BUG_ON(irqs_disabled());
344 346
345 if (cpufreq_disabled()) 347 if (cpufreq_disabled())
346 return; 348 return;
347 349
350 freqs->policy = policy;
348 freqs->flags = cpufreq_driver->flags; 351 freqs->flags = cpufreq_driver->flags;
349 pr_debug("notification %u of frequency transition to %u kHz\n", 352 pr_debug("notification %u of frequency transition to %u kHz\n",
350 state, freqs->new); 353 state, freqs->new);
@@ -364,10 +367,8 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy,
364 } 367 }
365 } 368 }
366 369
367 for_each_cpu(freqs->cpu, policy->cpus) { 370 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
368 srcu_notifier_call_chain(&cpufreq_transition_notifier_list, 371 CPUFREQ_PRECHANGE, freqs);
369 CPUFREQ_PRECHANGE, freqs);
370 }
371 372
372 adjust_jiffies(CPUFREQ_PRECHANGE, freqs); 373 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
373 break; 374 break;
@@ -377,11 +378,11 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy,
377 pr_debug("FREQ: %u - CPUs: %*pbl\n", freqs->new, 378 pr_debug("FREQ: %u - CPUs: %*pbl\n", freqs->new,
378 cpumask_pr_args(policy->cpus)); 379 cpumask_pr_args(policy->cpus));
379 380
380 for_each_cpu(freqs->cpu, policy->cpus) { 381 for_each_cpu(cpu, policy->cpus)
381 trace_cpu_frequency(freqs->new, freqs->cpu); 382 trace_cpu_frequency(freqs->new, cpu);
382 srcu_notifier_call_chain(&cpufreq_transition_notifier_list, 383
383 CPUFREQ_POSTCHANGE, freqs); 384 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
384 } 385 CPUFREQ_POSTCHANGE, freqs);
385 386
386 cpufreq_stats_record_transition(policy, freqs->new); 387 cpufreq_stats_record_transition(policy, freqs->new);
387 policy->cur = freqs->new; 388 policy->cur = freqs->new;
@@ -618,50 +619,52 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
618 return NULL; 619 return NULL;
619} 620}
620 621
622static 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
621/** 636/**
622 * cpufreq_parse_governor - parse a governor string 637 * cpufreq_parse_governor - parse a governor string only for !setpolicy
623 */ 638 */
624static int cpufreq_parse_governor(char *str_governor, 639static int cpufreq_parse_governor(char *str_governor,
625 struct cpufreq_policy *policy) 640 struct cpufreq_policy *policy)
626{ 641{
627 if (cpufreq_driver->setpolicy) { 642 struct cpufreq_governor *t;
628 if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
629 policy->policy = CPUFREQ_POLICY_PERFORMANCE;
630 return 0;
631 }
632 643
633 if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { 644 mutex_lock(&cpufreq_governor_mutex);
634 policy->policy = CPUFREQ_POLICY_POWERSAVE;
635 return 0;
636 }
637 } else {
638 struct cpufreq_governor *t;
639 645
640 mutex_lock(&cpufreq_governor_mutex); 646 t = find_governor(str_governor);
647 if (!t) {
648 int ret;
641 649
642 t = find_governor(str_governor); 650 mutex_unlock(&cpufreq_governor_mutex);
643 if (!t) {
644 int ret;
645
646 mutex_unlock(&cpufreq_governor_mutex);
647 651
648 ret = request_module("cpufreq_%s", str_governor); 652 ret = request_module("cpufreq_%s", str_governor);
649 if (ret) 653 if (ret)
650 return -EINVAL; 654 return -EINVAL;
651 655
652 mutex_lock(&cpufreq_governor_mutex); 656 mutex_lock(&cpufreq_governor_mutex);
653 657
654 t = find_governor(str_governor); 658 t = find_governor(str_governor);
655 } 659 }
656 if (t && !try_module_get(t->owner)) 660 if (t && !try_module_get(t->owner))
657 t = NULL; 661 t = NULL;
658 662
659 mutex_unlock(&cpufreq_governor_mutex); 663 mutex_unlock(&cpufreq_governor_mutex);
660 664
661 if (t) { 665 if (t) {
662 policy->governor = t; 666 policy->governor = t;
663 return 0; 667 return 0;
664 }
665 } 668 }
666 669
667 return -EINVAL; 670 return -EINVAL;
@@ -783,8 +786,13 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
783 if (ret != 1) 786 if (ret != 1)
784 return -EINVAL; 787 return -EINVAL;
785 788
786 if (cpufreq_parse_governor(str_governor, &new_policy)) 789 if (cpufreq_driver->setpolicy) {
787 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 }
788 796
789 ret = cpufreq_set_policy(policy, &new_policy); 797 ret = cpufreq_set_policy(policy, &new_policy);
790 798
@@ -1050,32 +1058,39 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
1050 1058
1051static int cpufreq_init_policy(struct cpufreq_policy *policy) 1059static int cpufreq_init_policy(struct cpufreq_policy *policy)
1052{ 1060{
1053 struct cpufreq_governor *gov = NULL; 1061 struct cpufreq_governor *gov = NULL, *def_gov = NULL;
1054 struct cpufreq_policy new_policy; 1062 struct cpufreq_policy new_policy;
1055 1063
1056 memcpy(&new_policy, policy, sizeof(*policy)); 1064 memcpy(&new_policy, policy, sizeof(*policy));
1057 1065
1058 /* Update governor of new_policy to the governor used before hotplug */ 1066 def_gov = cpufreq_default_governor();
1059 gov = find_governor(policy->last_governor); 1067
1060 if (gov) { 1068 if (has_target()) {
1061 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",
1062 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;
1063 } else { 1083 } else {
1064 gov = cpufreq_default_governor(); 1084 /* Use the default policy if there is no last_policy. */
1065 if (!gov) 1085 if (policy->last_policy) {
1066 return -ENODATA;
1067 }
1068
1069 new_policy.governor = gov;
1070
1071 /* Use the default policy if there is no last_policy. */
1072 if (cpufreq_driver->setpolicy) {
1073 if (policy->last_policy)
1074 new_policy.policy = policy->last_policy; 1086 new_policy.policy = policy->last_policy;
1075 else 1087 } else {
1076 cpufreq_parse_governor(gov->name, &new_policy); 1088 if (!def_gov)
1089 return -ENODATA;
1090 cpufreq_parse_policy(def_gov->name, &new_policy);
1091 }
1077 } 1092 }
1078 /* set default policy */ 1093
1079 return cpufreq_set_policy(policy, &new_policy); 1094 return cpufreq_set_policy(policy, &new_policy);
1080} 1095}
1081 1096
@@ -1133,6 +1148,11 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
1133 cpufreq_global_kobject, "policy%u", cpu); 1148 cpufreq_global_kobject, "policy%u", cpu);
1134 if (ret) { 1149 if (ret) {
1135 pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret); 1150 pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret);
1151 /*
1152 * The entire policy object will be freed below, but the extra
1153 * memory allocated for the kobject name needs to be freed by
1154 * releasing the kobject.
1155 */
1136 kobject_put(&policy->kobj); 1156 kobject_put(&policy->kobj);
1137 goto err_free_real_cpus; 1157 goto err_free_real_cpus;
1138 } 1158 }
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index 7d14a4b4e82a..29b43651c261 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -431,10 +431,19 @@ static int imx_gpc_probe(struct platform_device *pdev)
431 return ret; 431 return ret;
432 } 432 }
433 433
434 /* Disable PU power down in normal operation if ERR009619 is present */ 434 /*
435 * Disable PU power down by runtime PM if ERR009619 is present.
436 *
437 * The PRE clock will be paused for several cycles when turning on the
438 * PU domain LDO from power down state. If PRE is in use at that time,
439 * the IPU/PRG cannot get the correct display data from the PRE.
440 *
441 * This is not a concern when the whole system enters suspend state, so
442 * it's safe to power down PU in this case.
443 */
435 if (of_id_data->err009619_present) 444 if (of_id_data->err009619_present)
436 imx_gpc_domains[GPC_PGC_DOMAIN_PU].base.flags |= 445 imx_gpc_domains[GPC_PGC_DOMAIN_PU].base.flags |=
437 GENPD_FLAG_ALWAYS_ON; 446 GENPD_FLAG_RPM_ALWAYS_ON;
438 447
439 /* Keep DISP always on if ERR006287 is present */ 448 /* Keep DISP always on if ERR006287 is present */
440 if (of_id_data->err006287_present) 449 if (of_id_data->err006287_present)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 684caf067003..d01a74fbc4db 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -42,13 +42,6 @@ enum cpufreq_table_sorting {
42 CPUFREQ_TABLE_SORTED_DESCENDING 42 CPUFREQ_TABLE_SORTED_DESCENDING
43}; 43};
44 44
45struct cpufreq_freqs {
46 unsigned int cpu; /* cpu nr */
47 unsigned int old;
48 unsigned int new;
49 u8 flags; /* flags of cpufreq_driver, see below. */
50};
51
52struct cpufreq_cpuinfo { 45struct cpufreq_cpuinfo {
53 unsigned int max_freq; 46 unsigned int max_freq;
54 unsigned int min_freq; 47 unsigned int min_freq;
@@ -156,6 +149,13 @@ struct cpufreq_policy {
156 struct thermal_cooling_device *cdev; 149 struct thermal_cooling_device *cdev;
157}; 150};
158 151
152struct cpufreq_freqs {
153 struct cpufreq_policy *policy;
154 unsigned int old;
155 unsigned int new;
156 u8 flags; /* flags of cpufreq_driver, see below. */
157};
158
159/* Only for ACPI */ 159/* Only for ACPI */
160#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */ 160#define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
161#define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */ 161#define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 0e8e356bed6a..b21f35f0ee2e 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -53,12 +53,16 @@
53 * driver must then comply with the so called, 53 * driver must then comply with the so called,
54 * last-man-standing algorithm, for the CPUs in the 54 * last-man-standing algorithm, for the CPUs in the
55 * PM domain. 55 * PM domain.
56 *
57 * GENPD_FLAG_RPM_ALWAYS_ON: Instructs genpd to always keep the PM domain
58 * powered on except for system suspend.
56 */ 59 */
57#define GENPD_FLAG_PM_CLK (1U << 0) 60#define GENPD_FLAG_PM_CLK (1U << 0)
58#define GENPD_FLAG_IRQ_SAFE (1U << 1) 61#define GENPD_FLAG_IRQ_SAFE (1U << 1)
59#define GENPD_FLAG_ALWAYS_ON (1U << 2) 62#define GENPD_FLAG_ALWAYS_ON (1U << 2)
60#define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3) 63#define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3)
61#define GENPD_FLAG_CPU_DOMAIN (1U << 4) 64#define GENPD_FLAG_CPU_DOMAIN (1U << 4)
65#define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5)
62 66
63enum gpd_status { 67enum gpd_status {
64 GPD_STATE_ACTIVE = 0, /* PM domain is active */ 68 GPD_STATE_ACTIVE = 0, /* PM domain is active */