提交 fde5f74c 编写于 作者: M Mark Pearson 提交者: Hans de Goede

platform/x86: thinkpad_acpi: Fix profile mode display in AMT mode

Recently AMT mode was enabled (somewhat unexpectedly) on the Lenovo
Z13 platform. The FW is advertising it is available and the driver tries
to use it - unfortunately it reports the profile mode incorrectly.

Note, there is also some extra work needed to enable the dynamic aspect
of AMT support that I will be following up with; but more testing is
needed first. This patch just fixes things so the profiles are reported
correctly.

Link: https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/issues/115
Fixes: 46dcbc61 ("platform/x86: thinkpad-acpi: Add support for automatic mode transitions")
Reviewed-by: NMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: NMark Pearson <mpearson-lenovo@squebb.ca>
Link: https://lore.kernel.org/r/20230112221228.490946-1-mpearson-lenovo@squebb.caReviewed-by: NHans de Goede <hdegoede@redhat.com>
Signed-off-by: NHans de Goede <hdegoede@redhat.com>
上级 cf5ac2d4
...@@ -10311,9 +10311,11 @@ static DEFINE_MUTEX(dytc_mutex); ...@@ -10311,9 +10311,11 @@ static DEFINE_MUTEX(dytc_mutex);
static int dytc_capabilities; static int dytc_capabilities;
static bool dytc_mmc_get_available; static bool dytc_mmc_get_available;
static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *profile) static int convert_dytc_to_profile(int funcmode, int dytcmode,
enum platform_profile_option *profile)
{ {
if (dytc_capabilities & BIT(DYTC_FC_MMC)) { switch (funcmode) {
case DYTC_FUNCTION_MMC:
switch (dytcmode) { switch (dytcmode) {
case DYTC_MODE_MMC_LOWPOWER: case DYTC_MODE_MMC_LOWPOWER:
*profile = PLATFORM_PROFILE_LOW_POWER; *profile = PLATFORM_PROFILE_LOW_POWER;
...@@ -10329,8 +10331,7 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p ...@@ -10329,8 +10331,7 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
} case DYTC_FUNCTION_PSC:
if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
switch (dytcmode) { switch (dytcmode) {
case DYTC_MODE_PSC_LOWPOWER: case DYTC_MODE_PSC_LOWPOWER:
*profile = PLATFORM_PROFILE_LOW_POWER; *profile = PLATFORM_PROFILE_LOW_POWER;
...@@ -10344,6 +10345,14 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p ...@@ -10344,6 +10345,14 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
default: /* Unknown mode */ default: /* Unknown mode */
return -EINVAL; return -EINVAL;
} }
return 0;
case DYTC_FUNCTION_AMT:
/* For now return balanced. It's the closest we have to 'auto' */
*profile = PLATFORM_PROFILE_BALANCED;
return 0;
default:
/* Unknown function */
return -EOPNOTSUPP;
} }
return 0; return 0;
} }
...@@ -10492,6 +10501,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof, ...@@ -10492,6 +10501,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output); err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output);
if (err) if (err)
goto unlock; goto unlock;
/* system supports AMT, activate it when on balanced */ /* system supports AMT, activate it when on balanced */
if (dytc_capabilities & BIT(DYTC_FC_AMT)) if (dytc_capabilities & BIT(DYTC_FC_AMT))
dytc_control_amt(profile == PLATFORM_PROFILE_BALANCED); dytc_control_amt(profile == PLATFORM_PROFILE_BALANCED);
...@@ -10507,7 +10517,7 @@ static void dytc_profile_refresh(void) ...@@ -10507,7 +10517,7 @@ static void dytc_profile_refresh(void)
{ {
enum platform_profile_option profile; enum platform_profile_option profile;
int output, err = 0; int output, err = 0;
int perfmode; int perfmode, funcmode;
mutex_lock(&dytc_mutex); mutex_lock(&dytc_mutex);
if (dytc_capabilities & BIT(DYTC_FC_MMC)) { if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
...@@ -10522,8 +10532,9 @@ static void dytc_profile_refresh(void) ...@@ -10522,8 +10532,9 @@ static void dytc_profile_refresh(void)
if (err) if (err)
return; return;
funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF;
perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF; perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF;
convert_dytc_to_profile(perfmode, &profile); convert_dytc_to_profile(funcmode, perfmode, &profile);
if (profile != dytc_current_profile) { if (profile != dytc_current_profile) {
dytc_current_profile = profile; dytc_current_profile = profile;
platform_profile_notify(); platform_profile_notify();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册