From: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
To: sre@kernel.org, hansg@kernel.org, ilpo.jarvinen@linux.intel.com,
bryan.odonoghue@linaro.org
Cc: platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org, stephan.gerhold@linaro.org
Subject: [RFC PATCH] platform/arm64: lenovo-thinkpad-t14s: Adjust thermal trip with platform profile
Date: Thu, 1 Oct 2026 20:19:17 +0200 [thread overview]
Message-ID: <20261001181917.9367-1-daniel.lezcano@oss.qualcomm.com> (raw)
Tie the keyboard thermal mitigation temperature to the platform profile
selected through the ThinkPad embedded controller.
The EC reports Fn+L, Fn+M and Fn+H events corresponding to low-power,
balanced and performance operating modes. Use these events to update the
passive trip point of the "keyboard-thermal" zone to 49.85°C, 57.85°C
and 59.85°C respectively.
These thresholds match the thermal mitigation temperatures used by the
platform for the corresponding operating profiles.
Look up the keyboard thermal zone at probe time and locate the passive
trip named "keyboard-ec-alert". The trip name is used deliberately so
the EC driver can identify the device-tree trip associated with the
platform thermal profile without depending on its position in the trip
table.
Initialize the thermal mitigation threshold to the balanced profile,
matching the default platform behaviour, and update the thermal zone
whenever a profile change event is reported by the EC so that the new
mitigation temperature takes effect immediately.
Using the platform_profile API would provide a more appropriate interface
for exposing and managing these operating modes. However, while the API
itself is generic, the platform profile core implementation currently
lives under the ACPI framework. Making it available to device-tree based
platforms requires separating the generic infrastructure from ACPI,
which is a larger and independent piece of work.
For now, handle the EC profile events directly and use them to adjust the
thermal mitigation threshold while keeping the thermal policy described
in the device tree.
This change depends on the keyboard thermal zone and the
"keyboard-ec-alert" trip introduced by the following series.
Link: https://lore.kernel.org/all/20261001181055.9149-1-daniel.lezcano@oss.qualcomm.com/
Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
drivers/platform/arm64/lenovo-thinkpad-t14s.c | 109 ++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/drivers/platform/arm64/lenovo-thinkpad-t14s.c b/drivers/platform/arm64/lenovo-thinkpad-t14s.c
index e7acb66b77f2..ee39b0382219 100644
--- a/drivers/platform/arm64/lenovo-thinkpad-t14s.c
+++ b/drivers/platform/arm64/lenovo-thinkpad-t14s.c
@@ -18,8 +18,10 @@
#include <linux/leds.h>
#include <linux/lockdep.h>
#include <linux/module.h>
+#include <linux/platform_profile.h>
#include <linux/regmap.h>
#include <linux/slab.h>
+#include <linux/thermal.h>
#include <linux/pm.h>
#define T14S_EC_CMD_ECRD 0x02
@@ -93,9 +95,16 @@ struct t14s_ec_led_classdev {
struct t14s_ec *ec;
};
+struct t14s_ec_thermal_profile {
+ struct thermal_zone_device *tzd;
+ struct thermal_trip *keyboard_alert;
+ enum platform_profile_option current_profile;
+};
+
struct t14s_ec {
struct regmap *regmap;
struct device *dev;
+ struct t14s_ec_thermal_profile profile;
struct t14s_ec_led_classdev led_pwr_btn;
struct t14s_ec_led_classdev led_chrg_orange;
struct t14s_ec_led_classdev led_chrg_white;
@@ -472,6 +481,99 @@ static int t14s_input_probe(struct t14s_ec *ec)
return input_register_device(ec->inputdev);
}
+static int t14s_platform_profile_temp(enum platform_profile_option profile)
+{
+ /*
+ * These thresholds match the temperatures used by the
+ * platform firmware for the corresponding operating profiles.
+ */
+ switch (profile) {
+ case PLATFORM_PROFILE_LOW_POWER:
+ return 49850;
+ case PLATFORM_PROFILE_BALANCED:
+ return 57850;
+ case PLATFORM_PROFILE_PERFORMANCE:
+ return 59850;
+ default:
+ return THERMAL_TEMP_INVALID;
+ }
+}
+
+static int t14s_platform_profile_set(struct t14s_ec_thermal_profile *tp,
+ enum platform_profile_option profile)
+{
+ int temp;
+
+ if (!tp->tzd)
+ return -ENODEV;
+
+ if (tp->current_profile == profile)
+ return 0;
+
+ temp = t14s_platform_profile_temp(profile);
+ if (temp == THERMAL_TEMP_INVALID)
+ return -EINVAL;
+
+ thermal_zone_set_trip_temp(tp->tzd, tp->keyboard_alert, temp);
+ thermal_zone_device_update(tp->tzd, THERMAL_TRIP_CHANGED);
+
+ tp->current_profile = profile;
+
+ return 0;
+}
+
+static int t14s_profile_find_keyboard_alert(struct thermal_trip *tt, void *data)
+{
+ struct device_node *np;
+ struct t14s_ec_thermal_profile *tp = data;
+
+ if (tt->type != THERMAL_TRIP_PASSIVE)
+ return 0;
+
+ np = tt->priv;
+
+ if (!np)
+ return -EINVAL;
+
+ if (!of_node_name_eq(np, "keyboard-ec-alert"))
+ return 0;
+
+ tp->keyboard_alert = tt;
+
+ return 1;
+}
+
+static int t14s_profile_probe(struct t14s_ec_thermal_profile *tp)
+{
+ struct thermal_zone_device *tzd;
+ int ret;
+
+ tzd = thermal_zone_get_zone_by_name("keyboard-thermal");
+ if (IS_ERR(tzd)) {
+ ret = PTR_ERR(tzd);
+
+ if (ret == -ENODEV)
+ return -EPROBE_DEFER;
+
+ return ret;
+ }
+
+ tp->tzd = tzd;
+
+ ret = thermal_zone_for_each_trip(tzd, t14s_profile_find_keyboard_alert, tp);
+ if (ret < 0)
+ return ret;
+
+ if (!tp->keyboard_alert)
+ return -ENODEV;
+
+ ret = t14s_platform_profile_set(tp, PLATFORM_PROFILE_BALANCED);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static irqreturn_t t14s_ec_irq_handler(int irq, void *data)
{
struct t14s_ec *ec = data;
@@ -534,12 +636,15 @@ static irqreturn_t t14s_ec_irq_handler(int irq, void *data)
break;
case T14S_EC_EVT_KEY_FN_L:
dev_dbg(ec->dev, "FN + L - low performance mode\n");
+ t14s_platform_profile_set(&ec->profile, PLATFORM_PROFILE_LOW_POWER);
break;
case T14S_EC_EVT_KEY_FN_M:
dev_dbg(ec->dev, "FN + M - medium performance mode\n");
+ t14s_platform_profile_set(&ec->profile, PLATFORM_PROFILE_BALANCED);
break;
case T14S_EC_EVT_KEY_FN_H:
dev_dbg(ec->dev, "FN + H - high performance mode\n");
+ t14s_platform_profile_set(&ec->profile, PLATFORM_PROFILE_PERFORMANCE);
break;
case T14S_EC_EVT_KEY_FN_T:
dev_dbg(ec->dev, "FN + T - toggle intelligent cooling mode\n");
@@ -590,6 +695,10 @@ static int t14s_ec_probe(struct i2c_client *client)
if (ret < 0)
return ret;
+ ret = t14s_profile_probe(&ec->profile);
+ if (ret < 0)
+ return ret;
+
ret = devm_request_threaded_irq(dev, client->irq, NULL,
t14s_ec_irq_handler,
IRQF_ONESHOT, dev_name(dev), ec);
--
2.53.0
reply other threads:[~2026-10-01 18:19 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20261001181917.9367-1-daniel.lezcano@oss.qualcomm.com \
--to=daniel.lezcano@oss.qualcomm.com \
--cc=bryan.odonoghue@linaro.org \
--cc=hansg@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=sre@kernel.org \
--cc=stephan.gerhold@linaro.org \
/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®