@@ -61,6 +61,12 @@ static struct cpufreq_driver *cpufreq_driver;
6161static DEFINE_PER_CPU (struct cpufreq_policy * , cpufreq_cpu_data ) ;
6262static DEFINE_RWLOCK (cpufreq_driver_lock );
6363
64+ static DEFINE_STATIC_KEY_FALSE (cpufreq_freq_invariance );
65+ bool cpufreq_supports_freq_invariance (void )
66+ {
67+ return static_branch_likely (& cpufreq_freq_invariance );
68+ }
69+
6470/* Flag to suspend/resume CPUFreq governors */
6571static bool cpufreq_suspended ;
6672
@@ -154,8 +160,9 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
154160}
155161EXPORT_SYMBOL_GPL (get_cpu_idle_time );
156162
157- __weak void arch_set_freq_scale (struct cpumask * cpus , unsigned long cur_freq ,
158- unsigned long max_freq )
163+ __weak void arch_set_freq_scale (const struct cpumask * cpus ,
164+ unsigned long cur_freq ,
165+ unsigned long max_freq )
159166{
160167}
161168EXPORT_SYMBOL_GPL (arch_set_freq_scale );
@@ -446,6 +453,10 @@ void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
446453
447454 cpufreq_notify_post_transition (policy , freqs , transition_failed );
448455
456+ arch_set_freq_scale (policy -> related_cpus ,
457+ policy -> cur ,
458+ policy -> cpuinfo .max_freq );
459+
449460 policy -> transition_ongoing = false;
450461 policy -> transition_task = NULL ;
451462
@@ -2056,9 +2067,15 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
20562067unsigned int cpufreq_driver_fast_switch (struct cpufreq_policy * policy ,
20572068 unsigned int target_freq )
20582069{
2070+ unsigned int freq ;
2071+
20592072 target_freq = clamp_val (target_freq , policy -> min , policy -> max );
2073+ freq = cpufreq_driver -> fast_switch (policy , target_freq );
20602074
2061- return cpufreq_driver -> fast_switch (policy , target_freq );
2075+ arch_set_freq_scale (policy -> related_cpus , freq ,
2076+ policy -> cpuinfo .max_freq );
2077+
2078+ return freq ;
20622079}
20632080EXPORT_SYMBOL_GPL (cpufreq_driver_fast_switch );
20642081
@@ -2710,6 +2727,15 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
27102727 cpufreq_driver = driver_data ;
27112728 write_unlock_irqrestore (& cpufreq_driver_lock , flags );
27122729
2730+ /*
2731+ * Mark support for the scheduler's frequency invariance engine for
2732+ * drivers that implement target(), target_index() or fast_switch().
2733+ */
2734+ if (!cpufreq_driver -> setpolicy ) {
2735+ static_branch_enable_cpuslocked (& cpufreq_freq_invariance );
2736+ pr_debug ("supports frequency invariance" );
2737+ }
2738+
27132739 if (driver_data -> setpolicy )
27142740 driver_data -> flags |= CPUFREQ_CONST_LOOPS ;
27152741
@@ -2779,6 +2805,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
27792805 cpus_read_lock ();
27802806 subsys_interface_unregister (& cpufreq_interface );
27812807 remove_boost_sysfs_file ();
2808+ static_branch_disable_cpuslocked (& cpufreq_freq_invariance );
27822809 cpuhp_remove_state_nocalls_cpuslocked (hp_online );
27832810
27842811 write_lock_irqsave (& cpufreq_driver_lock , flags );
0 commit comments