Skip to content

Commit

Permalink
Merge tag 'pm-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/rafael/linux-pm

Pull power management updates from Rafael Wysocki:
 "These add Intel TPMI (Topology Aware Register and PM Capsule
  Interface) support to the power capping subsystem, extend the
  intel_idle driver to work in VM guests where MWAIT is not available,
  extend the system-wide power management diagnostics, fix bugs and
  clean up code.

  Specifics:

   - Introduce power capping core support for Intel TPMI (Topology Aware
     Register and PM Capsule Interface) and a TPMI interface driver for
     Intel RAPL (Zhang Rui, Dan Carpenter)

   - Fix CONFIG_IOSF_MBI dependency in the Intel RAPL power capping
     driver (Zhang Rui)

   - Fix invalid initialization for pl4_supported field in the Intel
     RAPL power capping driver (Sumeet Pawnikar)

   - Clean up the intel_idle driver, make it work with VM guests that
     cannot use the MWAIT instruction and address the case in which the
     host may enter a deep idle state when the guest is idle (Arjan van
     de Ven)

   - Prevent cpufreq drivers that provide the ->adjust_perf() callback
     without a ->fast_switch() one which is used as a fallback from the
     former in some cases (Wyes Karny)

   - Fix some issues related to the AMD P-state cpufreq driver (Mario
     Limonciello, Wyes Karny)

   - Fix the energy_performance_preference attribute handling in the
     intel_pstate driver in passive mode (Tero Kristo)

   - Fix the handling of pm_suspend_target_state when CONFIG_PM is unset
     (Kai-Heng Feng)

   - Correct spelling mistake in a comment in the hibernation code (Wang
     Honghui)

   - Add arch_resume_nosmt() prototype to avoid a "missing prototypes"
     build warning (Arnd Bergmann)

   - Restrict pm_pr_dbg() to system-wide power transitions and use it in
     a few additional places (Mario Limonciello)

   - Drop verification of in-params from genpd_add_device() and ensure
     that all of its callers will do it (Ulf Hansson)

   - Prevent possible integer overflows from occurring in
     genpd_parse_state() (Nikita Zhandarovich)

   - Reorder fieldls in 'struct devfreq_dev_status' to reduce its size
     somewhat (Christophe JAILLET)

   - Ensure that the Exynos PPMU driver is already loaded before the
     Exynos Bus driver starts probing so as to avoid a possible freeze
     loading of the kernel modules (Marek Szyprowski)

   - Fix variable deferencing before NULL check in the mtk-cci devfreq
     driver (Sukrut Bellary)"

* tag 'pm-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (42 commits)
  intel_idle: Add a "Long HLT" C1 state for the VM guest mode
  cpufreq: intel_pstate: Fix energy_performance_preference for passive
  cpufreq: amd-pstate: Add a kernel config option to set default mode
  cpufreq: amd-pstate: Set a fallback policy based on preferred_profile
  ACPI: CPPC: Add definition for undefined FADT preferred PM profile value
  cpufreq: amd-pstate: Set default governor to schedutil
  PM: domains: Move the verification of in-params from genpd_add_device()
  cpufreq: amd-pstate: Make amd-pstate EPP driver name hyphenated
  cpufreq: amd-pstate: Write CPPC enable bit per-socket
  intel_idle: Add support for using intel_idle in a VM guest using just hlt
  cpufreq: Fail driver register if it has adjust_perf without fast_switch
  intel_idle: clean up the (new) state_update_enter_method function
  intel_idle: refactor state->enter manipulation into its own function
  platform/x86/amd: pmc: Use pm_pr_dbg() for suspend related messages
  pinctrl: amd: Use pm_pr_dbg to show debugging messages
  ACPI: x86: Add pm_debug_messages for LPS0 _DSM state tracking
  include/linux/suspend.h: Only show pm_pr_dbg messages at suspend/resume
  powercap: RAPL: Fix a NULL vs IS_ERR() bug
  powercap: RAPL: Fix CONFIG_IOSF_MBI dependency
  powercap: RAPL: fix invalid initialization for pl4_supported field
  ...
  • Loading branch information
Linus Torvalds committed Jun 27, 2023
2 parents bb69505 + c89a27f commit 40e8e98
Show file tree
Hide file tree
Showing 27 changed files with 1,324 additions and 494 deletions.
52 changes: 46 additions & 6 deletions drivers/acpi/x86/s2idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ static int lps0_dsm_func_mask;

static guid_t lps0_dsm_guid_microsoft;
static int lps0_dsm_func_mask_microsoft;
static int lps0_dsm_state;

/* Device constraint entry structure */
struct lpi_device_info {
Expand Down Expand Up @@ -320,6 +321,44 @@ static void lpi_check_constraints(void)
}
}

static bool acpi_s2idle_vendor_amd(void)
{
return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
}

static const char *acpi_sleep_dsm_state_to_str(unsigned int state)
{
if (lps0_dsm_func_mask_microsoft || !acpi_s2idle_vendor_amd()) {
switch (state) {
case ACPI_LPS0_SCREEN_OFF:
return "screen off";
case ACPI_LPS0_SCREEN_ON:
return "screen on";
case ACPI_LPS0_ENTRY:
return "lps0 entry";
case ACPI_LPS0_EXIT:
return "lps0 exit";
case ACPI_LPS0_MS_ENTRY:
return "lps0 ms entry";
case ACPI_LPS0_MS_EXIT:
return "lps0 ms exit";
}
} else {
switch (state) {
case ACPI_LPS0_SCREEN_ON_AMD:
return "screen on";
case ACPI_LPS0_SCREEN_OFF_AMD:
return "screen off";
case ACPI_LPS0_ENTRY_AMD:
return "lps0 entry";
case ACPI_LPS0_EXIT_AMD:
return "lps0 exit";
}
}

return "unknown";
}

static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, guid_t dsm_guid)
{
union acpi_object *out_obj;
Expand All @@ -331,14 +370,15 @@ static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, g
rev_id, func, NULL);
ACPI_FREE(out_obj);

acpi_handle_debug(lps0_device_handle, "_DSM function %u evaluation %s\n",
func, out_obj ? "successful" : "failed");
lps0_dsm_state = func;
if (pm_debug_messages_on) {
acpi_handle_info(lps0_device_handle,
"%s transitioned to state %s\n",
out_obj ? "Successfully" : "Failed to",
acpi_sleep_dsm_state_to_str(lps0_dsm_state));
}
}

static bool acpi_s2idle_vendor_amd(void)
{
return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
}

static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *dsm_guid)
{
Expand Down
15 changes: 9 additions & 6 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,9 +1632,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,

dev_dbg(dev, "%s()\n", __func__);

if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
return -EINVAL;

gpd_data = genpd_alloc_dev_data(dev, gd);
if (IS_ERR(gpd_data))
return PTR_ERR(gpd_data);
Expand Down Expand Up @@ -1676,6 +1673,9 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
{
int ret;

if (!genpd || !dev)
return -EINVAL;

mutex_lock(&gpd_list_lock);
ret = genpd_add_device(genpd, dev, dev);
mutex_unlock(&gpd_list_lock);
Expand Down Expand Up @@ -2523,6 +2523,9 @@ int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev)
struct generic_pm_domain *genpd;
int ret;

if (!dev)
return -EINVAL;

mutex_lock(&gpd_list_lock);

genpd = genpd_get_from_provider(genpdspec);
Expand Down Expand Up @@ -2939,10 +2942,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,

err = of_property_read_u32(state_node, "min-residency-us", &residency);
if (!err)
genpd_state->residency_ns = 1000 * residency;
genpd_state->residency_ns = 1000LL * residency;

genpd_state->power_on_latency_ns = 1000 * exit_latency;
genpd_state->power_off_latency_ns = 1000 * entry_latency;
genpd_state->power_on_latency_ns = 1000LL * exit_latency;
genpd_state->power_off_latency_ns = 1000LL * entry_latency;
genpd_state->fwnode = &state_node->fwnode;

return 0;
Expand Down
5 changes: 0 additions & 5 deletions drivers/base/power/wakeup.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@

#include "power.h"

#ifndef CONFIG_SUSPEND
suspend_state_t pm_suspend_target_state;
#define pm_suspend_target_state (PM_SUSPEND_ON)
#endif

#define list_for_each_entry_rcu_locked(pos, head, member) \
list_for_each_entry_rcu(pos, head, member, \
srcu_read_lock_held(&wakeup_srcu))
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ choice
prompt "Default CPUFreq governor"
default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1110_CPUFREQ
default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if ARM64 || ARM
default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if X86_INTEL_PSTATE && SMP
default CPU_FREQ_DEFAULT_GOV_SCHEDUTIL if (X86_INTEL_PSTATE || X86_AMD_PSTATE) && SMP
default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
help
This option sets which CPUFreq governor shall be loaded at
Expand Down
17 changes: 17 additions & 0 deletions drivers/cpufreq/Kconfig.x86
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,23 @@ config X86_AMD_PSTATE

If in doubt, say N.

config X86_AMD_PSTATE_DEFAULT_MODE
int "AMD Processor P-State default mode"
depends on X86_AMD_PSTATE
default 3 if X86_AMD_PSTATE
range 1 4
help
Select the default mode the amd-pstate driver will use on
supported hardware.
The value set has the following meanings:
1 -> Disabled
2 -> Passive
3 -> Active (EPP)
4 -> Guided

For details, take a look at:
<file:Documentation/admin-guide/pm/amd-pstate.rst>.

config X86_AMD_PSTATE_UT
tristate "selftest for AMD Processor P-State driver"
depends on X86 && ACPI_PROCESSOR
Expand Down
131 changes: 102 additions & 29 deletions drivers/cpufreq/amd-pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
static struct cpufreq_driver *current_pstate_driver;
static struct cpufreq_driver amd_pstate_driver;
static struct cpufreq_driver amd_pstate_epp_driver;
static int cppc_state = AMD_PSTATE_DISABLE;
static int cppc_state = AMD_PSTATE_UNDEFINED;
static bool cppc_enabled;

/*
* AMD Energy Preference Performance (EPP)
Expand Down Expand Up @@ -228,14 +229,38 @@ static int amd_pstate_set_energy_pref_index(struct amd_cpudata *cpudata,

static inline int pstate_enable(bool enable)
{
return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable);
int ret, cpu;
unsigned long logical_proc_id_mask = 0;

if (enable == cppc_enabled)
return 0;

for_each_present_cpu(cpu) {
unsigned long logical_id = topology_logical_die_id(cpu);

if (test_bit(logical_id, &logical_proc_id_mask))
continue;

set_bit(logical_id, &logical_proc_id_mask);

ret = wrmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_ENABLE,
enable);
if (ret)
return ret;
}

cppc_enabled = enable;
return 0;
}

static int cppc_enable(bool enable)
{
int cpu, ret = 0;
struct cppc_perf_ctrls perf_ctrls;

if (enable == cppc_enabled)
return 0;

for_each_present_cpu(cpu) {
ret = cppc_set_enable(cpu, enable);
if (ret)
Expand All @@ -251,6 +276,7 @@ static int cppc_enable(bool enable)
}
}

cppc_enabled = enable;
return ret;
}

Expand Down Expand Up @@ -1045,6 +1071,26 @@ static const struct attribute_group amd_pstate_global_attr_group = {
.attrs = pstate_global_attributes,
};

static bool amd_pstate_acpi_pm_profile_server(void)
{
switch (acpi_gbl_FADT.preferred_profile) {
case PM_ENTERPRISE_SERVER:
case PM_SOHO_SERVER:
case PM_PERFORMANCE_SERVER:
return true;
}
return false;
}

static bool amd_pstate_acpi_pm_profile_undefined(void)
{
if (acpi_gbl_FADT.preferred_profile == PM_UNSPECIFIED)
return true;
if (acpi_gbl_FADT.preferred_profile >= NR_PM_PROFILES)
return true;
return false;
}

static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
{
int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
Expand Down Expand Up @@ -1102,10 +1148,14 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
policy->max = policy->cpuinfo.max_freq;

/*
* Set the policy to powersave to provide a valid fallback value in case
* Set the policy to provide a valid fallback value in case
* the default cpufreq governor is neither powersave nor performance.
*/
policy->policy = CPUFREQ_POLICY_POWERSAVE;
if (amd_pstate_acpi_pm_profile_server() ||
amd_pstate_acpi_pm_profile_undefined())
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
else
policy->policy = CPUFREQ_POLICY_POWERSAVE;

if (boot_cpu_has(X86_FEATURE_CPPC)) {
ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
Expand Down Expand Up @@ -1356,26 +1406,36 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
.online = amd_pstate_epp_cpu_online,
.suspend = amd_pstate_epp_suspend,
.resume = amd_pstate_epp_resume,
.name = "amd_pstate_epp",
.name = "amd-pstate-epp",
.attr = amd_pstate_epp_attr,
};

static int __init amd_pstate_set_driver(int mode_idx)
{
if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
cppc_state = mode_idx;
if (cppc_state == AMD_PSTATE_DISABLE)
pr_info("driver is explicitly disabled\n");

if (cppc_state == AMD_PSTATE_ACTIVE)
current_pstate_driver = &amd_pstate_epp_driver;

if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
current_pstate_driver = &amd_pstate_driver;

return 0;
}

return -EINVAL;
}

static int __init amd_pstate_init(void)
{
struct device *dev_root;
int ret;

if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return -ENODEV;
/*
* by default the pstate driver is disabled to load
* enable the amd_pstate passive mode driver explicitly
* with amd_pstate=passive or other modes in kernel command line
*/
if (cppc_state == AMD_PSTATE_DISABLE) {
pr_info("driver load is disabled, boot with specific mode to enable this\n");
return -ENODEV;
}

if (!acpi_cpc_valid()) {
pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n");
Expand All @@ -1386,6 +1446,33 @@ static int __init amd_pstate_init(void)
if (cpufreq_get_current_driver())
return -EEXIST;

switch (cppc_state) {
case AMD_PSTATE_UNDEFINED:
/* Disable on the following configs by default:
* 1. Undefined platforms
* 2. Server platforms
* 3. Shared memory designs
*/
if (amd_pstate_acpi_pm_profile_undefined() ||
amd_pstate_acpi_pm_profile_server() ||
!boot_cpu_has(X86_FEATURE_CPPC)) {
pr_info("driver load is disabled, boot with specific mode to enable this\n");
return -ENODEV;
}
ret = amd_pstate_set_driver(CONFIG_X86_AMD_PSTATE_DEFAULT_MODE);
if (ret)
return ret;
break;
case AMD_PSTATE_DISABLE:
return -ENODEV;
case AMD_PSTATE_PASSIVE:
case AMD_PSTATE_ACTIVE:
case AMD_PSTATE_GUIDED:
break;
default:
return -EINVAL;
}

/* capability check */
if (boot_cpu_has(X86_FEATURE_CPPC)) {
pr_debug("AMD CPPC MSR based functionality is supported\n");
Expand Down Expand Up @@ -1438,21 +1525,7 @@ static int __init amd_pstate_param(char *str)
size = strlen(str);
mode_idx = get_mode_idx_from_str(str, size);

if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
cppc_state = mode_idx;
if (cppc_state == AMD_PSTATE_DISABLE)
pr_info("driver is explicitly disabled\n");

if (cppc_state == AMD_PSTATE_ACTIVE)
current_pstate_driver = &amd_pstate_epp_driver;

if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
current_pstate_driver = &amd_pstate_driver;

return 0;
}

return -EINVAL;
return amd_pstate_set_driver(mode_idx);
}
early_param("amd_pstate", amd_pstate_param);

Expand Down
3 changes: 2 additions & 1 deletion drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -2828,7 +2828,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
(driver_data->setpolicy && (driver_data->target_index ||
driver_data->target)) ||
(!driver_data->get_intermediate != !driver_data->target_intermediate) ||
(!driver_data->online != !driver_data->offline))
(!driver_data->online != !driver_data->offline) ||
(driver_data->adjust_perf && !driver_data->fast_switch))
return -EINVAL;

pr_debug("trying to register driver %s\n", driver_data->name);
Expand Down
2 changes: 2 additions & 0 deletions drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,8 @@ static ssize_t store_energy_performance_preference(
err = cpufreq_start_governor(policy);
if (!ret)
ret = err;
} else {
ret = 0;
}
}

Expand Down
1 change: 1 addition & 0 deletions drivers/devfreq/exynos-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ static struct platform_driver exynos_bus_platdrv = {
};
module_platform_driver(exynos_bus_platdrv);

MODULE_SOFTDEP("pre: exynos_ppmu");
MODULE_DESCRIPTION("Generic Exynos Bus frequency driver");
MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
MODULE_LICENSE("GPL v2");
Loading

0 comments on commit 40e8e98

Please sign in to comment.