Skip to content

Commit b4c4eb5

Browse files
committed
Merge branch '7.0/lenovo-wmi' into 7.0/base
Signed-off-by: Eric Naim <dnaim@cachyos.org>
2 parents 9bea7e0 + 25eaeed commit b4c4eb5

11 files changed

Lines changed: 934 additions & 198 deletions

File tree

Documentation/wmi/devices/lenovo-wmi-other.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,28 @@ Each attribute has the following properties:
6868
- type
6969

7070
The following firmware-attributes are implemented:
71+
- cpu_temp: CPU Thermal Load Limit
72+
- dgpu_boost_clk: Dedicated GPU Boost Clock
73+
- dgpu_enable: Dedicated GPU Enabled Status
74+
- gpu_didvid: GPU Device Identifier and Vendor Identifier
75+
- gpu_mode: GPU Mode by Power Limit
76+
- gpu_nv_ac_offset: Nvidia GPU AC Total Processing Power Baseline Offset
77+
- gpu_nv_bpl: Nvidia GPU Base Power Limit
78+
- gpu_nv_cpu_boost: Nvidia GPU to CPU Dynamic Boost Limit
79+
- gpu_nv_ctgp: Nvidia GPU Configurable Total Graphics Power
80+
- gpu_nv_ppab: Nvidia GPU Power Performance Aware Boost Limit
81+
- gpu_temp: GPU Thermal Load Limit
82+
- ppt_cpu_cl: CPU Cross Loading Power Limit
83+
- ppt_pl1_apu_spl: Platform Profile Tracking APU Sustained Power Limit
7184
- ppt_pl1_spl: Platform Profile Tracking Sustained Power Limit
85+
- ppt_pl1_spl_cl: Platform Profile Tracking Cross Loading Sustained Power Limit
86+
- ppt_pl1_tau: Exceed Duration for Platform Profile Tracking Sustained Power Limit
7287
- ppt_pl2_sppt: Platform Profile Tracking Slow Package Power Tracking
88+
- ppt_pl2_sppt_cl: Platform Profile Tracking Cross Loading Slow Package Tracking
7389
- ppt_pl3_fppt: Platform Profile Tracking Fast Package Power Tracking
90+
- ppt_pl3_fppt_cl: Platform Profile Tracking Cross Loading Fast Package Power Tracking
91+
- ppt_pl4_ipl: Platform Profile Tracking Instantaneous Power Limit
92+
- ppt_pl4_ipl_cl: Platform Profile Tracking Cross Loading Instantaneous Power Limit
7493

7594
LENOVO_FAN_TEST_DATA
7695
-------------------------

drivers/platform/x86/lenovo/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ config YT2_1380
236236
config LENOVO_WMI_CAPDATA
237237
tristate
238238
depends on ACPI_WMI
239+
depends on LENOVO_WMI_HELPERS
239240

240241
config LENOVO_WMI_EVENTS
241242
tristate
@@ -252,7 +253,6 @@ config LENOVO_WMI_GAMEZONE
252253
select ACPI_PLATFORM_PROFILE
253254
select LENOVO_WMI_EVENTS
254255
select LENOVO_WMI_HELPERS
255-
select LENOVO_WMI_TUNING
256256
help
257257
Say Y here if you have a WMI aware Lenovo Legion device and would like to use the
258258
platform-profile firmware interface to manage power usage.
@@ -263,6 +263,7 @@ config LENOVO_WMI_GAMEZONE
263263
config LENOVO_WMI_TUNING
264264
tristate "Lenovo Other Mode WMI Driver"
265265
depends on ACPI_WMI
266+
depends on ACPI_BATTERY
266267
select HWMON
267268
select FW_ATTR_CLASS
268269
select LENOVO_WMI_CAPDATA

drivers/platform/x86/lenovo/wmi-capdata.c

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2828

2929
#include <linux/acpi.h>
30-
#include <linux/bitfield.h>
3130
#include <linux/bug.h>
3231
#include <linux/cleanup.h>
3332
#include <linux/component.h>
3433
#include <linux/container_of.h>
34+
#include <linux/debugfs.h>
3535
#include <linux/device.h>
3636
#include <linux/dev_printk.h>
3737
#include <linux/err.h>
@@ -43,11 +43,13 @@
4343
#include <linux/mutex_types.h>
4444
#include <linux/notifier.h>
4545
#include <linux/overflow.h>
46+
#include <linux/seq_file.h>
4647
#include <linux/stddef.h>
4748
#include <linux/types.h>
4849
#include <linux/wmi.h>
4950

5051
#include "wmi-capdata.h"
52+
#include "wmi-helpers.h"
5153

5254
#define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
5355
#define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
@@ -58,9 +60,9 @@
5860

5961
#define LWMI_FEATURE_ID_FAN_TEST 0x05
6062

61-
#define LWMI_ATTR_ID_FAN_TEST \
62-
(FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, LWMI_DEVICE_ID_FAN) | \
63-
FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, LWMI_FEATURE_ID_FAN_TEST))
63+
#define LWMI_ATTR_ID_FAN_TEST \
64+
lwmi_attr_id(LWMI_DEVICE_ID_FAN, LWMI_FEATURE_ID_FAN_TEST, \
65+
LWMI_GZ_THERMAL_MODE_NONE, LWMI_TYPE_ID_NONE)
6466

6567
enum lwmi_cd_type {
6668
LENOVO_CAPABILITY_DATA_00,
@@ -88,6 +90,7 @@ struct lwmi_cd_priv {
8890
struct notifier_block acpi_nb; /* ACPI events */
8991
struct wmi_device *wdev;
9092
struct cd_list *list;
93+
struct dentry *debugfs_dir;
9194

9295
/*
9396
* A capdata device may be a component master of another capdata device.
@@ -118,6 +121,8 @@ struct cd_list {
118121

119122
static struct wmi_driver lwmi_cd_driver;
120123

124+
/* ======== Device components ======== */
125+
121126
/**
122127
* lwmi_cd_match() - Match rule for the master driver.
123128
* @dev: Pointer to the capability data parent device.
@@ -471,6 +476,116 @@ EXPORT_SYMBOL_NS_GPL(lwmi_cd01_get_data, "LENOVO_WMI_CAPDATA");
471476
DEF_LWMI_CDXX_GET_DATA(cd_fan, LENOVO_FAN_TEST_DATA, struct capdata_fan);
472477
EXPORT_SYMBOL_NS_GPL(lwmi_cd_fan_get_data, "LENOVO_WMI_CAPDATA");
473478

479+
/* ======== debugfs ======== */
480+
481+
/**
482+
* lwmi_cd00_show() - Dump capdata00
483+
* @s: Pointer to seq_file where the capdata00 is dumped.
484+
* @cd00: Pointer to a capdata00 struct to be dumped.
485+
*/
486+
static void lwmi_cd00_show(struct seq_file *s, struct capdata00 *cd00)
487+
{
488+
u8 dev = FIELD_GET(LWMI_ATTR_DEV_ID_MASK, cd00->id);
489+
u8 feat = FIELD_GET(LWMI_ATTR_FEAT_ID_MASK, cd00->id);
490+
u8 mode = FIELD_GET(LWMI_ATTR_MODE_ID_MASK, cd00->id);
491+
u8 type = FIELD_GET(LWMI_ATTR_TYPE_ID_MASK, cd00->id);
492+
bool extra = cd00->supported & ~(LWMI_SUPP_GET | LWMI_SUPP_SET | LWMI_SUPP_VALID);
493+
bool get = cd00->supported & LWMI_SUPP_GET;
494+
bool set = cd00->supported & LWMI_SUPP_SET;
495+
bool valid = cd00->supported & LWMI_SUPP_VALID;
496+
497+
seq_printf(s, " id: 0x%08x [dev: %2u, feat: %2u, mode: %2u, type: %2u]\n",
498+
cd00->id, dev, feat, mode, type);
499+
500+
seq_printf(s, " supported: 0x%08x [%c%c%c%c]\n", cd00->supported,
501+
extra ? '+' : ' ',
502+
get ? 'R' : ' ',
503+
set ? 'W' : ' ',
504+
valid ? 'V' : ' ');
505+
506+
seq_printf(s, " default_value: %u\n", cd00->default_value);
507+
}
508+
509+
/**
510+
* lwmi_cd01_show() - Dump capdata01
511+
* @s: Pointer to seq_file where the capdata01 is dumped.
512+
* @cd01: Pointer to a capdata01 struct to be dumped.
513+
*/
514+
static void lwmi_cd01_show(struct seq_file *s, struct capdata01 *cd01)
515+
{
516+
/* capdata01 is an extension to capdata00. */
517+
lwmi_cd00_show(s, (struct capdata00 *)cd01);
518+
519+
seq_printf(s, " step: %u\n", cd01->step);
520+
seq_printf(s, " min_value: %u\n", cd01->min_value);
521+
seq_printf(s, " max_value: %u\n", cd01->max_value);
522+
}
523+
524+
/**
525+
* lwmi_cd_fan_show() - Dump capdata_fan
526+
* @s: Pointer to seq_file where the capdata_fan is dumped.
527+
* @cd_fan: Pointer to a capdata_fan struct to be dumped.
528+
*/
529+
static void lwmi_cd_fan_show(struct seq_file *s, struct capdata_fan *cd_fan)
530+
{
531+
seq_printf(s, " id: %u\n", cd_fan->id);
532+
seq_printf(s, " min_rpm: %u\n", cd_fan->min_rpm);
533+
seq_printf(s, " max_rpm: %u\n", cd_fan->max_rpm);
534+
}
535+
536+
/**
537+
* lwmi_cd_debugfs_show() - Dump capability data to debugfs
538+
* @s: Pointer to seq_file where the capability data is dumped.
539+
* @data: unused.
540+
*
541+
* Return: 0
542+
*/
543+
static int lwmi_cd_debugfs_show(struct seq_file *s, void *data)
544+
{
545+
struct lwmi_cd_priv *priv = s->private;
546+
u8 idx;
547+
548+
guard(mutex)(&priv->list->list_mutex);
549+
550+
/* lwmi_cd_alloc() ensured priv->list->type must be a valid type. */
551+
for (idx = 0; idx < priv->list->count; idx++) {
552+
seq_printf(s, "%s[%u]:\n", lwmi_cd_table[priv->list->type].name, idx);
553+
554+
if (priv->list->type == LENOVO_CAPABILITY_DATA_00)
555+
lwmi_cd00_show(s, &priv->list->cd00[idx]);
556+
else if (priv->list->type == LENOVO_CAPABILITY_DATA_01)
557+
lwmi_cd01_show(s, &priv->list->cd01[idx]);
558+
else if (priv->list->type == LENOVO_FAN_TEST_DATA)
559+
lwmi_cd_fan_show(s, &priv->list->cd_fan[idx]);
560+
}
561+
562+
return 0;
563+
}
564+
DEFINE_SHOW_ATTRIBUTE(lwmi_cd_debugfs);
565+
566+
/**
567+
* lwmi_cd_debugfs_add() - Create debugfs directory and files for a device
568+
* @priv: lenovo-wmi-capdata driver data.
569+
*/
570+
static void lwmi_cd_debugfs_add(struct lwmi_cd_priv *priv)
571+
{
572+
priv->debugfs_dir = lwmi_debugfs_create_dir(priv->wdev);
573+
574+
debugfs_create_file("capdata", 0444, priv->debugfs_dir, priv, &lwmi_cd_debugfs_fops);
575+
}
576+
577+
/**
578+
* lwmi_cd_debugfs_remove() - Remove debugfs directory for a device
579+
* @priv: lenovo-wmi-capdata driver data.
580+
*/
581+
static void lwmi_cd_debugfs_remove(struct lwmi_cd_priv *priv)
582+
{
583+
debugfs_remove_recursive(priv->debugfs_dir);
584+
priv->debugfs_dir = NULL;
585+
}
586+
587+
/* ======== WMI interface ======== */
588+
474589
/**
475590
* lwmi_cd_cache() - Cache all WMI data block information
476591
* @priv: lenovo-wmi-capdata driver data.
@@ -773,6 +888,8 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
773888
dev_err(&wdev->dev, "failed to register %s: %d\n",
774889
info->name, ret);
775890
} else {
891+
lwmi_cd_debugfs_add(priv);
892+
776893
dev_dbg(&wdev->dev, "registered %s with %u items\n",
777894
info->name, priv->list->count);
778895
}
@@ -783,6 +900,8 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
783900
{
784901
struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
785902

903+
lwmi_cd_debugfs_remove(priv);
904+
786905
switch (priv->list->type) {
787906
case LENOVO_CAPABILITY_DATA_00:
788907
lwmi_cd_sub_master_del(priv);
@@ -822,6 +941,7 @@ static struct wmi_driver lwmi_cd_driver = {
822941

823942
module_wmi_driver(lwmi_cd_driver);
824943

944+
MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
825945
MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
826946
MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
827947
MODULE_AUTHOR("Rong Zhang <i@rong.moe>");

drivers/platform/x86/lenovo/wmi-capdata.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define _LENOVO_WMI_CAPDATA_H_
77

88
#include <linux/bits.h>
9+
#include <linux/bitfield.h>
910
#include <linux/types.h>
1011

1112
#define LWMI_SUPP_VALID BIT(0)
@@ -17,7 +18,14 @@
1718
#define LWMI_ATTR_MODE_ID_MASK GENMASK(15, 8)
1819
#define LWMI_ATTR_TYPE_ID_MASK GENMASK(7, 0)
1920

20-
#define LWMI_DEVICE_ID_FAN 0x04
21+
enum lwmi_device_id {
22+
LWMI_DEVICE_ID_CPU = 0x01,
23+
LWMI_DEVICE_ID_GPU = 0x02,
24+
LWMI_DEVICE_ID_PSU = 0x03,
25+
LWMI_DEVICE_ID_FAN = 0x04,
26+
};
27+
28+
#define LWMI_TYPE_ID_NONE 0x00
2129

2230
struct component_match;
2331
struct device;
@@ -30,9 +38,7 @@ struct capdata00 {
3038
};
3139

3240
struct capdata01 {
33-
u32 id;
34-
u32 supported;
35-
u32 default_value;
41+
struct capdata00;
3642
u32 step;
3743
u32 min_value;
3844
u32 max_value;
@@ -57,6 +63,23 @@ struct lwmi_cd_binder {
5763
cd_list_cb_t cd_fan_list_cb;
5864
};
5965

66+
/**
67+
* lwmi_attr_id() - Formats a capability data attribute ID
68+
* @dev_id: The u8 corresponding to the device ID.
69+
* @feat_id: The u8 corresponding to the feature ID on the device.
70+
* @mode_id: The u8 corresponding to the wmi-gamezone mode for set/get.
71+
* @type_id: The u8 corresponding to the sub-device.
72+
*
73+
* Return: u32.
74+
*/
75+
static inline u32 lwmi_attr_id(u8 dev_id, u8 feat_id, u8 mode_id, u8 type_id)
76+
{
77+
return (FIELD_PREP(LWMI_ATTR_DEV_ID_MASK, dev_id) |
78+
FIELD_PREP(LWMI_ATTR_FEAT_ID_MASK, feat_id) |
79+
FIELD_PREP(LWMI_ATTR_MODE_ID_MASK, mode_id) |
80+
FIELD_PREP(LWMI_ATTR_TYPE_ID_MASK, type_id));
81+
}
82+
6083
void lwmi_cd_match_add_all(struct device *master, struct component_match **matchptr);
6184
int lwmi_cd00_get_data(struct cd_list *list, u32 attribute_id, struct capdata00 *output);
6285
int lwmi_cd01_get_data(struct cd_list *list, u32 attribute_id, struct capdata01 *output);

drivers/platform/x86/lenovo/wmi-events.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <linux/wmi.h>
1818

1919
#include "wmi-events.h"
20-
#include "wmi-gamezone.h"
20+
#include "wmi-helpers.h"
2121

2222
#define THERMAL_MODE_EVENT_GUID "D320289E-8FEA-41E0-86F9-911D83151B5F"
2323

drivers/platform/x86/lenovo/wmi-gamezone.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121
#include <linux/wmi.h>
2222

2323
#include "wmi-events.h"
24-
#include "wmi-gamezone.h"
2524
#include "wmi-helpers.h"
26-
#include "wmi-other.h"
2725

2826
#define LENOVO_GAMEZONE_GUID "887B54E3-DDDC-4B2C-8B88-68A26A8835D0"
2927

@@ -201,7 +199,7 @@ static int lwmi_gz_profile_set(struct device *dev,
201199
enum platform_profile_option profile)
202200
{
203201
struct lwmi_gz_priv *priv = dev_get_drvdata(dev);
204-
struct wmi_method_args_32 args;
202+
struct wmi_method_args_32 args = {};
205203
enum thermal_mode mode;
206204
int ret;
207205

@@ -383,7 +381,7 @@ static int lwmi_gz_probe(struct wmi_device *wdev, const void *context)
383381
return ret;
384382

385383
priv->mode_nb.notifier_call = lwmi_gz_mode_call;
386-
return devm_lwmi_om_register_notifier(&wdev->dev, &priv->mode_nb);
384+
return devm_lwmi_tm_register_notifier(&wdev->dev, &priv->mode_nb);
387385
}
388386

389387
static const struct wmi_device_id lwmi_gz_id_table[] = {
@@ -405,7 +403,6 @@ module_wmi_driver(lwmi_gz_driver);
405403

406404
MODULE_IMPORT_NS("LENOVO_WMI_EVENTS");
407405
MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
408-
MODULE_IMPORT_NS("LENOVO_WMI_OTHER");
409406
MODULE_DEVICE_TABLE(wmi, lwmi_gz_id_table);
410407
MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
411408
MODULE_DESCRIPTION("Lenovo GameZone WMI Driver");

drivers/platform/x86/lenovo/wmi-gamezone.h

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)