Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-6.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"These fix three recent regressions, two in cpufreq and one in the
Intel Soundwire driver, and an unchecked MSR access in the
intel_pstate driver:

- Fix a recent regression causing systems where frequency tables are
used by cpufreq to have issues with setting frequency limits
(Rafael Wysocki)

- Fix a recent regressions causing frequency boost settings to become
out-of-sync if platform firmware updates the registers associated
with frequency boost during system resume (Viresh Kumar)

- Fix a recent regression causing resume failures to occur in the
Intel Soundwire driver if the device handled by it is in runtime
suspend before a system-wide suspend (Rafael Wysocki)

- Fix an unchecked MSR aceess in the intel_pstate driver occurring
when CPUID indicates no turbo, but the driver attempts to enable
turbo frequencies due to a misleading value read from an MSR
(Srinivas Pandruvada)"

* tag 'pm-6.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode
soundwire: intel_auxdevice: Fix system suspend/resume handling
cpufreq: Fix setting policy limits when frequency tables are used
cpufreq: ACPI: Re-sync CPU boost state on system resume

+102 -66
+13 -2
drivers/cpufreq/acpi-cpufreq.c
··· 909 909 if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency) 910 910 pr_warn(FW_WARN "P-state 0 is not max freq\n"); 911 911 912 - if (acpi_cpufreq_driver.set_boost) 913 - policy->boost_supported = true; 912 + if (acpi_cpufreq_driver.set_boost) { 913 + if (policy->boost_supported) { 914 + /* 915 + * The firmware may have altered boost state while the 916 + * CPU was offline (for example during a suspend-resume 917 + * cycle). 918 + */ 919 + if (policy->boost_enabled != boost_state(cpu)) 920 + set_boost(policy, policy->boost_enabled); 921 + } else { 922 + policy->boost_supported = true; 923 + } 924 + } 914 925 915 926 return result; 916 927
+14 -8
drivers/cpufreq/cpufreq.c
··· 536 536 EXPORT_SYMBOL_GPL(cpufreq_disable_fast_switch); 537 537 538 538 static unsigned int __resolve_freq(struct cpufreq_policy *policy, 539 - unsigned int target_freq, unsigned int relation) 539 + unsigned int target_freq, 540 + unsigned int min, unsigned int max, 541 + unsigned int relation) 540 542 { 541 543 unsigned int idx; 544 + 545 + target_freq = clamp_val(target_freq, min, max); 542 546 543 547 if (!policy->freq_table) 544 548 return target_freq; 545 549 546 - idx = cpufreq_frequency_table_target(policy, target_freq, relation); 550 + idx = cpufreq_frequency_table_target(policy, target_freq, min, max, relation); 547 551 policy->cached_resolved_idx = idx; 548 552 policy->cached_target_freq = target_freq; 549 553 return policy->freq_table[idx].frequency; ··· 581 577 if (unlikely(min > max)) 582 578 min = max; 583 579 584 - return __resolve_freq(policy, clamp_val(target_freq, min, max), 585 - CPUFREQ_RELATION_LE); 580 + return __resolve_freq(policy, target_freq, min, max, CPUFREQ_RELATION_LE); 586 581 } 587 582 EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq); 588 583 ··· 2400 2397 if (cpufreq_disabled()) 2401 2398 return -ENODEV; 2402 2399 2403 - target_freq = clamp_val(target_freq, policy->min, policy->max); 2404 - target_freq = __resolve_freq(policy, target_freq, relation); 2400 + target_freq = __resolve_freq(policy, target_freq, policy->min, 2401 + policy->max, relation); 2405 2402 2406 2403 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", 2407 2404 policy->cpu, target_freq, relation, old_target_freq); ··· 2730 2727 * compiler optimizations around them because they may be accessed 2731 2728 * concurrently by cpufreq_driver_resolve_freq() during the update. 2732 2729 */ 2733 - WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, CPUFREQ_RELATION_H)); 2734 - new_data.min = __resolve_freq(policy, new_data.min, CPUFREQ_RELATION_L); 2730 + WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, 2731 + new_data.min, new_data.max, 2732 + CPUFREQ_RELATION_H)); 2733 + new_data.min = __resolve_freq(policy, new_data.min, new_data.min, 2734 + new_data.max, CPUFREQ_RELATION_L); 2735 2735 WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min); 2736 2736 2737 2737 trace_cpu_frequency_limits(policy);
+2 -1
drivers/cpufreq/cpufreq_ondemand.c
··· 76 76 return freq_next; 77 77 } 78 78 79 - index = cpufreq_frequency_table_target(policy, freq_next, relation); 79 + index = cpufreq_frequency_table_target(policy, freq_next, policy->min, 80 + policy->max, relation); 80 81 freq_req = freq_table[index].frequency; 81 82 freq_reduc = freq_req * od_tuners->powersave_bias / 1000; 82 83 freq_avg = freq_req - freq_reduc;
+3 -3
drivers/cpufreq/freq_table.c
··· 115 115 EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); 116 116 117 117 int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, 118 - unsigned int target_freq, 119 - unsigned int relation) 118 + unsigned int target_freq, unsigned int min, 119 + unsigned int max, unsigned int relation) 120 120 { 121 121 struct cpufreq_frequency_table optimal = { 122 122 .driver_data = ~0, ··· 147 147 cpufreq_for_each_valid_entry_idx(pos, table, i) { 148 148 freq = pos->frequency; 149 149 150 - if ((freq < policy->min) || (freq > policy->max)) 150 + if (freq < min || freq > max) 151 151 continue; 152 152 if (freq == target_freq) { 153 153 optimal.driver_data = i;
+3
drivers/cpufreq/intel_pstate.c
··· 598 598 { 599 599 u64 misc_en; 600 600 601 + if (!cpu_feature_enabled(X86_FEATURE_IDA)) 602 + return true; 603 + 601 604 rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); 602 605 603 606 return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
+13 -23
drivers/soundwire/intel_auxdevice.c
··· 353 353 /* use generic bandwidth allocation algorithm */ 354 354 sdw->cdns.bus.compute_params = sdw_compute_params; 355 355 356 - /* avoid resuming from pm_runtime suspend if it's not required */ 357 - dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND); 358 - 359 356 ret = sdw_bus_master_add(bus, dev, dev->fwnode); 360 357 if (ret) { 361 358 dev_err(dev, "sdw_bus_master_add fail: %d\n", ret); ··· 637 640 return 0; 638 641 } 639 642 640 - if (pm_runtime_suspended(dev)) { 643 + /* Prevent runtime PM from racing with the code below. */ 644 + pm_runtime_disable(dev); 645 + 646 + if (pm_runtime_status_suspended(dev)) { 641 647 dev_dbg(dev, "pm_runtime status: suspended\n"); 642 648 643 649 clock_stop_quirks = sdw->link_res->clock_stop_quirks; ··· 648 648 if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || 649 649 !clock_stop_quirks) { 650 650 651 - if (pm_runtime_suspended(dev->parent)) { 651 + if (pm_runtime_status_suspended(dev->parent)) { 652 652 /* 653 653 * paranoia check: this should not happen with the .prepare 654 654 * resume to full power ··· 715 715 struct sdw_cdns *cdns = dev_get_drvdata(dev); 716 716 struct sdw_intel *sdw = cdns_to_intel(cdns); 717 717 struct sdw_bus *bus = &cdns->bus; 718 - int link_flags; 719 718 int ret; 720 719 721 720 if (bus->prop.hw_disabled || !sdw->startup_done) { 722 721 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 723 722 bus->link_id); 724 723 return 0; 725 - } 726 - 727 - if (pm_runtime_suspended(dev)) { 728 - dev_dbg(dev, "pm_runtime status was suspended, forcing active\n"); 729 - 730 - /* follow required sequence from runtime_pm.rst */ 731 - pm_runtime_disable(dev); 732 - pm_runtime_set_active(dev); 733 - pm_runtime_mark_last_busy(dev); 734 - pm_runtime_enable(dev); 735 - 736 - pm_runtime_resume(bus->dev); 737 - 738 - link_flags = md_flags >> (bus->link_id * 8); 739 - 740 - if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) 741 - pm_runtime_idle(dev); 742 724 } 743 725 744 726 ret = sdw_intel_link_power_up(sdw); ··· 741 759 sdw_intel_link_power_down(sdw); 742 760 return ret; 743 761 } 762 + 763 + /* 764 + * Runtime PM has been disabled in intel_suspend(), so set the status 765 + * to active because the device has just been resumed and re-enable 766 + * runtime PM. 767 + */ 768 + pm_runtime_set_active(dev); 769 + pm_runtime_enable(dev); 744 770 745 771 /* 746 772 * after system resume, the pm_runtime suspend() may kick in
+54 -29
include/linux/cpufreq.h
··· 776 776 int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy); 777 777 778 778 int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, 779 - unsigned int target_freq, 780 - unsigned int relation); 779 + unsigned int target_freq, unsigned int min, 780 + unsigned int max, unsigned int relation); 781 781 int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, 782 782 unsigned int freq); 783 783 ··· 840 840 return best; 841 841 } 842 842 843 - /* Works only on sorted freq-tables */ 844 - static inline int cpufreq_table_find_index_l(struct cpufreq_policy *policy, 845 - unsigned int target_freq, 846 - bool efficiencies) 843 + static inline int find_index_l(struct cpufreq_policy *policy, 844 + unsigned int target_freq, 845 + unsigned int min, unsigned int max, 846 + bool efficiencies) 847 847 { 848 - target_freq = clamp_val(target_freq, policy->min, policy->max); 848 + target_freq = clamp_val(target_freq, min, max); 849 849 850 850 if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) 851 851 return cpufreq_table_find_index_al(policy, target_freq, ··· 853 853 else 854 854 return cpufreq_table_find_index_dl(policy, target_freq, 855 855 efficiencies); 856 + } 857 + 858 + /* Works only on sorted freq-tables */ 859 + static inline int cpufreq_table_find_index_l(struct cpufreq_policy *policy, 860 + unsigned int target_freq, 861 + bool efficiencies) 862 + { 863 + return find_index_l(policy, target_freq, policy->min, policy->max, efficiencies); 856 864 } 857 865 858 866 /* Find highest freq at or below target in a table in ascending order */ ··· 916 908 return best; 917 909 } 918 910 919 - /* Works only on sorted freq-tables */ 920 - static inline int cpufreq_table_find_index_h(struct cpufreq_policy *policy, 921 - unsigned int target_freq, 922 - bool efficiencies) 911 + static inline int find_index_h(struct cpufreq_policy *policy, 912 + unsigned int target_freq, 913 + unsigned int min, unsigned int max, 914 + bool efficiencies) 923 915 { 924 - target_freq = clamp_val(target_freq, policy->min, policy->max); 916 + target_freq = clamp_val(target_freq, min, max); 925 917 926 918 if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) 927 919 return cpufreq_table_find_index_ah(policy, target_freq, ··· 929 921 else 930 922 return cpufreq_table_find_index_dh(policy, target_freq, 931 923 efficiencies); 924 + } 925 + 926 + /* Works only on sorted freq-tables */ 927 + static inline int cpufreq_table_find_index_h(struct cpufreq_policy *policy, 928 + unsigned int target_freq, 929 + bool efficiencies) 930 + { 931 + return find_index_h(policy, target_freq, policy->min, policy->max, efficiencies); 932 932 } 933 933 934 934 /* Find closest freq to target in a table in ascending order */ ··· 1009 993 return best; 1010 994 } 1011 995 1012 - /* Works only on sorted freq-tables */ 1013 - static inline int cpufreq_table_find_index_c(struct cpufreq_policy *policy, 1014 - unsigned int target_freq, 1015 - bool efficiencies) 996 + static inline int find_index_c(struct cpufreq_policy *policy, 997 + unsigned int target_freq, 998 + unsigned int min, unsigned int max, 999 + bool efficiencies) 1016 1000 { 1017 - target_freq = clamp_val(target_freq, policy->min, policy->max); 1001 + target_freq = clamp_val(target_freq, min, max); 1018 1002 1019 1003 if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) 1020 1004 return cpufreq_table_find_index_ac(policy, target_freq, ··· 1024 1008 efficiencies); 1025 1009 } 1026 1010 1027 - static inline bool cpufreq_is_in_limits(struct cpufreq_policy *policy, int idx) 1011 + /* Works only on sorted freq-tables */ 1012 + static inline int cpufreq_table_find_index_c(struct cpufreq_policy *policy, 1013 + unsigned int target_freq, 1014 + bool efficiencies) 1015 + { 1016 + return find_index_c(policy, target_freq, policy->min, policy->max, efficiencies); 1017 + } 1018 + 1019 + static inline bool cpufreq_is_in_limits(struct cpufreq_policy *policy, 1020 + unsigned int min, unsigned int max, 1021 + int idx) 1028 1022 { 1029 1023 unsigned int freq; 1030 1024 ··· 1043 1017 1044 1018 freq = policy->freq_table[idx].frequency; 1045 1019 1046 - return freq == clamp_val(freq, policy->min, policy->max); 1020 + return freq == clamp_val(freq, min, max); 1047 1021 } 1048 1022 1049 1023 static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy, 1050 1024 unsigned int target_freq, 1025 + unsigned int min, 1026 + unsigned int max, 1051 1027 unsigned int relation) 1052 1028 { 1053 1029 bool efficiencies = policy->efficiencies_available && ··· 1060 1032 relation &= ~CPUFREQ_RELATION_E; 1061 1033 1062 1034 if (unlikely(policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED)) 1063 - return cpufreq_table_index_unsorted(policy, target_freq, 1064 - relation); 1035 + return cpufreq_table_index_unsorted(policy, target_freq, min, 1036 + max, relation); 1065 1037 retry: 1066 1038 switch (relation) { 1067 1039 case CPUFREQ_RELATION_L: 1068 - idx = cpufreq_table_find_index_l(policy, target_freq, 1069 - efficiencies); 1040 + idx = find_index_l(policy, target_freq, min, max, efficiencies); 1070 1041 break; 1071 1042 case CPUFREQ_RELATION_H: 1072 - idx = cpufreq_table_find_index_h(policy, target_freq, 1073 - efficiencies); 1043 + idx = find_index_h(policy, target_freq, min, max, efficiencies); 1074 1044 break; 1075 1045 case CPUFREQ_RELATION_C: 1076 - idx = cpufreq_table_find_index_c(policy, target_freq, 1077 - efficiencies); 1046 + idx = find_index_c(policy, target_freq, min, max, efficiencies); 1078 1047 break; 1079 1048 default: 1080 1049 WARN_ON_ONCE(1); 1081 1050 return 0; 1082 1051 } 1083 1052 1084 - /* Limit frequency index to honor policy->min/max */ 1085 - if (!cpufreq_is_in_limits(policy, idx) && efficiencies) { 1053 + /* Limit frequency index to honor min and max */ 1054 + if (!cpufreq_is_in_limits(policy, min, max, idx) && efficiencies) { 1086 1055 efficiencies = false; 1087 1056 goto retry; 1088 1057 }