cpufreq: amd-pstate: Restore previous mode when changing driver mode fails

amd_pstate_change_driver_mode() unregisters the currently active driver
before registering the requested mode.  If amd_pstate_register_driver()
fails for the new mode, the function returns the error without restoring
anything, leaving the system with no cpufreq scaling driver at all until
a valid mode is manually re-selected.

Remember the mode that was active before the transition and, if
registering the requested mode fails, register the previous mode again so
the system keeps a working scaling driver.  The original error is still
returned to the caller so the sysfs write reports the failure.

Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-5b138ddb-c88b-4f82-8a2d-f39446b625d4
Fixes: 3ca7bc818d ("cpufreq: amd-pstate: Add guided mode control support via sysfs")
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20260921190235.3651688-1-mario.limonciello@amd.com
Signed-off-by: Mario Limonciello <superm1@kernel.org>
This commit is contained in:
Mario Limonciello 2026-09-21 14:02:32 -05:00 committed by Mario Limonciello
parent b3f9051ae2
commit f6d3cbc639

View File

@ -1837,6 +1837,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode)
static int amd_pstate_change_driver_mode(int mode)
{
int old_mode = cppc_state;
int ret;
lockdep_assert_held(&amd_pstate_driver_lock);
@ -1846,10 +1847,16 @@ static int amd_pstate_change_driver_mode(int mode)
return ret;
ret = amd_pstate_register_driver(mode);
if (ret)
return ret;
if (ret) {
pr_err("Failed to register %s mode, restoring %s mode\n",
amd_pstate_get_mode_string(mode),
amd_pstate_get_mode_string(old_mode));
if (amd_pstate_register_driver(old_mode))
pr_err("Failed to restore %s mode\n",
amd_pstate_get_mode_string(old_mode));
}
return 0;
return ret;
}
static cppc_mode_transition_fn mode_state_machine[AMD_PSTATE_MAX][AMD_PSTATE_MAX] = {