···11-Generic cpufreq driver22-33-It is a generic DT based cpufreq driver for frequency management. It supports44-both uniprocessor (UP) and symmetric multiprocessor (SMP) systems which share55-clock and voltage across all CPUs.66-77-Both required and optional properties listed below must be defined88-under node /cpus/cpu@0.99-1010-Required properties:1111-- None1212-1313-Optional properties:1414-- operating-points: Refer to Documentation/devicetree/bindings/opp/opp-v1.yaml for1515- details. OPPs *must* be supplied either via DT, i.e. this property, or1616- populated at runtime.1717-- clock-latency: Specify the possible maximum transition latency for clock,1818- in unit of nanoseconds.1919-- voltage-tolerance: Specify the CPU voltage tolerance in percentage.2020-- #cooling-cells:2121- Please refer to2222- Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml.2323-2424-Examples:2525-2626-cpus {2727- #address-cells = <1>;2828- #size-cells = <0>;2929-3030- cpu@0 {3131- compatible = "arm,cortex-a9";3232- reg = <0>;3333- next-level-cache = <&L2>;3434- operating-points = <3535- /* kHz uV */3636- 792000 11000003737- 396000 9500003838- 198000 8500003939- >;4040- clock-latency = <61036>; /* two CLK32 periods */4141- #cooling-cells = <2>;4242- };4343-4444- cpu@1 {4545- compatible = "arm,cortex-a9";4646- reg = <1>;4747- next-level-cache = <&L2>;4848- };4949-5050- cpu@2 {5151- compatible = "arm,cortex-a9";5252- reg = <2>;5353- next-level-cache = <&L2>;5454- };5555-5656- cpu@3 {5757- compatible = "arm,cortex-a9";5858- reg = <3>;5959- next-level-cache = <&L2>;6060- };6161-};
···664664665665static unsigned int cpufreq_parse_policy(char *str_governor)666666{667667- if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN))667667+ if (!strncasecmp(str_governor, "performance", strlen("performance")))668668 return CPUFREQ_POLICY_PERFORMANCE;669669670670- if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN))670670+ if (!strncasecmp(str_governor, "powersave", strlen("powersave")))671671 return CPUFREQ_POLICY_POWERSAVE;672672673673 return CPUFREQ_POLICY_UNKNOWN;···914914 const char *buf, size_t count)915915{916916 unsigned int freq = 0;917917- unsigned int ret;917917+ int ret;918918919919 if (!policy->governor || !policy->governor->store_setspeed)920920 return -EINVAL;···1121112111221122 if (has_target()) {11231123 /* Update policy governor to the one used before hotplug. */11241124- gov = get_governor(policy->last_governor);11241124+ if (policy->last_governor[0] != '\0')11251125+ gov = get_governor(policy->last_governor);11251126 if (gov) {11261127 pr_debug("Restoring governor %s for cpu %d\n",11271128 gov->name, policy->cpu);···18451844 */18461845unsigned int cpufreq_quick_get(unsigned int cpu)18471846{18481848- struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL;18491847 unsigned long flags;1850184818511849 read_lock_irqsave(&cpufreq_driver_lock, flags);···1859185918601860 read_unlock_irqrestore(&cpufreq_driver_lock, flags);1861186118621862- policy = cpufreq_cpu_get(cpu);18621862+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);18631863 if (policy)18641864 return policy->cur;18651865···18751875 */18761876unsigned int cpufreq_quick_get_max(unsigned int cpu)18771877{18781878- struct cpufreq_policy *policy __free(put_cpufreq_policy);18791879-18801880- policy = cpufreq_cpu_get(cpu);18781878+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);18811879 if (policy)18821880 return policy->max;18831881···18911893 */18921894__weak unsigned int cpufreq_get_hw_max_freq(unsigned int cpu)18931895{18941894- struct cpufreq_policy *policy __free(put_cpufreq_policy);18951895-18961896- policy = cpufreq_cpu_get(cpu);18961896+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);18971897 if (policy)18981898 return policy->cpuinfo.max_freq;18991899···19151919 */19161920unsigned int cpufreq_get(unsigned int cpu)19171921{19181918- struct cpufreq_policy *policy __free(put_cpufreq_policy);19191919-19201920- policy = cpufreq_cpu_get(cpu);19221922+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);19211923 if (!policy)19221924 return 0;19231925···27442750 */27452751void cpufreq_update_policy(unsigned int cpu)27462752{27472747- struct cpufreq_policy *policy __free(put_cpufreq_policy);27482748-27492749- policy = cpufreq_cpu_get(cpu);27532753+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);27502754 if (!policy)27512755 return;27522756···27612769 */27622770void cpufreq_update_limits(unsigned int cpu)27632771{27642764- struct cpufreq_policy *policy __free(put_cpufreq_policy);27652765-27662766- policy = cpufreq_cpu_get(cpu);27722772+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);27672773 if (!policy)27682774 return;27692775···27822792 if (!policy->freq_table)27832793 return -ENXIO;2784279427852785- ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table);27952795+ ret = cpufreq_frequency_table_cpuinfo(policy);27862796 if (ret) {27872797 pr_err("%s: Policy frequency update failed\n", __func__);27882798 return ret;···29112921 return -EPROBE_DEFER;2912292229132923 if (!driver_data || !driver_data->verify || !driver_data->init ||29142914- !(driver_data->setpolicy || driver_data->target_index ||29152915- driver_data->target) ||29162916- (driver_data->setpolicy && (driver_data->target_index ||29172917- driver_data->target)) ||29242924+ (driver_data->target_index && driver_data->target) ||29252925+ (!!driver_data->setpolicy == (driver_data->target_index || driver_data->target)) ||29182926 (!driver_data->get_intermediate != !driver_data->target_intermediate) ||29192927 (!driver_data->online != !driver_data->offline) ||29202928 (driver_data->adjust_perf && !driver_data->fast_switch))···3046305830473059static bool cpufreq_policy_is_good_for_eas(unsigned int cpu)30483060{30493049- struct cpufreq_policy *policy __free(put_cpufreq_policy);30503050-30513051- policy = cpufreq_cpu_get(cpu);30613061+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);30523062 if (!policy) {30533063 pr_debug("cpufreq policy not set for CPU: %d\n", cpu);30543064 return false;
+12-12
drivers/cpufreq/cpufreq_conservative.c
···152152 struct dbs_data *dbs_data = to_dbs_data(attr_set);153153 unsigned int input;154154 int ret;155155- ret = sscanf(buf, "%u", &input);155155+ ret = kstrtouint(buf, 0, &input);156156157157- if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)157157+ if (ret || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)158158 return -EINVAL;159159160160 dbs_data->sampling_down_factor = input;···168168 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;169169 unsigned int input;170170 int ret;171171- ret = sscanf(buf, "%u", &input);171171+ ret = kstrtouint(buf, 0, &input);172172173173- if (ret != 1 || input > 100 || input <= cs_tuners->down_threshold)173173+ if (ret || input > 100 || input <= cs_tuners->down_threshold)174174 return -EINVAL;175175176176 dbs_data->up_threshold = input;···184184 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;185185 unsigned int input;186186 int ret;187187- ret = sscanf(buf, "%u", &input);187187+ ret = kstrtouint(buf, 0, &input);188188189189 /* cannot be lower than 1 otherwise freq will not fall */190190- if (ret != 1 || input < 1 || input >= dbs_data->up_threshold)190190+ if (ret || input < 1 || input >= dbs_data->up_threshold)191191 return -EINVAL;192192193193 cs_tuners->down_threshold = input;···201201 unsigned int input;202202 int ret;203203204204- ret = sscanf(buf, "%u", &input);205205- if (ret != 1)206206- return -EINVAL;204204+ ret = kstrtouint(buf, 0, &input);205205+ if (ret)206206+ return ret;207207208208 if (input > 1)209209 input = 1;···226226 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;227227 unsigned int input;228228 int ret;229229- ret = sscanf(buf, "%u", &input);229229+ ret = kstrtouint(buf, 0, &input);230230231231- if (ret != 1)232232- return -EINVAL;231231+ if (ret)232232+ return ret;233233234234 if (input > 100)235235 input = 100;
+1-24
drivers/cpufreq/cpufreq_ondemand.c
···3030static unsigned int default_powersave_bias;31313232/*3333- * Not all CPUs want IO time to be accounted as busy; this depends on how3434- * efficient idling at a higher frequency/voltage is.3535- * Pavel Machek says this is not so for various generations of AMD and old3636- * Intel systems.3737- * Mike Chan (android.com) claims this is also not true for ARM.3838- * Because of this, whitelist specific known (series) of CPUs by default, and3939- * leave all others up to the user.4040- */4141-static int should_io_be_busy(void)4242-{4343-#if defined(CONFIG_X86)4444- /*4545- * For Intel, Core 2 (model 15) and later have an efficient idle.4646- */4747- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&4848- boot_cpu_data.x86 == 6 &&4949- boot_cpu_data.x86_model >= 15)5050- return 1;5151-#endif5252- return 0;5353-}5454-5555-/*5633 * Find right freq to be set now with powersave_bias on.5734 * Returns the freq_hi to be used right now and will set freq_hi_delay_us,5835 * freq_lo, and freq_lo_delay_us in percpu area for averaging freqs.···354377 dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;355378 dbs_data->ignore_nice_load = 0;356379 tuners->powersave_bias = default_powersave_bias;357357- dbs_data->io_is_busy = should_io_be_busy();380380+ dbs_data->io_is_busy = od_should_io_be_busy();358381359382 dbs_data->tuners = tuners;360383 return 0;
+23
drivers/cpufreq/cpufreq_ondemand.h
···2424struct od_dbs_tuners {2525 unsigned int powersave_bias;2626};2727+2828+#ifdef CONFIG_X862929+#include <asm/cpu_device_id.h>3030+3131+/*3232+ * Not all CPUs want IO time to be accounted as busy; this depends on3333+ * how efficient idling at a higher frequency/voltage is.3434+ *3535+ * Pavel Machek says this is not so for various generations of AMD and3636+ * old Intel systems. Mike Chan (android.com) claims this is also not3737+ * true for ARM.3838+ *3939+ * Because of this, select a known series of Intel CPUs (Family 6 and4040+ * later) by default, and leave all others up to the user.4141+ */4242+static inline bool od_should_io_be_busy(void)4343+{4444+ return (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&4545+ boot_cpu_data.x86_vfm >= INTEL_PENTIUM_PRO);4646+}4747+#else4848+static inline bool od_should_io_be_busy(void) { return false; }4949+#endif
+10-12
drivers/cpufreq/freq_table.c
···2828 return false;2929}30303131-int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,3232- struct cpufreq_frequency_table *table)3131+int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy)3332{3434- struct cpufreq_frequency_table *pos;3333+ struct cpufreq_frequency_table *pos, *table = policy->freq_table;3534 unsigned int min_freq = ~0;3635 unsigned int max_freq = 0;3737- unsigned int freq;3636+ unsigned int freq, i;38373939- cpufreq_for_each_valid_entry(pos, table) {3838+ cpufreq_for_each_valid_entry_idx(pos, table, i) {4039 freq = pos->frequency;41404241 if ((!cpufreq_boost_enabled() || !policy->boost_enabled)4342 && (pos->flags & CPUFREQ_BOOST_FREQ))4443 continue;45444646- pr_debug("table entry %u: %u kHz\n", (int)(pos - table), freq);4545+ pr_debug("table entry %u: %u kHz\n", i, freq);4746 if (freq < min_freq)4847 min_freq = freq;4948 if (freq > max_freq)···6465 return 0;6566}66676767-int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy,6868- struct cpufreq_frequency_table *table)6868+int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy)6969{7070- struct cpufreq_frequency_table *pos;7070+ struct cpufreq_frequency_table *pos, *table = policy->freq_table;7171 unsigned int freq, prev_smaller = 0;7272 bool found = false;7373···108110 if (!policy->freq_table)109111 return -ENODEV;110112111111- return cpufreq_frequency_table_verify(policy, policy->freq_table);113113+ return cpufreq_frequency_table_verify(policy);112114}113115EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);114116···126128 };127129 struct cpufreq_frequency_table *pos;128130 struct cpufreq_frequency_table *table = policy->freq_table;129129- unsigned int freq, diff, i = 0;131131+ unsigned int freq, diff, i;130132 int index;131133132134 pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",···352354 return 0;353355 }354356355355- ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table);357357+ ret = cpufreq_frequency_table_cpuinfo(policy);356358 if (ret)357359 return ret;358360
+94-98
drivers/cpufreq/intel_pstate.c
···620620 (cpu->pstate.min_pstate * 100 / turbo_pstate) : 0;621621}622622623623-static s16 intel_pstate_get_epb(struct cpudata *cpu_data)624624-{625625- u64 epb;626626- int ret;627627-628628- if (!boot_cpu_has(X86_FEATURE_EPB))629629- return -ENXIO;630630-631631- ret = rdmsrq_on_cpu(cpu_data->cpu, MSR_IA32_ENERGY_PERF_BIAS, &epb);632632- if (ret)633633- return (s16)ret;634634-635635- return (s16)(epb & 0x0f);636636-}637637-638623static s16 intel_pstate_get_epp(struct cpudata *cpu_data, u64 hwp_req_data)639624{640640- s16 epp;625625+ s16 epp = -EOPNOTSUPP;641626642627 if (boot_cpu_has(X86_FEATURE_HWP_EPP)) {643628 /*···636651 return epp;637652 }638653 epp = (hwp_req_data >> 24) & 0xff;639639- } else {640640- /* When there is no EPP present, HWP uses EPB settings */641641- epp = intel_pstate_get_epb(cpu_data);642654 }643655644656 return epp;645657}646658647647-static int intel_pstate_set_epb(int cpu, s16 pref)648648-{649649- u64 epb;650650- int ret;651651-652652- if (!boot_cpu_has(X86_FEATURE_EPB))653653- return -ENXIO;654654-655655- ret = rdmsrq_on_cpu(cpu, MSR_IA32_ENERGY_PERF_BIAS, &epb);656656- if (ret)657657- return ret;658658-659659- epb = (epb & ~0x0f) | pref;660660- wrmsrq_on_cpu(cpu, MSR_IA32_ENERGY_PERF_BIAS, epb);661661-662662- return 0;663663-}664664-665659/*666666- * EPP/EPB display strings corresponding to EPP index in the660660+ * EPP display strings corresponding to EPP index in the667661 * energy_perf_strings[]668662 * index String669663 *-------------------------------------···746782 u32 raw_epp)747783{748784 int epp = -EINVAL;749749- int ret;785785+ int ret = -EOPNOTSUPP;750786751787 if (!pref_index)752788 epp = cpu_data->epp_default;···766802 return -EBUSY;767803768804 ret = intel_pstate_set_epp(cpu_data, epp);769769- } else {770770- if (epp == -EINVAL)771771- epp = (pref_index - 1) << 2;772772- ret = intel_pstate_set_epb(cpu_data->cpu, epp);773805 }774806775807 return ret;···897937898938cpufreq_freq_attr_ro(base_frequency);899939940940+enum hwp_cpufreq_attr_index {941941+ HWP_BASE_FREQUENCY_INDEX = 0,942942+ HWP_PERFORMANCE_PREFERENCE_INDEX,943943+ HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX,944944+ HWP_CPUFREQ_ATTR_COUNT,945945+};946946+900947static struct freq_attr *hwp_cpufreq_attrs[] = {901901- &energy_performance_preference,902902- &energy_performance_available_preferences,903903- &base_frequency,904904- NULL,948948+ [HWP_BASE_FREQUENCY_INDEX] = &base_frequency,949949+ [HWP_PERFORMANCE_PREFERENCE_INDEX] = &energy_performance_preference,950950+ [HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX] =951951+ &energy_performance_available_preferences,952952+ [HWP_CPUFREQ_ATTR_COUNT] = NULL,905953};906954907955static bool no_cas __ro_after_init;···13051337 if (boot_cpu_has(X86_FEATURE_HWP_EPP)) {13061338 value &= ~GENMASK_ULL(31, 24);13071339 value |= (u64)epp << 24;13081308- } else {13091309- intel_pstate_set_epb(cpu, epp);13101340 }13411341+13111342skip_epp:13121343 WRITE_ONCE(cpu_data->hwp_req_cached, value);13131344 wrmsrq_on_cpu(cpu, MSR_HWP_REQUEST, value);···1377141013781411#define POWER_CTL_EE_ENABLE 113791412#define POWER_CTL_EE_DISABLE 214131413+14141414+/* Enable bit for Dynamic Efficiency Control (DEC) */14151415+#define POWER_CTL_DEC_ENABLE 271380141613811417static int power_ctl_ee_state;13821418···1472150214731503static bool intel_pstate_update_max_freq(struct cpudata *cpudata)14741504{14751475- struct cpufreq_policy *policy __free(put_cpufreq_policy);14761476-14771477- policy = cpufreq_cpu_get(cpudata->cpu);15051505+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);14781506 if (!policy)14791507 return false;14801508···16631695 return count;16641696}1665169716661666-static void update_qos_request(enum freq_qos_req_type type)16981698+static void update_cpu_qos_request(int cpu, enum freq_qos_req_type type)16671699{17001700+ struct cpudata *cpudata = all_cpu_data[cpu];17011701+ unsigned int freq = cpudata->pstate.turbo_freq;16681702 struct freq_qos_request *req;16691669- struct cpufreq_policy *policy;17031703+17041704+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);17051705+ if (!policy)17061706+ return;17071707+17081708+ req = policy->driver_data;17091709+ if (!req)17101710+ return;17111711+17121712+ if (hwp_active)17131713+ intel_pstate_get_hwp_cap(cpudata);17141714+17151715+ if (type == FREQ_QOS_MIN) {17161716+ freq = DIV_ROUND_UP(freq * global.min_perf_pct, 100);17171717+ } else {17181718+ req++;17191719+ freq = (freq * global.max_perf_pct) / 100;17201720+ }17211721+17221722+ if (freq_qos_update_request(req, freq) < 0)17231723+ pr_warn("Failed to update freq constraint: CPU%d\n", cpu);17241724+}17251725+17261726+static void update_qos_requests(enum freq_qos_req_type type)17271727+{16701728 int i;1671172916721672- for_each_possible_cpu(i) {16731673- struct cpudata *cpu = all_cpu_data[i];16741674- unsigned int freq, perf_pct;16751675-16761676- policy = cpufreq_cpu_get(i);16771677- if (!policy)16781678- continue;16791679-16801680- req = policy->driver_data;16811681- cpufreq_cpu_put(policy);16821682-16831683- if (!req)16841684- continue;16851685-16861686- if (hwp_active)16871687- intel_pstate_get_hwp_cap(cpu);16881688-16891689- if (type == FREQ_QOS_MIN) {16901690- perf_pct = global.min_perf_pct;16911691- } else {16921692- req++;16931693- perf_pct = global.max_perf_pct;16941694- }16951695-16961696- freq = DIV_ROUND_UP(cpu->pstate.turbo_freq * perf_pct, 100);16971697-16981698- if (freq_qos_update_request(req, freq) < 0)16991699- pr_warn("Failed to update freq constraint: CPU%d\n", i);17001700- }17301730+ for_each_possible_cpu(i)17311731+ update_cpu_qos_request(i, type);17011732}1702173317031734static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b,···17251758 if (intel_pstate_driver == &intel_pstate)17261759 intel_pstate_update_policies();17271760 else17281728- update_qos_request(FREQ_QOS_MAX);17611761+ update_qos_requests(FREQ_QOS_MAX);1729176217301763 mutex_unlock(&intel_pstate_driver_lock);17311764···17591792 if (intel_pstate_driver == &intel_pstate)17601793 intel_pstate_update_policies();17611794 else17621762- update_qos_request(FREQ_QOS_MIN);17951795+ update_qos_requests(FREQ_QOS_MIN);1763179617641797 mutex_unlock(&intel_pstate_driver_lock);17651798···25422575 * that sample.time will always be reset before setting the utilization25432576 * update hook and make the caller skip the sample then.25442577 */25452545- if (cpu->last_sample_time) {25782578+ if (likely(cpu->last_sample_time)) {25462579 intel_pstate_calc_avg_perf(cpu);25472580 return true;25482581 }···37693802 {}37703803};3771380438053805+static bool hwp_check_epp(void)38063806+{38073807+ if (boot_cpu_has(X86_FEATURE_HWP_EPP))38083808+ return true;38093809+38103810+ /* Without EPP support, don't expose EPP-related sysfs attributes. */38113811+ hwp_cpufreq_attrs[HWP_PERFORMANCE_PREFERENCE_INDEX] = NULL;38123812+ hwp_cpufreq_attrs[HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX] = NULL;38133813+38143814+ return false;38153815+}38163816+38173817+static bool hwp_check_dec(void)38183818+{38193819+ u64 power_ctl;38203820+38213821+ rdmsrq(MSR_IA32_POWER_CTL, power_ctl);38223822+ return !!(power_ctl & BIT(POWER_CTL_DEC_ENABLE));38233823+}38243824+37723825static int __init intel_pstate_init(void)37733826{37743827 static struct cpudata **_all_cpu_data;···3809382238103823 id = x86_match_cpu(hwp_support_ids);38113824 if (id) {38123812- hwp_forced = intel_pstate_hwp_is_enabled();38253825+ bool epp_present = hwp_check_epp();3813382638143814- if (hwp_forced)38273827+ /*38283828+ * If HWP is enabled already, there is no choice but to deal38293829+ * with it.38303830+ */38313831+ hwp_forced = intel_pstate_hwp_is_enabled();38323832+ if (hwp_forced) {38153833 pr_info("HWP enabled by BIOS\n");38163816- else if (no_load)38343834+ no_hwp = 0;38353835+ } else if (no_load) {38173836 return -ENODEV;38373837+ } else if (!epp_present && !hwp_check_dec()) {38383838+ /*38393839+ * Avoid enabling HWP for processors without EPP support38403840+ * unless the Dynamic Efficiency Control (DEC) enable38413841+ * bit (MSR_IA32_POWER_CTL, bit 27) is set because that38423842+ * means incomplete HWP implementation which is a corner38433843+ * case and supporting it is generally problematic.38443844+ */38453845+ no_hwp = 1;38463846+ }3818384738193848 copy_cpu_funcs(&core_funcs);38203820- /*38213821- * Avoid enabling HWP for processors without EPP support,38223822- * because that means incomplete HWP implementation which is a38233823- * corner case and supporting it is generally problematic.38243824- *38253825- * If HWP is enabled already, though, there is no choice but to38263826- * deal with it.38273827- */38283828- if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) || hwp_forced) {38493849+38503850+ if (!no_hwp) {38293851 hwp_active = true;38303852 hwp_mode_bdw = id->driver_data;38313853 intel_pstate.attr = hwp_cpufreq_attrs;
+3
drivers/cpufreq/longhaul.c
···953953 struct cpufreq_policy *policy = cpufreq_cpu_get(0);954954 int i;955955956956+ if (unlikely(!policy))957957+ return;958958+956959 for (i = 0; i < numscales; i++) {957960 if (mults[i] == maxmult) {958961 struct cpufreq_freqs freqs;
+109-23
drivers/cpufreq/mediatek-cpufreq-hw.c
···2424#define POLL_USEC 10002525#define TIMEOUT_USEC 30000026262727+#define FDVFS_FDIV_HZ (26 * 1000)2828+2729enum {2830 REG_FREQ_LUT_TABLE,2931 REG_FREQ_ENABLE,···3735 REG_ARRAY_SIZE,3836};39374040-struct mtk_cpufreq_data {3838+struct mtk_cpufreq_priv {3939+ struct device *dev;4040+ const struct mtk_cpufreq_variant *variant;4141+ void __iomem *fdvfs;4242+};4343+4444+struct mtk_cpufreq_domain {4545+ struct mtk_cpufreq_priv *parent;4146 struct cpufreq_frequency_table *table;4247 void __iomem *reg_bases[REG_ARRAY_SIZE];4348 struct resource *res;···5243 int nr_opp;5344};54455555-static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {5656- [REG_FREQ_LUT_TABLE] = 0x0,5757- [REG_FREQ_ENABLE] = 0x84,5858- [REG_FREQ_PERF_STATE] = 0x88,5959- [REG_FREQ_HW_STATE] = 0x8c,6060- [REG_EM_POWER_TBL] = 0x90,6161- [REG_FREQ_LATENCY] = 0x110,4646+struct mtk_cpufreq_variant {4747+ int (*init)(struct mtk_cpufreq_priv *priv);4848+ const u16 reg_offsets[REG_ARRAY_SIZE];4949+ const bool is_hybrid_dvfs;5050+};5151+5252+static const struct mtk_cpufreq_variant cpufreq_mtk_base_variant = {5353+ .reg_offsets = {5454+ [REG_FREQ_LUT_TABLE] = 0x0,5555+ [REG_FREQ_ENABLE] = 0x84,5656+ [REG_FREQ_PERF_STATE] = 0x88,5757+ [REG_FREQ_HW_STATE] = 0x8c,5858+ [REG_EM_POWER_TBL] = 0x90,5959+ [REG_FREQ_LATENCY] = 0x110,6060+ },6161+};6262+6363+static int mtk_cpufreq_hw_mt8196_init(struct mtk_cpufreq_priv *priv)6464+{6565+ priv->fdvfs = devm_of_iomap(priv->dev, priv->dev->of_node, 0, NULL);6666+ if (IS_ERR(priv->fdvfs))6767+ return dev_err_probe(priv->dev, PTR_ERR(priv->fdvfs),6868+ "failed to get fdvfs iomem\n");6969+7070+ return 0;7171+}7272+7373+static const struct mtk_cpufreq_variant cpufreq_mtk_mt8196_variant = {7474+ .init = mtk_cpufreq_hw_mt8196_init,7575+ .reg_offsets = {7676+ [REG_FREQ_LUT_TABLE] = 0x0,7777+ [REG_FREQ_ENABLE] = 0x84,7878+ [REG_FREQ_PERF_STATE] = 0x88,7979+ [REG_FREQ_HW_STATE] = 0x8c,8080+ [REG_EM_POWER_TBL] = 0x90,8181+ [REG_FREQ_LATENCY] = 0x114,8282+ },8383+ .is_hybrid_dvfs = true,6284};63856486static int __maybe_unused6587mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *uW,6688 unsigned long *KHz)6789{6868- struct mtk_cpufreq_data *data;9090+ struct mtk_cpufreq_domain *data;6991 struct cpufreq_policy *policy;7092 int i;7193···12080 return 0;12181}122828383+static void mtk_cpufreq_hw_fdvfs_switch(unsigned int target_freq,8484+ struct cpufreq_policy *policy)8585+{8686+ struct mtk_cpufreq_domain *data = policy->driver_data;8787+ struct mtk_cpufreq_priv *priv = data->parent;8888+ unsigned int cpu;8989+9090+ target_freq = DIV_ROUND_UP(target_freq, FDVFS_FDIV_HZ);9191+ for_each_cpu(cpu, policy->real_cpus) {9292+ writel_relaxed(target_freq, priv->fdvfs + cpu * 4);9393+ }9494+}9595+12396static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,12497 unsigned int index)12598{126126- struct mtk_cpufreq_data *data = policy->driver_data;9999+ struct mtk_cpufreq_domain *data = policy->driver_data;100100+ unsigned int target_freq;127101128128- writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);102102+ if (data->parent->fdvfs) {103103+ target_freq = policy->freq_table[index].frequency;104104+ mtk_cpufreq_hw_fdvfs_switch(target_freq, policy);105105+ } else {106106+ writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);107107+ }129108130109 return 0;131110}132111133112static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)134113{135135- struct mtk_cpufreq_data *data;114114+ struct mtk_cpufreq_domain *data;136115 struct cpufreq_policy *policy;137116 unsigned int index;138117···170111static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,171112 unsigned int target_freq)172113{173173- struct mtk_cpufreq_data *data = policy->driver_data;114114+ struct mtk_cpufreq_domain *data = policy->driver_data;174115 unsigned int index;175116176117 index = cpufreq_table_find_index_dl(policy, target_freq, false);177118178178- writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);119119+ if (data->parent->fdvfs)120120+ mtk_cpufreq_hw_fdvfs_switch(target_freq, policy);121121+ else122122+ writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);179123180124 return policy->freq_table[index].frequency;181125}182126183127static int mtk_cpu_create_freq_table(struct platform_device *pdev,184184- struct mtk_cpufreq_data *data)128128+ struct mtk_cpufreq_domain *data)185129{186130 struct device *dev = &pdev->dev;187131 u32 temp, i, freq, prev_freq = 0;···219157220158static int mtk_cpu_resources_init(struct platform_device *pdev,221159 struct cpufreq_policy *policy,222222- const u16 *offsets)160160+ struct mtk_cpufreq_priv *priv)223161{224224- struct mtk_cpufreq_data *data;162162+ struct mtk_cpufreq_domain *data;225163 struct device *dev = &pdev->dev;226164 struct resource *res;227165 struct of_phandle_args args;···241179242180 index = args.args[0];243181 of_node_put(args.np);182182+183183+ /*184184+ * In a cpufreq with hybrid DVFS, such as the MT8196, the first declared185185+ * register range is for FDVFS, followed by the frequency domain MMIOs.186186+ */187187+ if (priv->variant->is_hybrid_dvfs)188188+ index++;189189+190190+ data->parent = priv;244191245192 res = platform_get_resource(pdev, IORESOURCE_MEM, index);246193 if (!res) {···273202 data->res = res;274203275204 for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)276276- data->reg_bases[i] = base + offsets[i];205205+ data->reg_bases[i] = base + priv->variant->reg_offsets[i];277206278207 ret = mtk_cpu_create_freq_table(pdev, data);279208 if (ret) {···294223{295224 struct platform_device *pdev = cpufreq_get_driver_data();296225 int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;297297- struct mtk_cpufreq_data *data;226226+ struct mtk_cpufreq_domain *data;298227 unsigned int latency;299228 int ret;300229···333262334263static void mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)335264{336336- struct mtk_cpufreq_data *data = policy->driver_data;265265+ struct mtk_cpufreq_domain *data = policy->driver_data;337266 struct resource *res = data->res;338267 void __iomem *base = data->base;339268···346275static void mtk_cpufreq_register_em(struct cpufreq_policy *policy)347276{348277 struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);349349- struct mtk_cpufreq_data *data = policy->driver_data;278278+ struct mtk_cpufreq_domain *data = policy->driver_data;350279351280 em_dev_register_perf_domain(get_cpu_device(policy->cpu), data->nr_opp,352281 &em_cb, policy->cpus, true);···368297369298static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)370299{300300+ struct mtk_cpufreq_priv *priv;371301 const void *data;372302 int ret, cpu;373303 struct device *cpu_dev;···392320 if (!data)393321 return -EINVAL;394322395395- platform_set_drvdata(pdev, (void *) data);323323+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);324324+ if (!priv)325325+ return -ENOMEM;326326+327327+ priv->variant = data;328328+ priv->dev = &pdev->dev;329329+330330+ if (priv->variant->init) {331331+ ret = priv->variant->init(priv);332332+ if (ret)333333+ return ret;334334+ }335335+336336+ platform_set_drvdata(pdev, priv);396337 cpufreq_mtk_hw_driver.driver_data = pdev;397338398339 ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver);···421336}422337423338static const struct of_device_id mtk_cpufreq_hw_match[] = {424424- { .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets },339339+ { .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_base_variant },340340+ { .compatible = "mediatek,mt8196-cpufreq-hw", .data = &cpufreq_mtk_mt8196_variant },425341 {}426342};427343MODULE_DEVICE_TABLE(of, mtk_cpufreq_hw_match);
+5-6
drivers/cpufreq/mediatek-cpufreq.c
···123123 soc_data->sram_max_volt);124124 return ret;125125 }126126- } else if (pre_vproc > new_vproc) {126126+ } else {127127 vproc = max(new_vproc,128128 pre_vsram - soc_data->max_volt_shift);129129 ret = regulator_set_voltage(proc_reg, vproc,···320320 struct dev_pm_opp *new_opp;321321 struct mtk_cpu_dvfs_info *info;322322 unsigned long freq, volt;323323- struct cpufreq_policy *policy;324323 int ret = 0;325324326325 info = container_of(nb, struct mtk_cpu_dvfs_info, opp_nb);···352353 }353354354355 dev_pm_opp_put(new_opp);355355- policy = cpufreq_cpu_get(info->opp_cpu);356356- if (policy) {356356+357357+ struct cpufreq_policy *policy __free(put_cpufreq_policy)358358+ = cpufreq_cpu_get(info->opp_cpu);359359+ if (policy)357360 cpufreq_driver_target(policy, freq / 1000,358361 CPUFREQ_RELATION_L);359359- cpufreq_cpu_put(policy);360360- }361362 }362363 }363364
···554554static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,555555 unsigned long event, void *ptr)556556{557557+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(0);557558 int ret;558558- struct cpufreq_policy *policy;559559560560- policy = cpufreq_cpu_get(0);561560 if (!policy) {562561 pr_debug("cpufreq: get no policy for cpu0\n");563562 return NOTIFY_BAD;564563 }565564566565 ret = cpufreq_driver_target(policy, SLEEP_FREQ, 0);567567- cpufreq_cpu_put(policy);568566569567 if (ret < 0)570568 return NOTIFY_BAD;
+10
drivers/cpufreq/scmi-cpufreq.c
···1515#include <linux/energy_model.h>1616#include <linux/export.h>1717#include <linux/module.h>1818+#include <linux/of.h>1819#include <linux/pm_opp.h>1920#include <linux/pm_qos.h>2021#include <linux/slab.h>···424423 if (np == scmi_np)425424 return true;426425 }426426+427427+ /*428428+ * Older Broadcom STB chips had a "clocks" property for CPU node(s)429429+ * that did not match the SCMI performance protocol node, if we got430430+ * there, it means we had such an older Device Tree, therefore return431431+ * true to preserve backwards compatibility.432432+ */433433+ if (of_machine_is_compatible("brcm,brcmstb"))434434+ return true;427435428436 return false;429437}
···378378 * DETECT SPEEDSTEP SPEEDS *379379 *********************************************************************/380380381381-unsigned int speedstep_get_freqs(enum speedstep_processor processor,382382- unsigned int *low_speed,383383- unsigned int *high_speed,384384- unsigned int *transition_latency,385385- void (*set_state) (unsigned int state))381381+int speedstep_get_freqs(enum speedstep_processor processor,382382+ unsigned int *low_speed,383383+ unsigned int *high_speed,384384+ unsigned int *transition_latency,385385+ void (*set_state)(unsigned int state))386386{387387 unsigned int prev_speed;388388- unsigned int ret = 0;389388 unsigned long flags;390389 ktime_t tv1, tv2;390390+ int ret = 0;391391392392 if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))393393 return -EINVAL;
+5-5
drivers/cpufreq/speedstep-lib.h
···4141 * SPEEDSTEP_LOW; the second argument is zero so that no4242 * cpufreq_notify_transition calls are initiated.4343 */4444-extern unsigned int speedstep_get_freqs(enum speedstep_processor processor,4545- unsigned int *low_speed,4646- unsigned int *high_speed,4747- unsigned int *transition_latency,4848- void (*set_state) (unsigned int state));4444+extern int speedstep_get_freqs(enum speedstep_processor processor,4545+ unsigned int *low_speed,4646+ unsigned int *high_speed,4747+ unsigned int *transition_latency,4848+ void (*set_state)(unsigned int state));
···543543 pub fn cpus(&mut self) -> &mut cpumask::Cpumask {544544 // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of545545 // the returned reference.546546- unsafe { cpumask::CpumaskVar::as_mut_ref(&mut self.as_mut_ref().cpus) }546546+ unsafe { cpumask::CpumaskVar::from_raw_mut(&mut self.as_mut_ref().cpus) }547547 }548548549549 /// Sets clock for the [`Policy`].
+3-2
rust/kernel/cpumask.rs
···212212/// }213213/// assert_eq!(mask2.weight(), count);214214/// ```215215+#[repr(transparent)]215216pub struct CpumaskVar {216217 #[cfg(CONFIG_CPUMASK_OFFSTACK)]217218 ptr: NonNull<Cpumask>,···271270 ///272271 /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime273272 /// of the returned reference.274274- pub unsafe fn as_mut_ref<'a>(ptr: *mut bindings::cpumask_var_t) -> &'a mut Self {273273+ pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpumask_var_t) -> &'a mut Self {275274 // SAFETY: Guaranteed by the safety requirements of the function.276275 //277276 // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the···285284 ///286285 /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime287286 /// of the returned reference.288288- pub unsafe fn as_ref<'a>(ptr: *const bindings::cpumask_var_t) -> &'a Self {287287+ pub unsafe fn from_raw<'a>(ptr: *const bindings::cpumask_var_t) -> &'a Self {289288 // SAFETY: Guaranteed by the safety requirements of the function.290289 //291290 // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
+7-6
rust/kernel/opp.rs
···1616 ffi::c_ulong,1717 prelude::*,1818 str::CString,1919- types::{ARef, AlwaysRefCounted, Opaque},1919+ sync::aref::{ARef, AlwaysRefCounted},2020+ types::Opaque,2021};21222223#[cfg(CONFIG_CPU_FREQ)]···163162/// use kernel::device::Device;164163/// use kernel::error::Result;165164/// use kernel::opp::{Data, MicroVolt, Token};166166-/// use kernel::types::ARef;165165+/// use kernel::sync::aref::ARef;167166///168167/// fn create_opp(dev: &ARef<Device>, freq: Hertz, volt: MicroVolt, level: u32) -> Result<Token> {169168/// let data = Data::new(freq, volt, level, false);···212211/// use kernel::device::Device;213212/// use kernel::error::Result;214213/// use kernel::opp::{Data, MicroVolt, Token};215215-/// use kernel::types::ARef;214214+/// use kernel::sync::aref::ARef;216215///217216/// fn create_opp(dev: &ARef<Device>, freq: Hertz, volt: MicroVolt, level: u32) -> Result<Token> {218217/// let data = Data::new(freq, volt, level, false);···263262/// use kernel::clk::Hertz;264263/// use kernel::error::Result;265264/// use kernel::opp::{OPP, SearchType, Table};266266-/// use kernel::types::ARef;265265+/// use kernel::sync::aref::ARef;267266///268267/// fn find_opp(table: &Table, freq: Hertz) -> Result<ARef<OPP>> {269268/// let opp = table.opp_from_freq(freq, Some(true), None, SearchType::Exact)?;···336335/// use kernel::error::Result;337336/// use kernel::opp::{Config, ConfigOps, ConfigToken};338337/// use kernel::str::CString;339339-/// use kernel::types::ARef;338338+/// use kernel::sync::aref::ARef;340339/// use kernel::macros::vtable;341340///342341/// #[derive(Default)]···582581/// use kernel::device::Device;583582/// use kernel::error::Result;584583/// use kernel::opp::Table;585585-/// use kernel::types::ARef;584584+/// use kernel::sync::aref::ARef;586585///587586/// fn get_table(dev: &ARef<Device>, mask: &mut Cpumask, freq: Hertz) -> Result<Table> {588587/// let mut opp_table = Table::from_of_cpumask(dev, mask)?;