From: Pavel Machek <pavel@ucw.cz>
To: Sasha Levin <sashal@kernel.org>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
"Vishnu Sankar" <vishnuocv@gmail.com>,
"Mark Pearson" <mpearson-lenovo@squebb.ca>,
"Hans de Goede" <hdegoede@redhat.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
hmh@hmh.eng.br, ibm-acpi-devel@lists.sourceforge.net,
platform-driver-x86@vger.kernel.org
Subject: Re: [PATCH AUTOSEL 6.1 12/24] platform/x86: thinkpad_acpi: fix for incorrect fan reporting on some ThinkPad systems
Date: Tue, 9 Jan 2024 12:46:03 +0100 [thread overview]
Message-ID: <ZZ0x+wlRGxwPOArK@duo.ucw.cz> (raw)
In-Reply-To: <20231226002255.5730-12-sashal@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 9515 bytes --]
Hi!
> [ Upstream commit 66e92e23a72761f5b53f970aeb1badc5fd92fc74 ]
>
> Some ThinkPad systems ECFW use non-standard addresses for fan control
> and reporting. This patch adds support for such ECFW so that it can report
> the correct fan values.
> Tested on Thinkpads L13 Yoga Gen 2 and X13 Yoga Gen 2.
This is just a new feature, and is > 200 lines. We should not have
this in stable.
BR,
Pavel
> Suggested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
> Signed-off-by: Vishnu Sankar <vishnuocv@gmail.com>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Link: https://lore.kernel.org/r/20231214134702.166464-1-vishnuocv@gmail.com
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> drivers/platform/x86/thinkpad_acpi.c | 98 ++++++++++++++++++++++++----
> 1 file changed, 85 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
> index 05a55bc31c796..6edd2e294750e 100644
> --- a/drivers/platform/x86/thinkpad_acpi.c
> +++ b/drivers/platform/x86/thinkpad_acpi.c
> @@ -8149,8 +8149,19 @@ static struct ibm_struct volume_driver_data = {
> * TPACPI_FAN_WR_TPEC is also available and should be used to
> * command the fan. The X31/X40/X41 seems to have 8 fan levels,
> * but the ACPI tables just mention level 7.
> + *
> + * TPACPI_FAN_RD_TPEC_NS:
> + * This mode is used for a few ThinkPads (L13 Yoga Gen2, X13 Yoga Gen2 etc.)
> + * that are using non-standard EC locations for reporting fan speeds.
> + * Currently these platforms only provide fan rpm reporting.
> + *
> */
>
> +#define FAN_RPM_CAL_CONST 491520 /* FAN RPM calculation offset for some non-standard ECFW */
> +
> +#define FAN_NS_CTRL_STATUS BIT(2) /* Bit which determines control is enabled or not */
> +#define FAN_NS_CTRL BIT(4) /* Bit which determines control is by host or EC */
> +
> enum { /* Fan control constants */
> fan_status_offset = 0x2f, /* EC register 0x2f */
> fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
> @@ -8158,6 +8169,11 @@ enum { /* Fan control constants */
> fan_select_offset = 0x31, /* EC register 0x31 (Firmware 7M)
> bit 0 selects which fan is active */
>
> + fan_status_offset_ns = 0x93, /* Special status/control offset for non-standard EC Fan1 */
> + fan2_status_offset_ns = 0x96, /* Special status/control offset for non-standard EC Fan2 */
> + fan_rpm_status_ns = 0x95, /* Special offset for Fan1 RPM status for non-standard EC */
> + fan2_rpm_status_ns = 0x98, /* Special offset for Fan2 RPM status for non-standard EC */
> +
> TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */
> TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */
>
> @@ -8168,6 +8184,7 @@ enum fan_status_access_mode {
> TPACPI_FAN_NONE = 0, /* No fan status or control */
> TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */
> TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */
> + TPACPI_FAN_RD_TPEC_NS, /* Use non-standard ACPI EC regs (eg: L13 Yoga gen2 etc.) */
> };
>
> enum fan_control_access_mode {
> @@ -8195,6 +8212,8 @@ static u8 fan_control_desired_level;
> static u8 fan_control_resume_level;
> static int fan_watchdog_maxinterval;
>
> +static bool fan_with_ns_addr;
> +
> static struct mutex fan_mutex;
>
> static void fan_watchdog_fire(struct work_struct *ignored);
> @@ -8325,6 +8344,15 @@ static int fan_get_status(u8 *status)
> }
>
> break;
> + case TPACPI_FAN_RD_TPEC_NS:
> + /* Default mode is AUTO which means controlled by EC */
> + if (!acpi_ec_read(fan_status_offset_ns, &s))
> + return -EIO;
> +
> + if (status)
> + *status = s;
> +
> + break;
>
> default:
> return -ENXIO;
> @@ -8341,7 +8369,8 @@ static int fan_get_status_safe(u8 *status)
> if (mutex_lock_killable(&fan_mutex))
> return -ERESTARTSYS;
> rc = fan_get_status(&s);
> - if (!rc)
> + /* NS EC doesn't have register with level settings */
> + if (!rc && !fan_with_ns_addr)
> fan_update_desired_level(s);
> mutex_unlock(&fan_mutex);
>
> @@ -8368,7 +8397,13 @@ static int fan_get_speed(unsigned int *speed)
>
> if (likely(speed))
> *speed = (hi << 8) | lo;
> + break;
> + case TPACPI_FAN_RD_TPEC_NS:
> + if (!acpi_ec_read(fan_rpm_status_ns, &lo))
> + return -EIO;
>
> + if (speed)
> + *speed = lo ? FAN_RPM_CAL_CONST / lo : 0;
> break;
>
> default:
> @@ -8380,7 +8415,7 @@ static int fan_get_speed(unsigned int *speed)
>
> static int fan2_get_speed(unsigned int *speed)
> {
> - u8 hi, lo;
> + u8 hi, lo, status;
> bool rc;
>
> switch (fan_status_access_mode) {
> @@ -8396,7 +8431,21 @@ static int fan2_get_speed(unsigned int *speed)
>
> if (likely(speed))
> *speed = (hi << 8) | lo;
> + break;
>
> + case TPACPI_FAN_RD_TPEC_NS:
> + rc = !acpi_ec_read(fan2_status_offset_ns, &status);
> + if (rc)
> + return -EIO;
> + if (!(status & FAN_NS_CTRL_STATUS)) {
> + pr_info("secondary fan control not supported\n");
> + return -EIO;
> + }
> + rc = !acpi_ec_read(fan2_rpm_status_ns, &lo);
> + if (rc)
> + return -EIO;
> + if (speed)
> + *speed = lo ? FAN_RPM_CAL_CONST / lo : 0;
> break;
>
> default:
> @@ -8899,6 +8948,7 @@ static const struct attribute_group fan_driver_attr_group = {
> #define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */
> #define TPACPI_FAN_2CTL 0x0004 /* selects fan2 control */
> #define TPACPI_FAN_NOFAN 0x0008 /* no fan available */
> +#define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */
>
> static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
> TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1),
> @@ -8917,6 +8967,8 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
> TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */
> TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */
> TPACPI_Q_LNV3('N', '3', '7', TPACPI_FAN_2CTL), /* T15g (2nd gen) */
> + TPACPI_Q_LNV3('R', '1', 'F', TPACPI_FAN_NS), /* L13 Yoga Gen 2 */
> + TPACPI_Q_LNV3('N', '2', 'U', TPACPI_FAN_NS), /* X13 Yoga Gen 2*/
> TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */
> };
>
> @@ -8951,18 +9003,27 @@ static int __init fan_init(struct ibm_init_struct *iibm)
> return -ENODEV;
> }
>
> + if (quirks & TPACPI_FAN_NS) {
> + pr_info("ECFW with non-standard fan reg control found\n");
> + fan_with_ns_addr = 1;
> + /* Fan ctrl support from host is undefined for now */
> + tp_features.fan_ctrl_status_undef = 1;
> + }
> +
> if (gfan_handle) {
> /* 570, 600e/x, 770e, 770x */
> fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
> } else {
> /* all other ThinkPads: note that even old-style
> * ThinkPad ECs supports the fan control register */
> - if (likely(acpi_ec_read(fan_status_offset,
> - &fan_control_initial_status))) {
> + if (fan_with_ns_addr ||
> + likely(acpi_ec_read(fan_status_offset, &fan_control_initial_status))) {
> int res;
> unsigned int speed;
>
> - fan_status_access_mode = TPACPI_FAN_RD_TPEC;
> + fan_status_access_mode = fan_with_ns_addr ?
> + TPACPI_FAN_RD_TPEC_NS : TPACPI_FAN_RD_TPEC;
> +
> if (quirks & TPACPI_FAN_Q1)
> fan_quirk1_setup();
> /* Try and probe the 2nd fan */
> @@ -8971,7 +9032,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
> if (res >= 0 && speed != FAN_NOT_PRESENT) {
> /* It responded - so let's assume it's there */
> tp_features.second_fan = 1;
> - tp_features.second_fan_ctl = 1;
> + /* fan control not currently available for ns ECFW */
> + tp_features.second_fan_ctl = !fan_with_ns_addr;
> pr_info("secondary fan control detected & enabled\n");
> } else {
> /* Fan not auto-detected */
> @@ -9146,6 +9208,7 @@ static int fan_read(struct seq_file *m)
> str_enabled_disabled(status), status);
> break;
>
> + case TPACPI_FAN_RD_TPEC_NS:
> case TPACPI_FAN_RD_TPEC:
> /* all except 570, 600e/x, 770e, 770x */
> rc = fan_get_status_safe(&status);
> @@ -9160,13 +9223,22 @@ static int fan_read(struct seq_file *m)
>
> seq_printf(m, "speed:\t\t%d\n", speed);
>
> - if (status & TP_EC_FAN_FULLSPEED)
> - /* Disengaged mode takes precedence */
> - seq_printf(m, "level:\t\tdisengaged\n");
> - else if (status & TP_EC_FAN_AUTO)
> - seq_printf(m, "level:\t\tauto\n");
> - else
> - seq_printf(m, "level:\t\t%d\n", status);
> + if (fan_status_access_mode == TPACPI_FAN_RD_TPEC_NS) {
> + /*
> + * No full speed bit in NS EC
> + * EC Auto mode is set by default.
> + * No other levels settings available
> + */
> + seq_printf(m, "level:\t\t%s\n", status & FAN_NS_CTRL ? "unknown" : "auto");
> + } else {
> + if (status & TP_EC_FAN_FULLSPEED)
> + /* Disengaged mode takes precedence */
> + seq_printf(m, "level:\t\tdisengaged\n");
> + else if (status & TP_EC_FAN_AUTO)
> + seq_printf(m, "level:\t\tauto\n");
> + else
> + seq_printf(m, "level:\t\t%d\n", status);
> + }
> break;
>
> case TPACPI_FAN_NONE:
--
People of Russia, stop Putin before his war on Ukraine escalates.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
next prev parent reply other threads:[~2024-01-09 11:46 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-26 0:21 [PATCH AUTOSEL 6.1 01/24] Input: psmouse - enable Synaptics InterTouch for ThinkPad L14 G1 Sasha Levin
2023-12-26 0:21 ` [PATCH AUTOSEL 6.1 02/24] reset: hisilicon: hi6220: fix Wvoid-pointer-to-enum-cast warning Sasha Levin
2023-12-26 0:21 ` [PATCH AUTOSEL 6.1 03/24] Input: atkbd - skip ATKBD_CMD_GETID in translated mode Sasha Levin
2023-12-26 0:21 ` [PATCH AUTOSEL 6.1 04/24] Input: i8042 - add nomux quirk for Acer P459-G2-M Sasha Levin
2023-12-26 0:21 ` [PATCH AUTOSEL 6.1 05/24] Input: amimouse - convert to platform remove callback returning void Sasha Levin
2023-12-26 0:21 ` [PATCH AUTOSEL 6.1 06/24] s390/scm: fix virtual vs physical address confusion Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 07/24] ARC: fix spare error Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 08/24] wifi: iwlwifi: pcie: avoid a NULL pointer dereference Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 09/24] Input: xpad - add Razer Wolverine V2 support Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 10/24] kselftest: alsa: fixed a print formatting warning Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 11/24] HID: nintendo: fix initializer element is not constant error Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 12/24] platform/x86: thinkpad_acpi: fix for incorrect fan reporting on some ThinkPad systems Sasha Levin
2024-01-09 11:46 ` Pavel Machek [this message]
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 13/24] ASoC: Intel: bytcr_rt5640: Add quirk for the Medion Lifetab S10346 Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 14/24] ASoC: Intel: bytcr_rt5640: Add new swapped-speakers quirk Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 15/24] ALSA: hda/realtek: Add quirks for ASUS Zenbook 2022 Models Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 16/24] dm audit: fix Kconfig so DM_AUDIT depends on BLK_DEV_DM Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 17/24] HID: nintendo: Prevent divide-by-zero on code Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 18/24] smb: client: fix potential OOB in smb2_dump_detail() Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 19/24] i2c: rk3x: fix potential spinlock recursion on poll Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 20/24] drm/amd/display: get dprefclk ss info from integration info table Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 21/24] pinctrl: cy8c95x0: Fix typo Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 22/24] pinctrl: cy8c95x0: Fix regression Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 23/24] pinctrl: cy8c95x0: Fix get_pincfg Sasha Levin
2023-12-26 0:22 ` [PATCH AUTOSEL 6.1 24/24] ida: Fix crash in ida_free when the bitmap is empty Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZZ0x+wlRGxwPOArK@duo.ucw.cz \
--to=pavel@ucw.cz \
--cc=hdegoede@redhat.com \
--cc=hmh@hmh.eng.br \
--cc=ibm-acpi-devel@lists.sourceforge.net \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mpearson-lenovo@squebb.ca \
--cc=platform-driver-x86@vger.kernel.org \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
--cc=vishnuocv@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®