linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/20] alienware-wmi driver rework
@ 2024-12-21  5:58 Kurt Borja
  2024-12-21  5:58 ` [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit Kurt Borja
                   ` (20 more replies)
  0 siblings, 21 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:58 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Hi :)

Hopefully these series are quite complete now. Your feedback is much
appreciated!

Previous discussions:

[1] https://lore.kernel.org/platform-driver-x86/6m66cuivkzhcsvpjv4nunjyddqhr42bmjdhptu4bqm6rm7fvxf@qjwove4hg6gb/
[2] https://lore.kernel.org/platform-driver-x86/20241205002733.2183537-3-kuurtb@gmail.com/

Comments
========

Patches 14 and 20 are proposals. Feel free to NACK them.

~ Kurt

---
Changes since RFC:
 - Incorporated comments from Ilpo which include style and organization
   issues
 - Instead of splitting functionallity blocks, split WMI drivers (Due to
   Armin's comments)
 - Replaced most of the patches near the end because of the above change
 - Some patches were squashed into eachother where it made sense
 - Rebased on top of recent platform_profile changes!

Kurt Borja (20):
  alienware-wmi: Remove unnecessary check at module exit
  alienware-wmi: Move Lighting Control State
  alienware-wmi: Modify parse_rgb() signature
  alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation
  alienware-wmi: Improve rgb-zones group creation
  alienware_wmi: Clean variable declaration in thermal methods
  alienware-wmi: Add a state container for LED control feature
  alienware-wmi: Add WMI Drivers
  alienware-wmi: Add a state container for thermal control methods
  alienware-wmi: Refactor LED control methods
  alienware-wmi: Refactor hdmi, amplifier, deepslp methods
  alienware-wmi: Refactor thermal control methods
  alienware-wmi: Split DMI table
  MAINTAINERS: Update ALIENWARE WMI DRIVER entry
  platform/x86: Rename alienware-wmi.c
  platform/x86: Add alienware-wmi.h
  platform-x86: Split the alienware-wmi driver
  platform/x86: dell: Modify Makefile alignment
  platform/x86: Update alienware-wmi config entries
  alienware-wmi: Update header and module information

 MAINTAINERS                                   |    4 +-
 drivers/platform/x86/dell/Kconfig             |   30 +-
 drivers/platform/x86/dell/Makefile            |   45 +-
 .../platform/x86/dell/alienware-wmi-base.c    |  721 ++++++++++
 .../platform/x86/dell/alienware-wmi-legacy.c  |   89 ++
 .../platform/x86/dell/alienware-wmi-wmax.c    |  526 +++++++
 drivers/platform/x86/dell/alienware-wmi.c     | 1269 -----------------
 drivers/platform/x86/dell/alienware-wmi.h     |  103 ++
 8 files changed, 1491 insertions(+), 1296 deletions(-)
 create mode 100644 drivers/platform/x86/dell/alienware-wmi-base.c
 create mode 100644 drivers/platform/x86/dell/alienware-wmi-legacy.c
 create mode 100644 drivers/platform/x86/dell/alienware-wmi-wmax.c
 delete mode 100644 drivers/platform/x86/dell/alienware-wmi.c
 create mode 100644 drivers/platform/x86/dell/alienware-wmi.h

-- 
2.47.1


^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
@ 2024-12-21  5:58 ` Kurt Borja
  2024-12-27  0:32   ` Armin Wolf
  2024-12-21  5:58 ` [PATCH 02/20] alienware-wmi: Move Lighting Control State Kurt Borja
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:58 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Module initialization fails if platform device fails to register so it's
always not NULL at exit.

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index e95d22c7b60c..ed66720260ab 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -1257,13 +1257,11 @@ module_init(alienware_wmi_init);
 
 static void __exit alienware_wmi_exit(void)
 {
-	if (platform_device) {
-		alienware_zone_exit(platform_device);
-		remove_hdmi(platform_device);
-		remove_thermal_profile();
-		platform_device_unregister(platform_device);
-		platform_driver_unregister(&platform_driver);
-	}
+	alienware_zone_exit(platform_device);
+	remove_hdmi(platform_device);
+	remove_thermal_profile();
+	platform_device_unregister(platform_device);
+	platform_driver_unregister(&platform_driver);
 }
 
 module_exit(alienware_wmi_exit);
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 02/20] alienware-wmi: Move Lighting Control State
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
  2024-12-21  5:58 ` [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit Kurt Borja
@ 2024-12-21  5:58 ` Kurt Borja
  2024-12-27  0:35   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 03/20] alienware-wmi: Modify parse_rgb() signature Kurt Borja
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:58 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Place Lighting Control State logic next to other attributes of the same
sysfs group.

While at it, rename:

store_control_state()	-> lighting_control_state_store()
show_control_state()	-> lighting_control_state_show()

Replace DEVICE_ATTR_RW() with DEVICE_ATTR() and do a general style
cleanup.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 74 ++++++++++++-----------
 1 file changed, 39 insertions(+), 35 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index ed66720260ab..c5ad0f95c442 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -545,6 +545,45 @@ static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
 	return ret ? ret : count;
 }
 
+/*
+ * Lighting control state device attribute (Global)
+ */
+static ssize_t lighting_control_state_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	if (lighting_control_state == LEGACY_BOOTING)
+		return sysfs_emit(buf, "[booting] running suspend\n");
+	else if (lighting_control_state == LEGACY_SUSPEND)
+		return sysfs_emit(buf, "booting running [suspend]\n");
+
+	return sysfs_emit(buf, "booting [running] suspend\n");
+}
+
+static ssize_t lighting_control_state_store(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	u8 val;
+
+	if (strcmp(buf, "booting\n") == 0)
+		val = LEGACY_BOOTING;
+	else if (strcmp(buf, "suspend\n") == 0)
+		val = LEGACY_SUSPEND;
+	else if (interface == LEGACY)
+		val = LEGACY_RUNNING;
+	else
+		val = WMAX_RUNNING;
+
+	lighting_control_state = val;
+	pr_debug("alienware-wmi: updated control state to %d\n",
+		 lighting_control_state);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(lighting_control_state);
+
 /*
  * LED Brightness (Global)
  */
@@ -589,41 +628,6 @@ static struct led_classdev global_led = {
 	.name = "alienware::global_brightness",
 };
 
-/*
- * Lighting control state device attribute (Global)
- */
-static ssize_t show_control_state(struct device *dev,
-				  struct device_attribute *attr, char *buf)
-{
-	if (lighting_control_state == LEGACY_BOOTING)
-		return sysfs_emit(buf, "[booting] running suspend\n");
-	else if (lighting_control_state == LEGACY_SUSPEND)
-		return sysfs_emit(buf, "booting running [suspend]\n");
-	return sysfs_emit(buf, "booting [running] suspend\n");
-}
-
-static ssize_t store_control_state(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf, size_t count)
-{
-	long unsigned int val;
-	if (strcmp(buf, "booting\n") == 0)
-		val = LEGACY_BOOTING;
-	else if (strcmp(buf, "suspend\n") == 0)
-		val = LEGACY_SUSPEND;
-	else if (interface == LEGACY)
-		val = LEGACY_RUNNING;
-	else
-		val = WMAX_RUNNING;
-	lighting_control_state = val;
-	pr_debug("alienware-wmi: updated control state to %d\n",
-		 lighting_control_state);
-	return count;
-}
-
-static DEVICE_ATTR(lighting_control_state, 0644, show_control_state,
-		   store_control_state);
-
 static int alienware_zone_init(struct platform_device *dev)
 {
 	u8 zone;
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 03/20] alienware-wmi: Modify parse_rgb() signature
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
  2024-12-21  5:58 ` [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit Kurt Borja
  2024-12-21  5:58 ` [PATCH 02/20] alienware-wmi: Move Lighting Control State Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  0:36   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 04/20] alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation Kurt Borja
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

parse_rgb() now takes struct color_platform instead of struct
platform_zone to support upcoming refactor.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index c5ad0f95c442..273ce9b10765 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -434,7 +434,7 @@ static u8 global_brightness;
 /*
  * Helpers used for zone control
  */
-static int parse_rgb(const char *buf, struct platform_zone *zone)
+static int parse_rgb(const char *buf, struct color_platform *colors)
 {
 	long unsigned int rgb;
 	int ret;
@@ -454,7 +454,7 @@ static int parse_rgb(const char *buf, struct platform_zone *zone)
 	repackager.package = rgb & 0x0f0f0f0f;
 	pr_debug("alienware-wmi: r: %d g:%d b: %d\n",
 		 repackager.cp.red, repackager.cp.green, repackager.cp.blue);
-	zone->colors = repackager.cp;
+	*colors = repackager.cp;
 	return 0;
 }
 
@@ -538,7 +538,7 @@ static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
 		pr_err("alienware-wmi: invalid target zone\n");
 		return 1;
 	}
-	ret = parse_rgb(buf, target_zone);
+	ret = parse_rgb(buf, &target_zone->colors);
 	if (ret)
 		return ret;
 	ret = alienware_update_led(target_zone);
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 04/20] alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (2 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 03/20] alienware-wmi: Modify parse_rgb() signature Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  0:44   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 05/20] alienware-wmi: Improve rgb-zones " Kurt Borja
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Devices with hdmi_mux, amplifier or deepslp quirks create a sysfs group
for each available feature. To accomplish this, helper create/remove
functions were called on module init, but they had the following
problems:

 - Create helpers called remove helpers on failure, which in turn tried
   to remove the sysfs group that failed to be created
 - If group creation failed mid way, previous successfully created groups
   were not cleaned up
 - Module exit only removed hdmi_mux group

To improve this, drop all helpers and let the platform driver manage these
sysfs groups, while controlling visibility with their respective quirks.

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 114 ++++++++--------------
 1 file changed, 38 insertions(+), 76 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index 273ce9b10765..e010c94555e8 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -417,12 +417,6 @@ static struct platform_zone *zone_data;
 static struct platform_profile_handler pp_handler;
 static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
 
-static struct platform_driver platform_driver = {
-	.driver = {
-		.name = "alienware-wmi",
-	}
-};
-
 static struct attribute_group zone_attribute_group = {
 	.name = "rgb_zones",
 };
@@ -804,6 +798,12 @@ static DEVICE_ATTR(cable, S_IRUGO, show_hdmi_cable, NULL);
 static DEVICE_ATTR(source, S_IRUGO | S_IWUSR, show_hdmi_source,
 		   toggle_hdmi_source);
 
+static bool hdmi_group_visible(struct kobject *kobj)
+{
+	return quirks->hdmi_mux;
+}
+DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(hdmi);
+
 static struct attribute *hdmi_attrs[] = {
 	&dev_attr_cable.attr,
 	&dev_attr_source.attr,
@@ -812,25 +812,10 @@ static struct attribute *hdmi_attrs[] = {
 
 static const struct attribute_group hdmi_attribute_group = {
 	.name = "hdmi",
+	.is_visible = SYSFS_GROUP_VISIBLE(hdmi),
 	.attrs = hdmi_attrs,
 };
 
-static void remove_hdmi(struct platform_device *dev)
-{
-	if (quirks->hdmi_mux > 0)
-		sysfs_remove_group(&dev->dev.kobj, &hdmi_attribute_group);
-}
-
-static int create_hdmi(struct platform_device *dev)
-{
-	int ret;
-
-	ret = sysfs_create_group(&dev->dev.kobj, &hdmi_attribute_group);
-	if (ret)
-		remove_hdmi(dev);
-	return ret;
-}
-
 /*
  * Alienware GFX amplifier support
  * - Currently supports reading cable status
@@ -859,6 +844,12 @@ static ssize_t show_amplifier_status(struct device *dev,
 
 static DEVICE_ATTR(status, S_IRUGO, show_amplifier_status, NULL);
 
+static bool amplifier_group_visible(struct kobject *kobj)
+{
+	return quirks->amplifier;
+}
+DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(amplifier);
+
 static struct attribute *amplifier_attrs[] = {
 	&dev_attr_status.attr,
 	NULL,
@@ -866,25 +857,10 @@ static struct attribute *amplifier_attrs[] = {
 
 static const struct attribute_group amplifier_attribute_group = {
 	.name = "amplifier",
+	.is_visible = SYSFS_GROUP_VISIBLE(amplifier),
 	.attrs = amplifier_attrs,
 };
 
-static void remove_amplifier(struct platform_device *dev)
-{
-	if (quirks->amplifier > 0)
-		sysfs_remove_group(&dev->dev.kobj, &amplifier_attribute_group);
-}
-
-static int create_amplifier(struct platform_device *dev)
-{
-	int ret;
-
-	ret = sysfs_create_group(&dev->dev.kobj, &amplifier_attribute_group);
-	if (ret)
-		remove_amplifier(dev);
-	return ret;
-}
-
 /*
  * Deep Sleep Control support
  * - Modifies BIOS setting for deep sleep control allowing extra wakeup events
@@ -937,6 +913,12 @@ static ssize_t toggle_deepsleep(struct device *dev,
 
 static DEVICE_ATTR(deepsleep, S_IRUGO | S_IWUSR, show_deepsleep_status, toggle_deepsleep);
 
+static bool deepsleep_group_visible(struct kobject *kobj)
+{
+	return quirks->deepslp;
+}
+DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(deepsleep);
+
 static struct attribute *deepsleep_attrs[] = {
 	&dev_attr_deepsleep.attr,
 	NULL,
@@ -944,25 +926,10 @@ static struct attribute *deepsleep_attrs[] = {
 
 static const struct attribute_group deepsleep_attribute_group = {
 	.name = "deepsleep",
+	.is_visible = SYSFS_GROUP_VISIBLE(deepsleep),
 	.attrs = deepsleep_attrs,
 };
 
-static void remove_deepsleep(struct platform_device *dev)
-{
-	if (quirks->deepslp > 0)
-		sysfs_remove_group(&dev->dev.kobj, &deepsleep_attribute_group);
-}
-
-static int create_deepsleep(struct platform_device *dev)
-{
-	int ret;
-
-	ret = sysfs_create_group(&dev->dev.kobj, &deepsleep_attribute_group);
-	if (ret)
-		remove_deepsleep(dev);
-	return ret;
-}
-
 /*
  * Thermal Profile control
  *  - Provides thermal profile control through the Platform Profile API
@@ -1172,6 +1139,23 @@ static void remove_thermal_profile(void)
 		platform_profile_remove(&pp_handler);
 }
 
+/*
+ * Platform Driver
+ */
+static const struct attribute_group *alienfx_groups[] = {
+	&hdmi_attribute_group,
+	&amplifier_attribute_group,
+	&deepsleep_attribute_group,
+	NULL
+};
+
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = "alienware-wmi",
+		.dev_groups = alienfx_groups,
+	},
+};
+
 static int __init alienware_wmi_init(void)
 {
 	int ret;
@@ -1211,24 +1195,6 @@ static int __init alienware_wmi_init(void)
 	if (ret)
 		goto fail_platform_device2;
 
-	if (quirks->hdmi_mux > 0) {
-		ret = create_hdmi(platform_device);
-		if (ret)
-			goto fail_prep_hdmi;
-	}
-
-	if (quirks->amplifier > 0) {
-		ret = create_amplifier(platform_device);
-		if (ret)
-			goto fail_prep_amplifier;
-	}
-
-	if (quirks->deepslp > 0) {
-		ret = create_deepsleep(platform_device);
-		if (ret)
-			goto fail_prep_deepsleep;
-	}
-
 	if (quirks->thermal) {
 		ret = create_thermal_profile(platform_device);
 		if (ret)
@@ -1245,9 +1211,6 @@ static int __init alienware_wmi_init(void)
 	alienware_zone_exit(platform_device);
 	remove_thermal_profile();
 fail_prep_thermal_profile:
-fail_prep_deepsleep:
-fail_prep_amplifier:
-fail_prep_hdmi:
 	platform_device_del(platform_device);
 fail_platform_device2:
 	platform_device_put(platform_device);
@@ -1262,7 +1225,6 @@ module_init(alienware_wmi_init);
 static void __exit alienware_wmi_exit(void)
 {
 	alienware_zone_exit(platform_device);
-	remove_hdmi(platform_device);
 	remove_thermal_profile();
 	platform_device_unregister(platform_device);
 	platform_driver_unregister(&platform_driver);
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 05/20] alienware-wmi: Improve rgb-zones group creation
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (3 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 04/20] alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  1:04   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 06/20] alienware_wmi: Clean variable declaration in thermal methods Kurt Borja
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Define zone_attrs statically with the use of helper macros and
initialize the zone_attribute_group with driver's .dev_groups.

Drop match_zone() and instead pass a `location` argument to previous
show/store methods to access the correct `zone` LED state. On top of
that rename zone_set() -> zone_store() to be more consistent with sysfs
conventions.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 179 +++++++++-------------
 1 file changed, 72 insertions(+), 107 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index e010c94555e8..a431b1fec9fb 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -376,12 +376,6 @@ struct color_platform {
 	u8 red;
 } __packed;
 
-struct platform_zone {
-	u8 location;
-	struct device_attribute *attr;
-	struct color_platform colors;
-};
-
 struct wmax_brightness_args {
 	u32 led_mask;
 	u32 percentage;
@@ -411,16 +405,10 @@ struct wmax_u32_args {
 };
 
 static struct platform_device *platform_device;
-static struct device_attribute *zone_dev_attrs;
-static struct attribute **zone_attrs;
-static struct platform_zone *zone_data;
+static struct color_platform colors[4];
 static struct platform_profile_handler pp_handler;
 static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
 
-static struct attribute_group zone_attribute_group = {
-	.name = "rgb_zones",
-};
-
 static u8 interface;
 static u8 lighting_control_state;
 static u8 global_brightness;
@@ -452,24 +440,10 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
 	return 0;
 }
 
-static struct platform_zone *match_zone(struct device_attribute *attr)
-{
-	u8 zone;
-
-	for (zone = 0; zone < quirks->num_zones; zone++) {
-		if ((struct device_attribute *)zone_data[zone].attr == attr) {
-			pr_debug("alienware-wmi: matched zone location: %d\n",
-				 zone_data[zone].location);
-			return &zone_data[zone];
-		}
-	}
-	return NULL;
-}
-
 /*
  * Individual RGB zone control
  */
-static int alienware_update_led(struct platform_zone *zone)
+static int alienware_update_led(u8 location)
 {
 	int method_id;
 	acpi_status status;
@@ -478,8 +452,8 @@ static int alienware_update_led(struct platform_zone *zone)
 	struct legacy_led_args legacy_args;
 	struct wmax_led_args wmax_basic_args;
 	if (interface == WMAX) {
-		wmax_basic_args.led_mask = 1 << zone->location;
-		wmax_basic_args.colors = zone->colors;
+		wmax_basic_args.led_mask = 1 << location;
+		wmax_basic_args.colors = colors[location];
 		wmax_basic_args.state = lighting_control_state;
 		guid = WMAX_CONTROL_GUID;
 		method_id = WMAX_METHOD_ZONE_CONTROL;
@@ -487,7 +461,7 @@ static int alienware_update_led(struct platform_zone *zone)
 		input.length = sizeof(wmax_basic_args);
 		input.pointer = &wmax_basic_args;
 	} else {
-		legacy_args.colors = zone->colors;
+		legacy_args.colors = colors[location];
 		legacy_args.brightness = global_brightness;
 		legacy_args.state = 0;
 		if (lighting_control_state == LEGACY_BOOTING ||
@@ -496,7 +470,7 @@ static int alienware_update_led(struct platform_zone *zone)
 			legacy_args.state = lighting_control_state;
 		} else
 			guid = LEGACY_CONTROL_GUID;
-		method_id = zone->location + 1;
+		method_id = location + 1;
 
 		input.length = sizeof(legacy_args);
 		input.pointer = &legacy_args;
@@ -510,35 +484,54 @@ static int alienware_update_led(struct platform_zone *zone)
 }
 
 static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
-			 char *buf)
+			 char *buf, u8 location)
 {
-	struct platform_zone *target_zone;
-	target_zone = match_zone(attr);
-	if (target_zone == NULL)
-		return sprintf(buf, "red: -1, green: -1, blue: -1\n");
 	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
-		       target_zone->colors.red,
-		       target_zone->colors.green, target_zone->colors.blue);
+		       colors[location].red, colors[location].green,
+		       colors[location].blue);
 
 }
 
-static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
-			const char *buf, size_t count)
+static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count, u8 location)
 {
-	struct platform_zone *target_zone;
 	int ret;
-	target_zone = match_zone(attr);
-	if (target_zone == NULL) {
-		pr_err("alienware-wmi: invalid target zone\n");
-		return 1;
-	}
-	ret = parse_rgb(buf, &target_zone->colors);
+
+	ret = parse_rgb(buf, &colors[location]);
 	if (ret)
 		return ret;
-	ret = alienware_update_led(target_zone);
+
+	ret = alienware_update_led(location);
+
 	return ret ? ret : count;
 }
 
+#define ALIENWARE_ZONE_SHOW_FUNC(_num)					\
+	static ssize_t zone0##_num##_show(struct device *dev,		\
+					struct device_attribute *attr,	\
+					char *buf)			\
+	{								\
+		return zone_show(dev, attr, buf, _num);			\
+	}
+
+#define ALIENWARE_ZONE_STORE_FUNC(_num)					\
+	static ssize_t zone0##_num##_store(struct device *dev,		\
+					struct device_attribute *attr,	\
+					const char *buf, size_t count)	\
+	{								\
+		return zone_store(dev, attr, buf, count, _num);		\
+	}
+
+#define ALIENWARE_ZONE_ATTR(_num)					\
+	ALIENWARE_ZONE_SHOW_FUNC(_num)					\
+	ALIENWARE_ZONE_STORE_FUNC(_num)					\
+	static DEVICE_ATTR_RW(zone0##_num)
+
+ALIENWARE_ZONE_ATTR(0);
+ALIENWARE_ZONE_ATTR(1);
+ALIENWARE_ZONE_ATTR(2);
+ALIENWARE_ZONE_ATTR(3);
+
 /*
  * Lighting control state device attribute (Global)
  */
@@ -578,6 +571,33 @@ static ssize_t lighting_control_state_store(struct device *dev,
 
 static DEVICE_ATTR_RW(lighting_control_state);
 
+static umode_t zone_attr_visible(struct kobject *kobj,
+				 struct attribute *attr, int n)
+{
+	return n < quirks->num_zones + 1 ? 0644 : 0;
+}
+
+static bool zone_group_visible(struct kobject *kobj)
+{
+	return quirks->num_zones > 0;
+}
+DEFINE_SYSFS_GROUP_VISIBLE(zone);
+
+static struct attribute *zone_attrs[] = {
+	&dev_attr_lighting_control_state.attr,
+	&dev_attr_zone00.attr,
+	&dev_attr_zone01.attr,
+	&dev_attr_zone02.attr,
+	&dev_attr_zone03.attr,
+	NULL
+};
+
+static struct attribute_group zone_attribute_group = {
+	.name = "rgb_zones",
+	.is_visible = SYSFS_GROUP_VISIBLE(zone),
+	.attrs = zone_attrs,
+};
+
 /*
  * LED Brightness (Global)
  */
@@ -606,7 +626,7 @@ static void global_led_set(struct led_classdev *led_cdev,
 	if (interface == WMAX)
 		ret = wmax_brightness(brightness);
 	else
-		ret = alienware_update_led(&zone_data[0]);
+		ret = alienware_update_led(0);
 	if (ret)
 		pr_err("LED brightness update failed\n");
 }
@@ -624,9 +644,6 @@ static struct led_classdev global_led = {
 
 static int alienware_zone_init(struct platform_device *dev)
 {
-	u8 zone;
-	char *name;
-
 	if (interface == WMAX) {
 		lighting_control_state = WMAX_RUNNING;
 	} else if (interface == LEGACY) {
@@ -635,65 +652,12 @@ static int alienware_zone_init(struct platform_device *dev)
 	global_led.max_brightness = 0x0F;
 	global_brightness = global_led.max_brightness;
 
-	/*
-	 *      - zone_dev_attrs num_zones + 1 is for individual zones and then
-	 *        null terminated
-	 *      - zone_attrs num_zones + 2 is for all attrs in zone_dev_attrs +
-	 *        the lighting control + null terminated
-	 *      - zone_data num_zones is for the distinct zones
-	 */
-	zone_dev_attrs =
-	    kcalloc(quirks->num_zones + 1, sizeof(struct device_attribute),
-		    GFP_KERNEL);
-	if (!zone_dev_attrs)
-		return -ENOMEM;
-
-	zone_attrs =
-	    kcalloc(quirks->num_zones + 2, sizeof(struct attribute *),
-		    GFP_KERNEL);
-	if (!zone_attrs)
-		return -ENOMEM;
-
-	zone_data =
-	    kcalloc(quirks->num_zones, sizeof(struct platform_zone),
-		    GFP_KERNEL);
-	if (!zone_data)
-		return -ENOMEM;
-
-	for (zone = 0; zone < quirks->num_zones; zone++) {
-		name = kasprintf(GFP_KERNEL, "zone%02hhX", zone);
-		if (name == NULL)
-			return 1;
-		sysfs_attr_init(&zone_dev_attrs[zone].attr);
-		zone_dev_attrs[zone].attr.name = name;
-		zone_dev_attrs[zone].attr.mode = 0644;
-		zone_dev_attrs[zone].show = zone_show;
-		zone_dev_attrs[zone].store = zone_set;
-		zone_data[zone].location = zone;
-		zone_attrs[zone] = &zone_dev_attrs[zone].attr;
-		zone_data[zone].attr = &zone_dev_attrs[zone];
-	}
-	zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
-	zone_attribute_group.attrs = zone_attrs;
-
-	led_classdev_register(&dev->dev, &global_led);
-
-	return sysfs_create_group(&dev->dev.kobj, &zone_attribute_group);
+	return led_classdev_register(&dev->dev, &global_led);
 }
 
 static void alienware_zone_exit(struct platform_device *dev)
 {
-	u8 zone;
-
-	sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
 	led_classdev_unregister(&global_led);
-	if (zone_dev_attrs) {
-		for (zone = 0; zone < quirks->num_zones; zone++)
-			kfree(zone_dev_attrs[zone].attr.name);
-	}
-	kfree(zone_dev_attrs);
-	kfree(zone_data);
-	kfree(zone_attrs);
 }
 
 static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
@@ -1143,6 +1107,7 @@ static void remove_thermal_profile(void)
  * Platform Driver
  */
 static const struct attribute_group *alienfx_groups[] = {
+	&zone_attribute_group,
 	&hdmi_attribute_group,
 	&amplifier_attribute_group,
 	&deepsleep_attribute_group,
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 06/20] alienware_wmi: Clean variable declaration in thermal methods
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (4 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 05/20] alienware-wmi: Improve rgb-zones " Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  1:06   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 07/20] alienware-wmi: Add a state container for LED control feature Kurt Borja
                   ` (14 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Reorder variable declaration from longest to shortest.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index a431b1fec9fb..67cf376df0f5 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -923,13 +923,13 @@ static bool is_wmax_thermal_code(u32 code)
 
 static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
 {
-	acpi_status status;
 	struct wmax_u32_args in_args = {
 		.operation = operation,
 		.arg1 = arg,
 		.arg2 = 0,
 		.arg3 = 0,
 	};
+	acpi_status status;
 
 	status = alienware_wmax_command(&in_args, sizeof(in_args),
 					WMAX_METHOD_THERMAL_INFORMATION,
@@ -946,13 +946,13 @@ static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
 
 static int wmax_thermal_control(u8 profile)
 {
-	acpi_status status;
 	struct wmax_u32_args in_args = {
 		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
 		.arg1 = profile,
 		.arg2 = 0,
 		.arg3 = 0,
 	};
+	acpi_status status;
 	u32 out_data;
 
 	status = alienware_wmax_command(&in_args, sizeof(in_args),
@@ -970,13 +970,13 @@ static int wmax_thermal_control(u8 profile)
 
 static int wmax_game_shift_status(u8 operation, u32 *out_data)
 {
-	acpi_status status;
 	struct wmax_u32_args in_args = {
 		.operation = operation,
 		.arg1 = 0,
 		.arg2 = 0,
 		.arg3 = 0,
 	};
+	acpi_status status;
 
 	status = alienware_wmax_command(&in_args, sizeof(in_args),
 					WMAX_METHOD_GAME_SHIFT_STATUS,
@@ -1045,11 +1045,11 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 
 static int create_thermal_profile(struct platform_device *platform_device)
 {
-	u32 out_data;
+	enum platform_profile_option profile;
+	enum wmax_thermal_mode mode;
 	u8 sys_desc[4];
 	u32 first_mode;
-	enum wmax_thermal_mode mode;
-	enum platform_profile_option profile;
+	u32 out_data;
 	int ret;
 
 	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 07/20] alienware-wmi: Add a state container for LED control feature
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (5 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 06/20] alienware_wmi: Clean variable declaration in thermal methods Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  1:32   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 08/20] alienware-wmi: Add WMI Drivers Kurt Borja
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Add a state container for the "alienware-wmi" platform device and
initialize it on the new alienfx_probe(). Migrate all LED control functions
to use this state container.

Additionally move the led_classdev registration to the platform driver
probe and make it device managed.

Drop alienware_zone_init() and alienware_zone_exit() because they are no
longer needed.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 128 +++++++++++++---------
 1 file changed, 76 insertions(+), 52 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index 67cf376df0f5..4b68d64bd742 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -404,14 +404,19 @@ struct wmax_u32_args {
 	u8 arg3;
 };
 
+struct alienfx_priv {
+	struct platform_device *pdev;
+	struct led_classdev global_led;
+	struct color_platform colors[4];
+	u8 global_brightness;
+	u8 lighting_control_state;
+};
+
 static struct platform_device *platform_device;
-static struct color_platform colors[4];
 static struct platform_profile_handler pp_handler;
 static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
 
 static u8 interface;
-static u8 lighting_control_state;
-static u8 global_brightness;
 
 /*
  * Helpers used for zone control
@@ -443,7 +448,7 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
 /*
  * Individual RGB zone control
  */
-static int alienware_update_led(u8 location)
+static int alienware_update_led(struct alienfx_priv *priv, u8 location)
 {
 	int method_id;
 	acpi_status status;
@@ -453,21 +458,21 @@ static int alienware_update_led(u8 location)
 	struct wmax_led_args wmax_basic_args;
 	if (interface == WMAX) {
 		wmax_basic_args.led_mask = 1 << location;
-		wmax_basic_args.colors = colors[location];
-		wmax_basic_args.state = lighting_control_state;
+		wmax_basic_args.colors = priv->colors[location];
+		wmax_basic_args.state = priv->lighting_control_state;
 		guid = WMAX_CONTROL_GUID;
 		method_id = WMAX_METHOD_ZONE_CONTROL;
 
 		input.length = sizeof(wmax_basic_args);
 		input.pointer = &wmax_basic_args;
 	} else {
-		legacy_args.colors = colors[location];
-		legacy_args.brightness = global_brightness;
+		legacy_args.colors = priv->colors[location];
+		legacy_args.brightness = priv->global_brightness;
 		legacy_args.state = 0;
-		if (lighting_control_state == LEGACY_BOOTING ||
-		    lighting_control_state == LEGACY_SUSPEND) {
+		if (priv->lighting_control_state == LEGACY_BOOTING ||
+		    priv->lighting_control_state == LEGACY_SUSPEND) {
 			guid = LEGACY_POWER_CONTROL_GUID;
-			legacy_args.state = lighting_control_state;
+			legacy_args.state = priv->lighting_control_state;
 		} else
 			guid = LEGACY_CONTROL_GUID;
 		method_id = location + 1;
@@ -486,22 +491,32 @@ static int alienware_update_led(u8 location)
 static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
 			 char *buf, u8 location)
 {
+	struct color_platform *colors;
+	struct alienfx_priv *priv;
+
+	priv = dev_get_drvdata(dev);
+	colors = &priv->colors[location];
+
 	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
-		       colors[location].red, colors[location].green,
-		       colors[location].blue);
+		       colors->red, colors->green, colors->blue);
 
 }
 
 static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count, u8 location)
 {
+	struct color_platform *colors;
+	struct alienfx_priv *priv;
 	int ret;
 
-	ret = parse_rgb(buf, &colors[location]);
+	priv = dev_get_drvdata(dev);
+	colors = &priv->colors[location];
+
+	ret = parse_rgb(buf, colors);
 	if (ret)
 		return ret;
 
-	ret = alienware_update_led(location);
+	ret = alienware_update_led(priv, location);
 
 	return ret ? ret : count;
 }
@@ -539,9 +554,13 @@ static ssize_t lighting_control_state_show(struct device *dev,
 					   struct device_attribute *attr,
 					   char *buf)
 {
-	if (lighting_control_state == LEGACY_BOOTING)
+	struct alienfx_priv *priv;
+
+	priv = dev_get_drvdata(dev);
+
+	if (priv->lighting_control_state == LEGACY_BOOTING)
 		return sysfs_emit(buf, "[booting] running suspend\n");
-	else if (lighting_control_state == LEGACY_SUSPEND)
+	else if (priv->lighting_control_state == LEGACY_SUSPEND)
 		return sysfs_emit(buf, "booting running [suspend]\n");
 
 	return sysfs_emit(buf, "booting [running] suspend\n");
@@ -551,8 +570,11 @@ static ssize_t lighting_control_state_store(struct device *dev,
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
+	struct alienfx_priv *priv;
 	u8 val;
 
+	priv = dev_get_drvdata(dev);
+
 	if (strcmp(buf, "booting\n") == 0)
 		val = LEGACY_BOOTING;
 	else if (strcmp(buf, "suspend\n") == 0)
@@ -562,9 +584,9 @@ static ssize_t lighting_control_state_store(struct device *dev,
 	else
 		val = WMAX_RUNNING;
 
-	lighting_control_state = val;
+	priv->lighting_control_state = val;
 	pr_debug("alienware-wmi: updated control state to %d\n",
-		 lighting_control_state);
+		 priv->lighting_control_state);
 
 	return count;
 }
@@ -621,43 +643,26 @@ static int wmax_brightness(int brightness)
 static void global_led_set(struct led_classdev *led_cdev,
 			   enum led_brightness brightness)
 {
+	struct alienfx_priv *priv;
 	int ret;
-	global_brightness = brightness;
+
+	priv = container_of(led_cdev, struct alienfx_priv, global_led);
+	priv->global_brightness = brightness;
 	if (interface == WMAX)
 		ret = wmax_brightness(brightness);
 	else
-		ret = alienware_update_led(0);
+		ret = alienware_update_led(priv, 0);
 	if (ret)
 		pr_err("LED brightness update failed\n");
 }
 
 static enum led_brightness global_led_get(struct led_classdev *led_cdev)
 {
-	return global_brightness;
-}
-
-static struct led_classdev global_led = {
-	.brightness_set = global_led_set,
-	.brightness_get = global_led_get,
-	.name = "alienware::global_brightness",
-};
-
-static int alienware_zone_init(struct platform_device *dev)
-{
-	if (interface == WMAX) {
-		lighting_control_state = WMAX_RUNNING;
-	} else if (interface == LEGACY) {
-		lighting_control_state = LEGACY_RUNNING;
-	}
-	global_led.max_brightness = 0x0F;
-	global_brightness = global_led.max_brightness;
+	struct alienfx_priv *priv;
 
-	return led_classdev_register(&dev->dev, &global_led);
-}
+	priv = container_of(led_cdev, struct alienfx_priv, global_led);
 
-static void alienware_zone_exit(struct platform_device *dev)
-{
-	led_classdev_unregister(&global_led);
+	return priv->global_brightness;
 }
 
 static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
@@ -1106,6 +1111,32 @@ static void remove_thermal_profile(void)
 /*
  * Platform Driver
  */
+static int alienfx_probe(struct platform_device *pdev)
+{
+	struct alienfx_priv *priv;
+	struct led_classdev *leds;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	platform_set_drvdata(pdev, priv);
+
+	priv->pdev = pdev;
+
+	if (interface == WMAX)
+		priv->lighting_control_state = WMAX_RUNNING;
+	else if (interface == LEGACY)
+		priv->lighting_control_state = LEGACY_RUNNING;
+
+	leds = &priv->global_led;
+	leds->name = "alienware::global_brightness";
+	leds->brightness_set = global_led_set;
+	leds->brightness_get = global_led_get;
+	leds->max_brightness = 0x0F;
+
+	priv->global_brightness = priv->global_led.max_brightness;
+
+	return devm_led_classdev_register(&pdev->dev, &priv->global_led);
+}
+
 static const struct attribute_group *alienfx_groups[] = {
 	&zone_attribute_group,
 	&hdmi_attribute_group,
@@ -1119,6 +1150,7 @@ static struct platform_driver platform_driver = {
 		.name = "alienware-wmi",
 		.dev_groups = alienfx_groups,
 	},
+	.probe = alienfx_probe,
 };
 
 static int __init alienware_wmi_init(void)
@@ -1166,15 +1198,8 @@ static int __init alienware_wmi_init(void)
 			goto fail_prep_thermal_profile;
 	}
 
-	ret = alienware_zone_init(platform_device);
-	if (ret)
-		goto fail_prep_zones;
-
 	return 0;
 
-fail_prep_zones:
-	alienware_zone_exit(platform_device);
-	remove_thermal_profile();
 fail_prep_thermal_profile:
 	platform_device_del(platform_device);
 fail_platform_device2:
@@ -1189,7 +1214,6 @@ module_init(alienware_wmi_init);
 
 static void __exit alienware_wmi_exit(void)
 {
-	alienware_zone_exit(platform_device);
 	remove_thermal_profile();
 	platform_device_unregister(platform_device);
 	platform_driver_unregister(&platform_driver);
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 08/20] alienware-wmi: Add WMI Drivers
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (6 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 07/20] alienware-wmi: Add a state container for LED control feature Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:21   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods Kurt Borja
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Add WMI drivers for LEGACY and WMAX devices.

This involves moving platform driver and device registration to a helper
function, which is now called from the driver's preferred WMI device
driver probe. However this is only done if !quirks->thermal because
newer WMAX interface doesn't support any of the features exposed by this
device.

Only one driver is registered on module initialization to prevent
registering duplicate platform driver and device.

Aditionally, create_thermal_profile() now takes wmi_device * instead of
platform_device *.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 186 +++++++++++++++++-----
 1 file changed, 146 insertions(+), 40 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index 4b68d64bd742..f2f6842e27e6 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -15,6 +15,7 @@
 #include <linux/platform_profile.h>
 #include <linux/dmi.h>
 #include <linux/leds.h>
+#include <linux/wmi.h>
 
 #define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
 #define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
@@ -39,8 +40,6 @@
 MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
 MODULE_DESCRIPTION("Alienware special feature control");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("wmi:" LEGACY_CONTROL_GUID);
-MODULE_ALIAS("wmi:" WMAX_CONTROL_GUID);
 
 static bool force_platform_profile;
 module_param_unsafe(force_platform_profile, bool, 0);
@@ -412,7 +411,10 @@ struct alienfx_priv {
 	u8 lighting_control_state;
 };
 
-static struct platform_device *platform_device;
+struct alienfx_platdata {
+	struct wmi_device *wdev;
+};
+
 static struct platform_profile_handler pp_handler;
 static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
 
@@ -1048,7 +1050,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 	return wmax_thermal_control(supported_thermal_profiles[profile]);
 }
 
-static int create_thermal_profile(struct platform_device *platform_device)
+static int create_thermal_profile(struct wmi_device *wdev)
 {
 	enum platform_profile_option profile;
 	enum wmax_thermal_mode mode;
@@ -1097,7 +1099,7 @@ static int create_thermal_profile(struct platform_device *platform_device)
 	pp_handler.profile_get = thermal_profile_get;
 	pp_handler.profile_set = thermal_profile_set;
 	pp_handler.name = "alienware-wmi";
-	pp_handler.dev = &platform_device->dev;
+	pp_handler.dev = &wdev->dev;
 
 	return platform_profile_register(&pp_handler);
 }
@@ -1153,19 +1155,138 @@ static struct platform_driver platform_driver = {
 	.probe = alienfx_probe,
 };
 
-static int __init alienware_wmi_init(void)
+static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
 {
+	struct platform_device *pdev;
 	int ret;
 
-	if (wmi_has_guid(LEGACY_CONTROL_GUID))
-		interface = LEGACY;
-	else if (wmi_has_guid(WMAX_CONTROL_GUID))
-		interface = WMAX;
-	else {
-		pr_warn("alienware-wmi: No known WMI GUID found\n");
-		return -ENODEV;
+	ret = platform_driver_register(&platform_driver);
+	if (ret < 0)
+		return ret;
+
+	pdev = platform_device_register_data(NULL, "alienware-wmi",
+					     PLATFORM_DEVID_NONE, pdata,
+					     sizeof(*pdata));
+
+	if (IS_ERR(pdev)) {
+		platform_driver_unregister(&platform_driver);
+		return PTR_ERR(pdev);
 	}
 
+	dev_set_drvdata(&pdata->wdev->dev, pdev);
+
+	return 0;
+}
+
+static void alienware_alienfx_exit(struct wmi_device *wdev)
+{
+	struct platform_device *pdev;
+
+	pdev = dev_get_drvdata(&wdev->dev);
+
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&platform_driver);
+}
+
+/*
+ * Legacy WMI driver
+ */
+static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+	struct alienfx_platdata pdata = {
+		.wdev = wdev,
+	};
+
+	return alienware_alienfx_setup(&pdata);
+}
+
+static void legacy_wmi_remove(struct wmi_device *wdev)
+{
+	alienware_alienfx_exit(wdev);
+}
+
+static struct wmi_device_id alienware_legacy_device_id_table[] = {
+	{ LEGACY_CONTROL_GUID, NULL },
+	{ },
+};
+MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
+
+static struct wmi_driver alienware_legacy_wmi_driver = {
+	.driver = {
+		.name = "alienware-wmi-alienfx",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.id_table = alienware_legacy_device_id_table,
+	.probe = legacy_wmi_probe,
+	.remove = legacy_wmi_remove,
+};
+
+static int __init alienware_legacy_wmi_init(void)
+{
+	return wmi_driver_register(&alienware_legacy_wmi_driver);
+}
+
+static void __exit alienware_legacy_wmi_exit(void)
+{
+	wmi_driver_unregister(&alienware_legacy_wmi_driver);
+}
+
+/*
+ * WMAX WMI driver
+ */
+static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+	struct alienfx_platdata pdata = {
+		.wdev = wdev,
+	};
+	int ret = 0;
+
+	if (quirks->thermal)
+		ret = create_thermal_profile(wdev);
+	else
+		ret = alienware_alienfx_setup(&pdata);
+
+	return ret;
+}
+
+static void wmax_wmi_remove(struct wmi_device *wdev)
+{
+	if (quirks->thermal)
+		remove_thermal_profile();
+	else
+		alienware_alienfx_exit(wdev);
+}
+
+static struct wmi_device_id alienware_wmax_device_id_table[] = {
+	{ WMAX_CONTROL_GUID, NULL },
+	{ },
+};
+MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
+
+static struct wmi_driver alienware_wmax_wmi_driver = {
+	.driver = {
+		.name = "alienware-wmi-wmax",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.id_table = alienware_wmax_device_id_table,
+	.probe = wmax_wmi_probe,
+	.remove = wmax_wmi_remove,
+};
+
+static int __init alienware_wmax_wmi_init(void)
+{
+	return wmi_driver_register(&alienware_wmax_wmi_driver);
+}
+
+static void __exit alienware_wmax_wmi_exit(void)
+{
+	wmi_driver_unregister(&alienware_wmax_wmi_driver);
+}
+
+static int __init alienware_wmi_init(void)
+{
+	int ret;
+
 	dmi_check_system(alienware_quirks);
 	if (quirks == NULL)
 		quirks = &quirk_unknown;
@@ -1180,43 +1301,28 @@ static int __init alienware_wmi_init(void)
 			pr_warn("force_gmode requires platform profile support\n");
 	}
 
-	ret = platform_driver_register(&platform_driver);
-	if (ret)
-		goto fail_platform_driver;
-	platform_device = platform_device_alloc("alienware-wmi", PLATFORM_DEVID_NONE);
-	if (!platform_device) {
-		ret = -ENOMEM;
-		goto fail_platform_device1;
+	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
+		interface = WMAX;
+		ret = alienware_wmax_wmi_init();
+	} else {
+		interface = LEGACY;
+		ret = alienware_legacy_wmi_init();
 	}
-	ret = platform_device_add(platform_device);
-	if (ret)
-		goto fail_platform_device2;
 
-	if (quirks->thermal) {
-		ret = create_thermal_profile(platform_device);
-		if (ret)
-			goto fail_prep_thermal_profile;
-	}
+	if (ret < 0)
+		return ret;
 
 	return 0;
-
-fail_prep_thermal_profile:
-	platform_device_del(platform_device);
-fail_platform_device2:
-	platform_device_put(platform_device);
-fail_platform_device1:
-	platform_driver_unregister(&platform_driver);
-fail_platform_driver:
-	return ret;
 }
 
 module_init(alienware_wmi_init);
 
 static void __exit alienware_wmi_exit(void)
 {
-	remove_thermal_profile();
-	platform_device_unregister(platform_device);
-	platform_driver_unregister(&platform_driver);
+	if (interface == WMAX)
+		alienware_wmax_wmi_exit();
+	else
+		alienware_legacy_wmi_exit();
 }
 
 module_exit(alienware_wmi_exit);
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (7 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 08/20] alienware-wmi: Add WMI Drivers Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:26   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 10/20] alienware-wmi: Refactor LED " Kurt Borja
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Refactor all thermal control methods to use the newly defined awcc_priv
state container instead of global variables.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 71 +++++++++++++++++------
 1 file changed, 52 insertions(+), 19 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index f2f6842e27e6..c4ca141d628e 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -403,6 +403,12 @@ struct wmax_u32_args {
 	u8 arg3;
 };
 
+struct awcc_priv {
+	struct wmi_device *wdev;
+	struct platform_profile_handler pp_handler;
+	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
+};
+
 struct alienfx_priv {
 	struct platform_device *pdev;
 	struct led_classdev global_led;
@@ -415,9 +421,6 @@ struct alienfx_platdata {
 	struct wmi_device *wdev;
 };
 
-static struct platform_profile_handler pp_handler;
-static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
-
 static u8 interface;
 
 /*
@@ -1027,6 +1030,10 @@ static int thermal_profile_get(struct platform_profile_handler *pprof,
 static int thermal_profile_set(struct platform_profile_handler *pprof,
 			       enum platform_profile_option profile)
 {
+	struct awcc_priv *priv;
+
+	priv = container_of(pprof, struct awcc_priv, pp_handler);
+
 	if (quirks->gmode) {
 		u32 gmode_status;
 		int ret;
@@ -1047,18 +1054,21 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 		}
 	}
 
-	return wmax_thermal_control(supported_thermal_profiles[profile]);
+	return wmax_thermal_control(priv->supported_thermal_profiles[profile]);
 }
 
 static int create_thermal_profile(struct wmi_device *wdev)
 {
 	enum platform_profile_option profile;
 	enum wmax_thermal_mode mode;
+	struct awcc_priv *priv;
 	u8 sys_desc[4];
 	u32 first_mode;
 	u32 out_data;
 	int ret;
 
+	priv = dev_get_drvdata(&wdev->dev);
+
 	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
 				       0, (u32 *) &sys_desc);
 	if (ret < 0)
@@ -1081,33 +1091,56 @@ static int create_thermal_profile(struct wmi_device *wdev)
 
 		mode = out_data & WMAX_THERMAL_MODE_MASK;
 		profile = wmax_mode_to_platform_profile[mode];
-		supported_thermal_profiles[profile] = out_data;
+		priv->supported_thermal_profiles[profile] = out_data;
 
-		set_bit(profile, pp_handler.choices);
+		set_bit(profile, priv->pp_handler.choices);
 	}
 
-	if (bitmap_empty(pp_handler.choices, PLATFORM_PROFILE_LAST))
+	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
 		return -ENODEV;
 
 	if (quirks->gmode) {
-		supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
+		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
 			WMAX_THERMAL_MODE_GMODE;
 
-		set_bit(PLATFORM_PROFILE_PERFORMANCE, pp_handler.choices);
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
 	}
 
-	pp_handler.profile_get = thermal_profile_get;
-	pp_handler.profile_set = thermal_profile_set;
-	pp_handler.name = "alienware-wmi";
-	pp_handler.dev = &wdev->dev;
+	priv->pp_handler.profile_get = thermal_profile_get;
+	priv->pp_handler.profile_set = thermal_profile_set;
+	priv->pp_handler.name = "alienware-wmi";
+	priv->pp_handler.dev = &wdev->dev;
 
-	return platform_profile_register(&pp_handler);
+	return platform_profile_register(&priv->pp_handler);
 }
 
-static void remove_thermal_profile(void)
+static int alienware_awcc_setup(struct wmi_device *wdev)
 {
-	if (quirks->thermal)
-		platform_profile_remove(&pp_handler);
+	struct awcc_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(&wdev->dev, priv);
+
+	priv->wdev = wdev;
+
+	ret = create_thermal_profile(wdev);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void alienware_awcc_exit(struct wmi_device *wdev)
+{
+	struct awcc_priv *priv;
+
+	priv = dev_get_drvdata(&wdev->dev);
+
+	platform_profile_remove(&priv->pp_handler);
 }
 
 /*
@@ -1242,7 +1275,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
 	int ret = 0;
 
 	if (quirks->thermal)
-		ret = create_thermal_profile(wdev);
+		ret = alienware_awcc_setup(wdev);
 	else
 		ret = alienware_alienfx_setup(&pdata);
 
@@ -1252,7 +1285,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
 static void wmax_wmi_remove(struct wmi_device *wdev)
 {
 	if (quirks->thermal)
-		remove_thermal_profile();
+		alienware_awcc_exit(wdev);
 	else
 		alienware_alienfx_exit(wdev);
 }
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 10/20] alienware-wmi: Refactor LED control methods
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (8 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:41   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 11/20] alienware-wmi: Refactor hdmi, amplifier, deepslp methods Kurt Borja
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Both WMI devices handled by this module specify a distinct interface for
LED control. Previously this module handled this by dynamically adapting
arguments passed to wmi_evaluate_method() based on the `interface`
global variable.

To avoid the use of global variables, and enable the migration to
non-deprecated WMI methods, let the WMI drivers define upd_led and
upd_brightness operations, which completely replace
alienware_update_led() and wmax_brightness().

Also define alienware_wmi_command(), which serves as a wrapper for
wmidev_evaluate_method(). This new method is very similar to
alienware_wmax_command() but is WMI device agnostic.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 180 ++++++++++++++--------
 1 file changed, 118 insertions(+), 62 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index c4ca141d628e..bcf3b2f80dfd 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -417,12 +417,46 @@ struct alienfx_priv {
 	u8 lighting_control_state;
 };
 
+struct alienfx_ops {
+	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
+		       u8 location);
+	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
+			      u8 brightness);
+};
+
 struct alienfx_platdata {
 	struct wmi_device *wdev;
+	struct alienfx_ops ops;
 };
 
 static u8 interface;
 
+static acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
+					 void *in_args, size_t in_size, u32 *out_data)
+{
+	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer in = {in_size, in_args};
+	union acpi_object *obj;
+	acpi_status ret;
+
+	if (out_data) {
+		ret = wmidev_evaluate_method(wdev, 0, method_id, &in, &out);
+		if (ACPI_FAILURE(ret))
+			goto out_free_ptr;
+
+		obj = (union acpi_object *)out.pointer;
+
+		if (obj && obj->type == ACPI_TYPE_INTEGER)
+			*out_data = (u32)obj->integer.value;
+	} else {
+		ret = wmidev_evaluate_method(wdev, 0, method_id, &in, NULL);
+	}
+
+out_free_ptr:
+	kfree(out.pointer);
+	return ret;
+}
+
 /*
  * Helpers used for zone control
  */
@@ -453,46 +487,6 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
 /*
  * Individual RGB zone control
  */
-static int alienware_update_led(struct alienfx_priv *priv, u8 location)
-{
-	int method_id;
-	acpi_status status;
-	char *guid;
-	struct acpi_buffer input;
-	struct legacy_led_args legacy_args;
-	struct wmax_led_args wmax_basic_args;
-	if (interface == WMAX) {
-		wmax_basic_args.led_mask = 1 << location;
-		wmax_basic_args.colors = priv->colors[location];
-		wmax_basic_args.state = priv->lighting_control_state;
-		guid = WMAX_CONTROL_GUID;
-		method_id = WMAX_METHOD_ZONE_CONTROL;
-
-		input.length = sizeof(wmax_basic_args);
-		input.pointer = &wmax_basic_args;
-	} else {
-		legacy_args.colors = priv->colors[location];
-		legacy_args.brightness = priv->global_brightness;
-		legacy_args.state = 0;
-		if (priv->lighting_control_state == LEGACY_BOOTING ||
-		    priv->lighting_control_state == LEGACY_SUSPEND) {
-			guid = LEGACY_POWER_CONTROL_GUID;
-			legacy_args.state = priv->lighting_control_state;
-		} else
-			guid = LEGACY_CONTROL_GUID;
-		method_id = location + 1;
-
-		input.length = sizeof(legacy_args);
-		input.pointer = &legacy_args;
-	}
-	pr_debug("alienware-wmi: guid %s method %d\n", guid, method_id);
-
-	status = wmi_evaluate_method(guid, 0, method_id, &input, NULL);
-	if (ACPI_FAILURE(status))
-		pr_err("alienware-wmi: zone set failure: %u\n", status);
-	return ACPI_FAILURE(status);
-}
-
 static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
 			 char *buf, u8 location)
 {
@@ -510,18 +504,20 @@ static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
 static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count, u8 location)
 {
+	struct alienfx_platdata *pdata;
 	struct color_platform *colors;
 	struct alienfx_priv *priv;
 	int ret;
 
 	priv = dev_get_drvdata(dev);
+	pdata = dev_get_platdata(dev);
 	colors = &priv->colors[location];
 
 	ret = parse_rgb(buf, colors);
 	if (ret)
 		return ret;
 
-	ret = alienware_update_led(priv, location);
+	ret = pdata->ops.upd_led(priv, pdata->wdev, location);
 
 	return ret ? ret : count;
 }
@@ -628,35 +624,19 @@ static struct attribute_group zone_attribute_group = {
 /*
  * LED Brightness (Global)
  */
-static int wmax_brightness(int brightness)
-{
-	acpi_status status;
-	struct acpi_buffer input;
-	struct wmax_brightness_args args = {
-		.led_mask = 0xFF,
-		.percentage = brightness,
-	};
-	input.length = sizeof(args);
-	input.pointer = &args;
-	status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
-				     WMAX_METHOD_BRIGHTNESS, &input, NULL);
-	if (ACPI_FAILURE(status))
-		pr_err("alienware-wmi: brightness set failure: %u\n", status);
-	return ACPI_FAILURE(status);
-}
-
 static void global_led_set(struct led_classdev *led_cdev,
 			   enum led_brightness brightness)
 {
+	struct alienfx_platdata *pdata;
 	struct alienfx_priv *priv;
 	int ret;
 
 	priv = container_of(led_cdev, struct alienfx_priv, global_led);
+	pdata = dev_get_platdata(&priv->pdev->dev);
+
 	priv->global_brightness = brightness;
-	if (interface == WMAX)
-		ret = wmax_brightness(brightness);
-	else
-		ret = alienware_update_led(priv, 0);
+
+	ret = pdata->ops.upd_brightness(priv, pdata->wdev, brightness);
 	if (ret)
 		pr_err("LED brightness update failed\n");
 }
@@ -1224,10 +1204,47 @@ static void alienware_alienfx_exit(struct wmi_device *wdev)
 /*
  * Legacy WMI driver
  */
+static int legacy_wmi_update_led(struct alienfx_priv *priv,
+				 struct wmi_device *wdev, u8 location)
+{
+	struct legacy_led_args legacy_args;
+	struct acpi_buffer input;
+	acpi_status status;
+
+	legacy_args.colors = priv->colors[location];
+	legacy_args.brightness = priv->global_brightness;
+	legacy_args.state = priv->lighting_control_state;
+
+	input.length = sizeof(legacy_args);
+	input.pointer = &legacy_args;
+
+	if (legacy_args.state == LEGACY_RUNNING)
+		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
+					       sizeof(legacy_args), NULL);
+	else
+		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
+					     location + 1, &input, NULL);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	return 0;
+}
+
+static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
+					struct wmi_device *wdev, u8 brightness)
+{
+	return legacy_wmi_update_led(priv, wdev, 0);
+}
+
 static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
 {
 	struct alienfx_platdata pdata = {
 		.wdev = wdev,
+		.ops = {
+			.upd_led = legacy_wmi_update_led,
+			.upd_brightness = legacy_wmi_update_brightness,
+		},
 	};
 
 	return alienware_alienfx_setup(&pdata);
@@ -1267,10 +1284,49 @@ static void __exit alienware_legacy_wmi_exit(void)
 /*
  * WMAX WMI driver
  */
+static int wmax_wmi_update_led(struct alienfx_priv *priv,
+			       struct wmi_device *wdev, u8 location)
+{
+	struct wmax_led_args in_args = {
+		.led_mask = 1 << location,
+		.colors = priv->colors[location],
+		.state = priv->lighting_control_state,
+	};
+	acpi_status status;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
+				       &in_args, sizeof(in_args), NULL);
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	return 0;
+}
+
+static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
+				      struct wmi_device *wdev, u8 brightness)
+{
+	struct wmax_brightness_args in_args = {
+		.led_mask = 0xFF,
+		.percentage = brightness,
+	};
+	acpi_status status;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
+				       sizeof(in_args), NULL);
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	return 0;
+}
+
 static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
 {
 	struct alienfx_platdata pdata = {
 		.wdev = wdev,
+		.ops = {
+			.upd_led = wmax_wmi_update_led,
+			.upd_brightness = wmax_wmi_update_brightness,
+		},
 	};
 	int ret = 0;
 
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 11/20] alienware-wmi: Refactor hdmi, amplifier, deepslp methods
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (9 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 10/20] alienware-wmi: Refactor LED " Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:43   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 12/20] alienware-wmi: Refactor thermal control methods Kurt Borja
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Refactor show/store methods for hdmi, amplifier, deepslp sysfs groups to
use alienware_wmi_command() instead of alienware_wmax_command() which
uses deprecated WMI methods.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 51 ++++++++++++++++-------
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index bcf3b2f80dfd..b9da5fe657a9 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -685,14 +685,18 @@ static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
 static ssize_t show_hdmi_cable(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 {
+	struct alienfx_platdata *pdata;
 	acpi_status status;
 	u32 out_data;
 	struct wmax_basic_args in_args = {
 		.arg = 0,
 	};
-	status =
-	    alienware_wmax_command(&in_args, sizeof(in_args),
-				   WMAX_METHOD_HDMI_CABLE, &out_data);
+
+	pdata = dev_get_platdata(dev);
+
+	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_CABLE,
+				       &in_args, sizeof(in_args), &out_data);
+
 	if (ACPI_SUCCESS(status)) {
 		if (out_data == 0)
 			return sysfs_emit(buf, "[unconnected] connected unknown\n");
@@ -706,14 +710,17 @@ static ssize_t show_hdmi_cable(struct device *dev,
 static ssize_t show_hdmi_source(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct alienfx_platdata *pdata;
 	acpi_status status;
 	u32 out_data;
 	struct wmax_basic_args in_args = {
 		.arg = 0,
 	};
-	status =
-	    alienware_wmax_command(&in_args, sizeof(in_args),
-				   WMAX_METHOD_HDMI_STATUS, &out_data);
+
+	pdata = dev_get_platdata(dev);
+
+	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_STATUS,
+				       &in_args, sizeof(in_args), &out_data);
 
 	if (ACPI_SUCCESS(status)) {
 		if (out_data == 1)
@@ -729,8 +736,12 @@ static ssize_t toggle_hdmi_source(struct device *dev,
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
 {
+	struct alienfx_platdata *pdata;
 	acpi_status status;
 	struct wmax_basic_args args;
+
+	pdata = dev_get_platdata(dev);
+
 	if (strcmp(buf, "gpu\n") == 0)
 		args.arg = 1;
 	else if (strcmp(buf, "input\n") == 0)
@@ -739,8 +750,8 @@ static ssize_t toggle_hdmi_source(struct device *dev,
 		args.arg = 3;
 	pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf);
 
-	status = alienware_wmax_command(&args, sizeof(args),
-					WMAX_METHOD_HDMI_SOURCE, NULL);
+	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_SOURCE,
+				       &args, sizeof(args), NULL);
 
 	if (ACPI_FAILURE(status))
 		pr_err("alienware-wmi: HDMI toggle failed: results: %u\n",
@@ -778,14 +789,17 @@ static const struct attribute_group hdmi_attribute_group = {
 static ssize_t show_amplifier_status(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct alienfx_platdata *pdata;
 	acpi_status status;
 	u32 out_data;
 	struct wmax_basic_args in_args = {
 		.arg = 0,
 	};
-	status =
-	    alienware_wmax_command(&in_args, sizeof(in_args),
-				   WMAX_METHOD_AMPLIFIER_CABLE, &out_data);
+
+	pdata = dev_get_platdata(dev);
+
+	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_AMPLIFIER_CABLE,
+				       &in_args, sizeof(in_args), &out_data);
 	if (ACPI_SUCCESS(status)) {
 		if (out_data == 0)
 			return sysfs_emit(buf, "[unconnected] connected unknown\n");
@@ -822,13 +836,17 @@ static const struct attribute_group amplifier_attribute_group = {
 static ssize_t show_deepsleep_status(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct alienfx_platdata *pdata;
 	acpi_status status;
 	u32 out_data;
 	struct wmax_basic_args in_args = {
 		.arg = 0,
 	};
-	status = alienware_wmax_command(&in_args, sizeof(in_args),
-					WMAX_METHOD_DEEP_SLEEP_STATUS, &out_data);
+
+	pdata = dev_get_platdata(dev);
+
+	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_STATUS,
+				       &in_args, sizeof(in_args), &out_data);
 	if (ACPI_SUCCESS(status)) {
 		if (out_data == 0)
 			return sysfs_emit(buf, "[disabled] s5 s5_s4\n");
@@ -845,9 +863,12 @@ static ssize_t toggle_deepsleep(struct device *dev,
 				struct device_attribute *attr,
 				const char *buf, size_t count)
 {
+	struct alienfx_platdata *pdata;
 	acpi_status status;
 	struct wmax_basic_args args;
 
+	pdata = dev_get_platdata(dev);
+
 	if (strcmp(buf, "disabled\n") == 0)
 		args.arg = 0;
 	else if (strcmp(buf, "s5\n") == 0)
@@ -856,8 +877,8 @@ static ssize_t toggle_deepsleep(struct device *dev,
 		args.arg = 2;
 	pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf);
 
-	status = alienware_wmax_command(&args, sizeof(args),
-					WMAX_METHOD_DEEP_SLEEP_CONTROL, NULL);
+	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_CONTROL,
+				       &args, sizeof(args), NULL);
 
 	if (ACPI_FAILURE(status))
 		pr_err("alienware-wmi: deep sleep control failed: results: %u\n",
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 12/20] alienware-wmi: Refactor thermal control methods
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (10 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 11/20] alienware-wmi: Refactor hdmi, amplifier, deepslp methods Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:45   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 13/20] alienware-wmi: Split DMI table Kurt Borja
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Refactor thermal control methods to use alienware_wmi_command() instead
of alienware_wmax_command().

Drop alienware_wmax_command() as there is no more users left.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 69 ++++++++---------------
 1 file changed, 23 insertions(+), 46 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index b9da5fe657a9..0a0b72dc61ea 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -650,34 +650,6 @@ static enum led_brightness global_led_get(struct led_classdev *led_cdev)
 	return priv->global_brightness;
 }
 
-static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
-					  u32 command, u32 *out_data)
-{
-	acpi_status status;
-	union acpi_object *obj;
-	struct acpi_buffer input;
-	struct acpi_buffer output;
-
-	input.length = in_size;
-	input.pointer = in_args;
-	if (out_data) {
-		output.length = ACPI_ALLOCATE_BUFFER;
-		output.pointer = NULL;
-		status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
-					     command, &input, &output);
-		if (ACPI_SUCCESS(status)) {
-			obj = (union acpi_object *)output.pointer;
-			if (obj && obj->type == ACPI_TYPE_INTEGER)
-				*out_data = (u32)obj->integer.value;
-		}
-		kfree(output.pointer);
-	} else {
-		status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
-					     command, &input, NULL);
-	}
-	return status;
-}
-
 /*
  *	The HDMI mux sysfs node indicates the status of the HDMI input mux.
  *	It can toggle between standard system GPU output and HDMI input.
@@ -932,7 +904,8 @@ static bool is_wmax_thermal_code(u32 code)
 	return false;
 }
 
-static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
+static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
+				    u8 arg, u32 *out_data)
 {
 	struct wmax_u32_args in_args = {
 		.operation = operation,
@@ -942,9 +915,8 @@ static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
 	};
 	acpi_status status;
 
-	status = alienware_wmax_command(&in_args, sizeof(in_args),
-					WMAX_METHOD_THERMAL_INFORMATION,
-					out_data);
+	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
+				       &in_args, sizeof(in_args), out_data);
 
 	if (ACPI_FAILURE(status))
 		return -EIO;
@@ -955,7 +927,7 @@ static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
 	return 0;
 }
 
-static int wmax_thermal_control(u8 profile)
+static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
 {
 	struct wmax_u32_args in_args = {
 		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
@@ -966,9 +938,8 @@ static int wmax_thermal_control(u8 profile)
 	acpi_status status;
 	u32 out_data;
 
-	status = alienware_wmax_command(&in_args, sizeof(in_args),
-					WMAX_METHOD_THERMAL_CONTROL,
-					&out_data);
+	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
+				       &in_args, sizeof(in_args), &out_data);
 
 	if (ACPI_FAILURE(status))
 		return -EIO;
@@ -979,7 +950,8 @@ static int wmax_thermal_control(u8 profile)
 	return 0;
 }
 
-static int wmax_game_shift_status(u8 operation, u32 *out_data)
+static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
+				  u32 *out_data)
 {
 	struct wmax_u32_args in_args = {
 		.operation = operation,
@@ -989,9 +961,8 @@ static int wmax_game_shift_status(u8 operation, u32 *out_data)
 	};
 	acpi_status status;
 
-	status = alienware_wmax_command(&in_args, sizeof(in_args),
-					WMAX_METHOD_GAME_SHIFT_STATUS,
-					out_data);
+	status = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
+				       &in_args, sizeof(in_args), out_data);
 
 	if (ACPI_FAILURE(status))
 		return -EIO;
@@ -1005,10 +976,13 @@ static int wmax_game_shift_status(u8 operation, u32 *out_data)
 static int thermal_profile_get(struct platform_profile_handler *pprof,
 			       enum platform_profile_option *profile)
 {
+	struct awcc_priv *priv;
 	u32 out_data;
 	int ret;
 
-	ret = wmax_thermal_information(WMAX_OPERATION_CURRENT_PROFILE,
+	priv = container_of(pprof, struct awcc_priv, pp_handler);
+
+	ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
 				       0, &out_data);
 
 	if (ret < 0)
@@ -1039,7 +1013,8 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 		u32 gmode_status;
 		int ret;
 
-		ret = wmax_game_shift_status(WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
+		ret = wmax_game_shift_status(priv->wdev,
+					     WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
 					     &gmode_status);
 
 		if (ret < 0)
@@ -1047,7 +1022,8 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 
 		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
 		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
-			ret = wmax_game_shift_status(WMAX_OPERATION_TOGGLE_GAME_SHIFT,
+			ret = wmax_game_shift_status(priv->wdev,
+						     WMAX_OPERATION_TOGGLE_GAME_SHIFT,
 						     &gmode_status);
 
 			if (ret < 0)
@@ -1055,7 +1031,8 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 		}
 	}
 
-	return wmax_thermal_control(priv->supported_thermal_profiles[profile]);
+	return wmax_thermal_control(priv->wdev,
+				    priv->supported_thermal_profiles[profile]);
 }
 
 static int create_thermal_profile(struct wmi_device *wdev)
@@ -1070,7 +1047,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
 
 	priv = dev_get_drvdata(&wdev->dev);
 
-	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
+	ret = wmax_thermal_information(wdev, WMAX_OPERATION_SYS_DESCRIPTION,
 				       0, (u32 *) &sys_desc);
 	if (ret < 0)
 		return ret;
@@ -1078,7 +1055,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
 	first_mode = sys_desc[0] + sys_desc[1];
 
 	for (u32 i = 0; i < sys_desc[3]; i++) {
-		ret = wmax_thermal_information(WMAX_OPERATION_LIST_IDS,
+		ret = wmax_thermal_information(wdev, WMAX_OPERATION_LIST_IDS,
 					       i + first_mode, &out_data);
 
 		if (ret == -EIO)
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 13/20] alienware-wmi: Split DMI table
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (11 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 12/20] alienware-wmi: Refactor thermal control methods Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:55   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 14/20] MAINTAINERS: Update ALIENWARE WMI DRIVER entry Kurt Borja
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Split thermal features into a new DMI table to support upcoming file
split.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi.c | 163 +++++++++-------------
 1 file changed, 69 insertions(+), 94 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
index 0a0b72dc61ea..8ea08f5f8810 100644
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ b/drivers/platform/x86/dell/alienware-wmi.c
@@ -118,8 +118,6 @@ struct quirk_entry {
 	u8 hdmi_mux;
 	u8 amplifier;
 	u8 deepslp;
-	bool thermal;
-	bool gmode;
 };
 
 static struct quirk_entry *quirks;
@@ -130,8 +128,6 @@ static struct quirk_entry quirk_inspiron5675 = {
 	.hdmi_mux = 0,
 	.amplifier = 0,
 	.deepslp = 0,
-	.thermal = false,
-	.gmode = false,
 };
 
 static struct quirk_entry quirk_unknown = {
@@ -139,8 +135,6 @@ static struct quirk_entry quirk_unknown = {
 	.hdmi_mux = 0,
 	.amplifier = 0,
 	.deepslp = 0,
-	.thermal = false,
-	.gmode = false,
 };
 
 static struct quirk_entry quirk_x51_r1_r2 = {
@@ -148,8 +142,6 @@ static struct quirk_entry quirk_x51_r1_r2 = {
 	.hdmi_mux = 0,
 	.amplifier = 0,
 	.deepslp = 0,
-	.thermal = false,
-	.gmode = false,
 };
 
 static struct quirk_entry quirk_x51_r3 = {
@@ -157,8 +149,6 @@ static struct quirk_entry quirk_x51_r3 = {
 	.hdmi_mux = 0,
 	.amplifier = 1,
 	.deepslp = 0,
-	.thermal = false,
-	.gmode = false,
 };
 
 static struct quirk_entry quirk_asm100 = {
@@ -166,8 +156,6 @@ static struct quirk_entry quirk_asm100 = {
 	.hdmi_mux = 1,
 	.amplifier = 0,
 	.deepslp = 0,
-	.thermal = false,
-	.gmode = false,
 };
 
 static struct quirk_entry quirk_asm200 = {
@@ -175,8 +163,6 @@ static struct quirk_entry quirk_asm200 = {
 	.hdmi_mux = 1,
 	.amplifier = 0,
 	.deepslp = 1,
-	.thermal = false,
-	.gmode = false,
 };
 
 static struct quirk_entry quirk_asm201 = {
@@ -184,26 +170,6 @@ static struct quirk_entry quirk_asm201 = {
 	.hdmi_mux = 1,
 	.amplifier = 1,
 	.deepslp = 1,
-	.thermal = false,
-	.gmode = false,
-};
-
-static struct quirk_entry quirk_g_series = {
-	.num_zones = 2,
-	.hdmi_mux = 0,
-	.amplifier = 0,
-	.deepslp = 0,
-	.thermal = true,
-	.gmode = true,
-};
-
-static struct quirk_entry quirk_x_series = {
-	.num_zones = 2,
-	.hdmi_mux = 0,
-	.amplifier = 0,
-	.deepslp = 0,
-	.thermal = true,
-	.gmode = false,
 };
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
@@ -242,133 +208,140 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
 	},
 	{
 		.callback = dmi_matched,
-		.ident = "Alienware m17 R5",
+		.ident = "Alienware X51 R1",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
 		},
-		.driver_data = &quirk_x_series,
+		.driver_data = &quirk_x51_r1_r2,
 	},
 	{
 		.callback = dmi_matched,
-		.ident = "Alienware m18 R2",
+		.ident = "Alienware X51 R2",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
 		},
-		.driver_data = &quirk_x_series,
+		.driver_data = &quirk_x51_r1_r2,
 	},
 	{
 		.callback = dmi_matched,
-		.ident = "Alienware x15 R1",
+		.ident = "Alienware X51 R3",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
 		},
-		.driver_data = &quirk_x_series,
+		.driver_data = &quirk_x51_r3,
 	},
 	{
 		.callback = dmi_matched,
-		.ident = "Alienware x17 R2",
+		.ident = "Dell Inc. Inspiron 5675",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
+		},
+		.driver_data = &quirk_inspiron5675,
+	},
+	{}
+};
+
+struct awcc_features {
+	bool gmode;
+};
+
+static struct awcc_features g_series_features = {
+	.gmode = true,
+};
+
+static struct awcc_features x_series_features = {
+	.gmode = false,
+};
+
+static const struct dmi_system_id awcc_dmi_table[] __initconst = {
+	{
+		.ident = "Alienware m17 R5",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
 		},
-		.driver_data = &quirk_x_series,
+		.driver_data = &x_series_features,
 	},
 	{
-		.callback = dmi_matched,
-		.ident = "Alienware X51 R1",
+		.ident = "Alienware m18 R2",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
 		},
-		.driver_data = &quirk_x51_r1_r2,
+		.driver_data = &x_series_features,
 	},
 	{
-		.callback = dmi_matched,
-		.ident = "Alienware X51 R2",
+		.ident = "Alienware x15 R1",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
 		},
-		.driver_data = &quirk_x51_r1_r2,
+		.driver_data = &x_series_features,
 	},
 	{
-		.callback = dmi_matched,
-		.ident = "Alienware X51 R3",
+		.ident = "Alienware x17 R2",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
 		},
-		.driver_data = &quirk_x51_r3,
+		.driver_data = &x_series_features,
 	},
 	{
-		.callback = dmi_matched,
 		.ident = "Dell Inc. G15 5510",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
 		},
-		.driver_data = &quirk_g_series,
+		.driver_data = &g_series_features,
 	},
 	{
-		.callback = dmi_matched,
 		.ident = "Dell Inc. G15 5511",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
 		},
-		.driver_data = &quirk_g_series,
+		.driver_data = &g_series_features,
 	},
 	{
-		.callback = dmi_matched,
 		.ident = "Dell Inc. G15 5515",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
 		},
-		.driver_data = &quirk_g_series,
+		.driver_data = &g_series_features,
 	},
 	{
-		.callback = dmi_matched,
 		.ident = "Dell Inc. G3 3500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
 		},
-		.driver_data = &quirk_g_series,
+		.driver_data = &g_series_features,
 	},
 	{
-		.callback = dmi_matched,
 		.ident = "Dell Inc. G3 3590",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
 		},
-		.driver_data = &quirk_g_series,
+		.driver_data = &g_series_features,
 	},
 	{
-		.callback = dmi_matched,
 		.ident = "Dell Inc. G5 5500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
 		},
-		.driver_data = &quirk_g_series,
-	},
-	{
-		.callback = dmi_matched,
-		.ident = "Dell Inc. Inspiron 5675",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
-		},
-		.driver_data = &quirk_inspiron5675,
+		.driver_data = &g_series_features,
 	},
-	{}
 };
 
+struct awcc_features *awcc;
+
 struct color_platform {
 	u8 blue;
 	u8 green;
@@ -1009,7 +982,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
 
 	priv = container_of(pprof, struct awcc_priv, pp_handler);
 
-	if (quirks->gmode) {
+	if (awcc->gmode) {
 		u32 gmode_status;
 		int ret;
 
@@ -1077,7 +1050,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
 	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
 		return -ENODEV;
 
-	if (quirks->gmode) {
+	if (awcc->gmode) {
 		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
 			WMAX_THERMAL_MODE_GMODE;
 
@@ -1328,7 +1301,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
 	};
 	int ret = 0;
 
-	if (quirks->thermal)
+	if (awcc)
 		ret = alienware_awcc_setup(wdev);
 	else
 		ret = alienware_alienfx_setup(&pdata);
@@ -1338,7 +1311,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
 
 static void wmax_wmi_remove(struct wmi_device *wdev)
 {
-	if (quirks->thermal)
+	if (awcc)
 		alienware_awcc_exit(wdev);
 	else
 		alienware_alienfx_exit(wdev);
@@ -1362,6 +1335,18 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
 
 static int __init alienware_wmax_wmi_init(void)
 {
+	const struct dmi_system_id *id;
+
+	id = dmi_first_match(awcc_dmi_table);
+	if (id)
+		awcc = id->driver_data;
+
+	if (force_platform_profile)
+		awcc = &x_series_features;
+
+	if (force_gmode)
+		awcc = &g_series_features;
+
 	return wmi_driver_register(&alienware_wmax_wmi_driver);
 }
 
@@ -1378,16 +1363,6 @@ static int __init alienware_wmi_init(void)
 	if (quirks == NULL)
 		quirks = &quirk_unknown;
 
-	if (force_platform_profile)
-		quirks->thermal = true;
-
-	if (force_gmode) {
-		if (quirks->thermal)
-			quirks->gmode = true;
-		else
-			pr_warn("force_gmode requires platform profile support\n");
-	}
-
 	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
 		interface = WMAX;
 		ret = alienware_wmax_wmi_init();
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 14/20] MAINTAINERS: Update ALIENWARE WMI DRIVER entry
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (12 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 13/20] alienware-wmi: Split DMI table Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:56   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 15/20] platform/x86: Rename alienware-wmi.c Kurt Borja
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Dell has been inactive in its maintainership role of this driver since
around 2021. Due to this, add myself as a maintainer.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 MAINTAINERS | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3809931b9240..596c6a46478c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -784,10 +784,12 @@ F:	Documentation/admin-guide/perf/alibaba_pmu.rst
 F:	drivers/perf/alibaba_uncore_drw_pmu.c
 
 ALIENWARE WMI DRIVER
+M:	Kurt Borja <kuurtb@gmail.com>
+L:	platform-driver-x86@vger.kernel.org
 L:	Dell.Client.Kernel@dell.com
 S:	Maintained
 F:	Documentation/wmi/devices/alienware-wmi.rst
-F:	drivers/platform/x86/dell/alienware-wmi.c
+F:	drivers/platform/x86/dell/alienware-wmi*
 
 ALLEGRO DVT VIDEO IP CORE DRIVER
 M:	Michael Tretter <m.tretter@pengutronix.de>
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 15/20] platform/x86: Rename alienware-wmi.c
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (13 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 14/20] MAINTAINERS: Update ALIENWARE WMI DRIVER entry Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  3:57   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 16/20] platform/x86: Add alienware-wmi.h Kurt Borja
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Rename alienware-wmi to support upcoming split.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/Makefile                               | 1 +
 .../platform/x86/dell/{alienware-wmi.c => alienware-wmi-base.c}  | 0
 2 files changed, 1 insertion(+)
 rename drivers/platform/x86/dell/{alienware-wmi.c => alienware-wmi-base.c} (100%)

diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
index bb3cbd470a46..f8aec8502c2f 100644
--- a/drivers/platform/x86/dell/Makefile
+++ b/drivers/platform/x86/dell/Makefile
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
+alienware-wmi-objs			:= alienware-wmi-base.o
 obj-$(CONFIG_DCDBAS)			+= dcdbas.o
 obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
 obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi-base.c
similarity index 100%
rename from drivers/platform/x86/dell/alienware-wmi.c
rename to drivers/platform/x86/dell/alienware-wmi-base.c
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 16/20] platform/x86: Add alienware-wmi.h
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (14 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 15/20] platform/x86: Rename alienware-wmi.c Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  4:02   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 17/20] platform-x86: Split the alienware-wmi driver Kurt Borja
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Add a header file for alienware-wmi with shared resources to support the
upcoming file split.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 .../platform/x86/dell/alienware-wmi-base.c    |  93 ++--------------
 drivers/platform/x86/dell/alienware-wmi.h     | 103 ++++++++++++++++++
 2 files changed, 112 insertions(+), 84 deletions(-)
 create mode 100644 drivers/platform/x86/dell/alienware-wmi.h

diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
index 8ea08f5f8810..e8d470bbb608 100644
--- a/drivers/platform/x86/dell/alienware-wmi-base.c
+++ b/drivers/platform/x86/dell/alienware-wmi-base.c
@@ -16,26 +16,7 @@
 #include <linux/dmi.h>
 #include <linux/leds.h>
 #include <linux/wmi.h>
-
-#define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
-#define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
-#define WMAX_CONTROL_GUID		"A70591CE-A997-11DA-B012-B622A1EF5492"
-
-#define WMAX_METHOD_HDMI_SOURCE		0x1
-#define WMAX_METHOD_HDMI_STATUS		0x2
-#define WMAX_METHOD_BRIGHTNESS		0x3
-#define WMAX_METHOD_ZONE_CONTROL	0x4
-#define WMAX_METHOD_HDMI_CABLE		0x5
-#define WMAX_METHOD_AMPLIFIER_CABLE	0x6
-#define WMAX_METHOD_DEEP_SLEEP_CONTROL	0x0B
-#define WMAX_METHOD_DEEP_SLEEP_STATUS	0x0C
-#define WMAX_METHOD_THERMAL_INFORMATION	0x14
-#define WMAX_METHOD_THERMAL_CONTROL	0x15
-#define WMAX_METHOD_GAME_SHIFT_STATUS	0x25
-
-#define WMAX_THERMAL_MODE_GMODE		0xAB
-
-#define WMAX_FAILURE_CODE		0xFFFFFFFF
+#include "alienware-wmi.h"
 
 MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
 MODULE_DESCRIPTION("Alienware special feature control");
@@ -54,18 +35,6 @@ enum INTERFACE_FLAGS {
 	WMAX,
 };
 
-enum LEGACY_CONTROL_STATES {
-	LEGACY_RUNNING = 1,
-	LEGACY_BOOTING = 0,
-	LEGACY_SUSPEND = 3,
-};
-
-enum WMAX_CONTROL_STATES {
-	WMAX_RUNNING = 0xFF,
-	WMAX_BOOTING = 0,
-	WMAX_SUSPEND = 3,
-};
-
 enum WMAX_THERMAL_INFORMATION_OPERATIONS {
 	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
 	WMAX_OPERATION_LIST_IDS			= 0x03,
@@ -122,7 +91,6 @@ struct quirk_entry {
 
 static struct quirk_entry *quirks;
 
-
 static struct quirk_entry quirk_inspiron5675 = {
 	.num_zones = 2,
 	.hdmi_mux = 0,
@@ -342,33 +310,10 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {
 
 struct awcc_features *awcc;
 
-struct color_platform {
-	u8 blue;
-	u8 green;
-	u8 red;
-} __packed;
-
-struct wmax_brightness_args {
-	u32 led_mask;
-	u32 percentage;
-};
-
 struct wmax_basic_args {
 	u8 arg;
 };
 
-struct legacy_led_args {
-	struct color_platform colors;
-	u8 brightness;
-	u8 state;
-} __packed;
-
-struct wmax_led_args {
-	u32 led_mask;
-	struct color_platform colors;
-	u8 state;
-} __packed;
-
 struct wmax_u32_args {
 	u8 operation;
 	u8 arg1;
@@ -382,30 +327,10 @@ struct awcc_priv {
 	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
 };
 
-struct alienfx_priv {
-	struct platform_device *pdev;
-	struct led_classdev global_led;
-	struct color_platform colors[4];
-	u8 global_brightness;
-	u8 lighting_control_state;
-};
-
-struct alienfx_ops {
-	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
-		       u8 location);
-	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
-			      u8 brightness);
-};
-
-struct alienfx_platdata {
-	struct wmi_device *wdev;
-	struct alienfx_ops ops;
-};
-
 static u8 interface;
 
-static acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
-					 void *in_args, size_t in_size, u32 *out_data)
+acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
+				  void *in_args, size_t in_size, u32 *out_data)
 {
 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
 	struct acpi_buffer in = {in_size, in_args};
@@ -1139,7 +1064,7 @@ static struct platform_driver platform_driver = {
 	.probe = alienfx_probe,
 };
 
-static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
+int alienware_alienfx_setup(struct alienfx_platdata *pdata)
 {
 	struct platform_device *pdev;
 	int ret;
@@ -1162,7 +1087,7 @@ static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
 	return 0;
 }
 
-static void alienware_alienfx_exit(struct wmi_device *wdev)
+void alienware_alienfx_exit(struct wmi_device *wdev)
 {
 	struct platform_device *pdev;
 
@@ -1242,12 +1167,12 @@ static struct wmi_driver alienware_legacy_wmi_driver = {
 	.remove = legacy_wmi_remove,
 };
 
-static int __init alienware_legacy_wmi_init(void)
+int __init alienware_legacy_wmi_init(void)
 {
 	return wmi_driver_register(&alienware_legacy_wmi_driver);
 }
 
-static void __exit alienware_legacy_wmi_exit(void)
+void __exit alienware_legacy_wmi_exit(void)
 {
 	wmi_driver_unregister(&alienware_legacy_wmi_driver);
 }
@@ -1333,7 +1258,7 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
 	.remove = wmax_wmi_remove,
 };
 
-static int __init alienware_wmax_wmi_init(void)
+int __init alienware_wmax_wmi_init(void)
 {
 	const struct dmi_system_id *id;
 
@@ -1350,7 +1275,7 @@ static int __init alienware_wmax_wmi_init(void)
 	return wmi_driver_register(&alienware_wmax_wmi_driver);
 }
 
-static void __exit alienware_wmax_wmi_exit(void)
+void __exit alienware_wmax_wmi_exit(void)
 {
 	wmi_driver_unregister(&alienware_wmax_wmi_driver);
 }
diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
new file mode 100644
index 000000000000..78ac10122155
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Alienware WMI special features driver
+ *
+ * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
+ * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#ifndef _ALIENWARE_WMI_H_
+#define _ALIENWARE_WMI_H_
+
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/wmi.h>
+
+#define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
+#define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
+#define WMAX_CONTROL_GUID		"A70591CE-A997-11DA-B012-B622A1EF5492"
+
+#define WMAX_METHOD_HDMI_SOURCE			0x1
+#define WMAX_METHOD_HDMI_STATUS			0x2
+#define WMAX_METHOD_BRIGHTNESS			0x3
+#define WMAX_METHOD_ZONE_CONTROL		0x4
+#define WMAX_METHOD_HDMI_CABLE			0x5
+#define WMAX_METHOD_AMPLIFIER_CABLE		0x6
+#define WMAX_METHOD_DEEP_SLEEP_CONTROL		0x0B
+#define WMAX_METHOD_DEEP_SLEEP_STATUS		0x0C
+#define WMAX_METHOD_THERMAL_INFORMATION		0x14
+#define WMAX_METHOD_THERMAL_CONTROL		0x15
+#define WMAX_METHOD_GAME_SHIFT_STATUS		0x25
+
+#define WMAX_THERMAL_MODE_GMODE			0xAB
+
+#define WMAX_FAILURE_CODE			0xFFFFFFFF
+
+enum LEGACY_CONTROL_STATES {
+	LEGACY_RUNNING = 1,
+	LEGACY_BOOTING = 0,
+	LEGACY_SUSPEND = 3,
+};
+
+enum WMAX_CONTROL_STATES {
+	WMAX_RUNNING = 0xFF,
+	WMAX_BOOTING = 0,
+	WMAX_SUSPEND = 3,
+};
+
+struct color_platform {
+	u8 blue;
+	u8 green;
+	u8 red;
+} __packed;
+
+struct wmax_brightness_args {
+	u32 led_mask;
+	u32 percentage;
+};
+
+struct legacy_led_args {
+	struct color_platform colors;
+	u8 brightness;
+	u8 state;
+} __packed;
+
+struct wmax_led_args {
+	u32 led_mask;
+	struct color_platform colors;
+	u8 state;
+} __packed;
+
+struct alienfx_priv {
+	struct platform_device *pdev;
+	struct led_classdev global_led;
+	struct color_platform colors[4];
+	u8 global_brightness;
+	u8 lighting_control_state;
+};
+
+struct alienfx_ops {
+	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
+		       u8 location);
+	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
+			      u8 brightness);
+};
+
+struct alienfx_platdata {
+	struct wmi_device *wdev;
+	struct alienfx_ops ops;
+};
+
+acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
+				  void *in_args, size_t in_size, u32 *out_data);
+
+int alienware_alienfx_setup(struct alienfx_platdata *pdata);
+void alienware_alienfx_exit(struct wmi_device *wdev);
+
+int __init alienware_legacy_wmi_init(void);
+void __exit alienware_legacy_wmi_exit(void);
+
+int __init alienware_wmax_wmi_init(void);
+void __exit alienware_wmax_wmi_exit(void);
+
+#endif
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 17/20] platform-x86: Split the alienware-wmi driver
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (15 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 16/20] platform/x86: Add alienware-wmi.h Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  4:04   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 18/20] platform/x86: dell: Modify Makefile alignment Kurt Borja
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Split alienware-wmi WMI drivers into different files. This is done
seamlessly by copying and pasting.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/Makefile            |   2 +
 .../platform/x86/dell/alienware-wmi-base.c    | 596 ------------------
 .../platform/x86/dell/alienware-wmi-legacy.c  |  89 +++
 .../platform/x86/dell/alienware-wmi-wmax.c    | 526 ++++++++++++++++
 4 files changed, 617 insertions(+), 596 deletions(-)
 create mode 100644 drivers/platform/x86/dell/alienware-wmi-legacy.c
 create mode 100644 drivers/platform/x86/dell/alienware-wmi-wmax.c

diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
index f8aec8502c2f..03ba459f3d31 100644
--- a/drivers/platform/x86/dell/Makefile
+++ b/drivers/platform/x86/dell/Makefile
@@ -6,6 +6,8 @@
 
 obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
 alienware-wmi-objs			:= alienware-wmi-base.o
+alienware-wmi-y				+= alienware-wmi-legacy.o
+alienware-wmi-y				+= alienware-wmi-wmax.o
 obj-$(CONFIG_DCDBAS)			+= dcdbas.o
 obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
 obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
index e8d470bbb608..450ba0a48004 100644
--- a/drivers/platform/x86/dell/alienware-wmi-base.c
+++ b/drivers/platform/x86/dell/alienware-wmi-base.c
@@ -8,80 +8,21 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/acpi.h>
-#include <linux/bitfield.h>
-#include <linux/bits.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/platform_profile.h>
 #include <linux/dmi.h>
 #include <linux/leds.h>
-#include <linux/wmi.h>
 #include "alienware-wmi.h"
 
 MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
 MODULE_DESCRIPTION("Alienware special feature control");
 MODULE_LICENSE("GPL");
 
-static bool force_platform_profile;
-module_param_unsafe(force_platform_profile, bool, 0);
-MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
-
-static bool force_gmode;
-module_param_unsafe(force_gmode, bool, 0);
-MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
-
 enum INTERFACE_FLAGS {
 	LEGACY,
 	WMAX,
 };
 
-enum WMAX_THERMAL_INFORMATION_OPERATIONS {
-	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
-	WMAX_OPERATION_LIST_IDS			= 0x03,
-	WMAX_OPERATION_CURRENT_PROFILE		= 0x0B,
-};
-
-enum WMAX_THERMAL_CONTROL_OPERATIONS {
-	WMAX_OPERATION_ACTIVATE_PROFILE		= 0x01,
-};
-
-enum WMAX_GAME_SHIFT_STATUS_OPERATIONS {
-	WMAX_OPERATION_TOGGLE_GAME_SHIFT	= 0x01,
-	WMAX_OPERATION_GET_GAME_SHIFT_STATUS	= 0x02,
-};
-
-enum WMAX_THERMAL_TABLES {
-	WMAX_THERMAL_TABLE_BASIC		= 0x90,
-	WMAX_THERMAL_TABLE_USTT			= 0xA0,
-};
-
-enum wmax_thermal_mode {
-	THERMAL_MODE_USTT_BALANCED,
-	THERMAL_MODE_USTT_BALANCED_PERFORMANCE,
-	THERMAL_MODE_USTT_COOL,
-	THERMAL_MODE_USTT_QUIET,
-	THERMAL_MODE_USTT_PERFORMANCE,
-	THERMAL_MODE_USTT_LOW_POWER,
-	THERMAL_MODE_BASIC_QUIET,
-	THERMAL_MODE_BASIC_BALANCED,
-	THERMAL_MODE_BASIC_BALANCED_PERFORMANCE,
-	THERMAL_MODE_BASIC_PERFORMANCE,
-	THERMAL_MODE_LAST,
-};
-
-static const enum platform_profile_option wmax_mode_to_platform_profile[THERMAL_MODE_LAST] = {
-	[THERMAL_MODE_USTT_BALANCED]			= PLATFORM_PROFILE_BALANCED,
-	[THERMAL_MODE_USTT_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
-	[THERMAL_MODE_USTT_COOL]			= PLATFORM_PROFILE_COOL,
-	[THERMAL_MODE_USTT_QUIET]			= PLATFORM_PROFILE_QUIET,
-	[THERMAL_MODE_USTT_PERFORMANCE]			= PLATFORM_PROFILE_PERFORMANCE,
-	[THERMAL_MODE_USTT_LOW_POWER]			= PLATFORM_PROFILE_LOW_POWER,
-	[THERMAL_MODE_BASIC_QUIET]			= PLATFORM_PROFILE_QUIET,
-	[THERMAL_MODE_BASIC_BALANCED]			= PLATFORM_PROFILE_BALANCED,
-	[THERMAL_MODE_BASIC_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
-	[THERMAL_MODE_BASIC_PERFORMANCE]		= PLATFORM_PROFILE_PERFORMANCE,
-};
-
 struct quirk_entry {
 	u8 num_zones;
 	u8 hdmi_mux;
@@ -213,120 +154,10 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
 	{}
 };
 
-struct awcc_features {
-	bool gmode;
-};
-
-static struct awcc_features g_series_features = {
-	.gmode = true,
-};
-
-static struct awcc_features x_series_features = {
-	.gmode = false,
-};
-
-static const struct dmi_system_id awcc_dmi_table[] __initconst = {
-	{
-		.ident = "Alienware m17 R5",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
-		},
-		.driver_data = &x_series_features,
-	},
-	{
-		.ident = "Alienware m18 R2",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
-		},
-		.driver_data = &x_series_features,
-	},
-	{
-		.ident = "Alienware x15 R1",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
-		},
-		.driver_data = &x_series_features,
-	},
-	{
-		.ident = "Alienware x17 R2",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
-		},
-		.driver_data = &x_series_features,
-	},
-	{
-		.ident = "Dell Inc. G15 5510",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
-		},
-		.driver_data = &g_series_features,
-	},
-	{
-		.ident = "Dell Inc. G15 5511",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
-		},
-		.driver_data = &g_series_features,
-	},
-	{
-		.ident = "Dell Inc. G15 5515",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
-		},
-		.driver_data = &g_series_features,
-	},
-	{
-		.ident = "Dell Inc. G3 3500",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
-		},
-		.driver_data = &g_series_features,
-	},
-	{
-		.ident = "Dell Inc. G3 3590",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
-		},
-		.driver_data = &g_series_features,
-	},
-	{
-		.ident = "Dell Inc. G5 5500",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
-		},
-		.driver_data = &g_series_features,
-	},
-};
-
-struct awcc_features *awcc;
-
 struct wmax_basic_args {
 	u8 arg;
 };
 
-struct wmax_u32_args {
-	u8 operation;
-	u8 arg1;
-	u8 arg2;
-	u8 arg3;
-};
-
-struct awcc_priv {
-	struct wmi_device *wdev;
-	struct platform_profile_handler pp_handler;
-	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
-};
-
 static u8 interface;
 
 acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
@@ -775,250 +606,6 @@ static const struct attribute_group deepsleep_attribute_group = {
 	.attrs = deepsleep_attrs,
 };
 
-/*
- * Thermal Profile control
- *  - Provides thermal profile control through the Platform Profile API
- */
-#define WMAX_THERMAL_TABLE_MASK		GENMASK(7, 4)
-#define WMAX_THERMAL_MODE_MASK		GENMASK(3, 0)
-#define WMAX_SENSOR_ID_MASK		BIT(8)
-
-static bool is_wmax_thermal_code(u32 code)
-{
-	if (code & WMAX_SENSOR_ID_MASK)
-		return false;
-
-	if ((code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_LAST)
-		return false;
-
-	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_BASIC &&
-	    (code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_BASIC_QUIET)
-		return true;
-
-	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_USTT &&
-	    (code & WMAX_THERMAL_MODE_MASK) <= THERMAL_MODE_USTT_LOW_POWER)
-		return true;
-
-	return false;
-}
-
-static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
-				    u8 arg, u32 *out_data)
-{
-	struct wmax_u32_args in_args = {
-		.operation = operation,
-		.arg1 = arg,
-		.arg2 = 0,
-		.arg3 = 0,
-	};
-	acpi_status status;
-
-	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
-				       &in_args, sizeof(in_args), out_data);
-
-	if (ACPI_FAILURE(status))
-		return -EIO;
-
-	if (*out_data == WMAX_FAILURE_CODE)
-		return -EBADRQC;
-
-	return 0;
-}
-
-static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
-{
-	struct wmax_u32_args in_args = {
-		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
-		.arg1 = profile,
-		.arg2 = 0,
-		.arg3 = 0,
-	};
-	acpi_status status;
-	u32 out_data;
-
-	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
-				       &in_args, sizeof(in_args), &out_data);
-
-	if (ACPI_FAILURE(status))
-		return -EIO;
-
-	if (out_data == WMAX_FAILURE_CODE)
-		return -EBADRQC;
-
-	return 0;
-}
-
-static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
-				  u32 *out_data)
-{
-	struct wmax_u32_args in_args = {
-		.operation = operation,
-		.arg1 = 0,
-		.arg2 = 0,
-		.arg3 = 0,
-	};
-	acpi_status status;
-
-	status = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
-				       &in_args, sizeof(in_args), out_data);
-
-	if (ACPI_FAILURE(status))
-		return -EIO;
-
-	if (*out_data == WMAX_FAILURE_CODE)
-		return -EOPNOTSUPP;
-
-	return 0;
-}
-
-static int thermal_profile_get(struct platform_profile_handler *pprof,
-			       enum platform_profile_option *profile)
-{
-	struct awcc_priv *priv;
-	u32 out_data;
-	int ret;
-
-	priv = container_of(pprof, struct awcc_priv, pp_handler);
-
-	ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
-				       0, &out_data);
-
-	if (ret < 0)
-		return ret;
-
-	if (out_data == WMAX_THERMAL_MODE_GMODE) {
-		*profile = PLATFORM_PROFILE_PERFORMANCE;
-		return 0;
-	}
-
-	if (!is_wmax_thermal_code(out_data))
-		return -ENODATA;
-
-	out_data &= WMAX_THERMAL_MODE_MASK;
-	*profile = wmax_mode_to_platform_profile[out_data];
-
-	return 0;
-}
-
-static int thermal_profile_set(struct platform_profile_handler *pprof,
-			       enum platform_profile_option profile)
-{
-	struct awcc_priv *priv;
-
-	priv = container_of(pprof, struct awcc_priv, pp_handler);
-
-	if (awcc->gmode) {
-		u32 gmode_status;
-		int ret;
-
-		ret = wmax_game_shift_status(priv->wdev,
-					     WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
-					     &gmode_status);
-
-		if (ret < 0)
-			return ret;
-
-		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
-		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
-			ret = wmax_game_shift_status(priv->wdev,
-						     WMAX_OPERATION_TOGGLE_GAME_SHIFT,
-						     &gmode_status);
-
-			if (ret < 0)
-				return ret;
-		}
-	}
-
-	return wmax_thermal_control(priv->wdev,
-				    priv->supported_thermal_profiles[profile]);
-}
-
-static int create_thermal_profile(struct wmi_device *wdev)
-{
-	enum platform_profile_option profile;
-	enum wmax_thermal_mode mode;
-	struct awcc_priv *priv;
-	u8 sys_desc[4];
-	u32 first_mode;
-	u32 out_data;
-	int ret;
-
-	priv = dev_get_drvdata(&wdev->dev);
-
-	ret = wmax_thermal_information(wdev, WMAX_OPERATION_SYS_DESCRIPTION,
-				       0, (u32 *) &sys_desc);
-	if (ret < 0)
-		return ret;
-
-	first_mode = sys_desc[0] + sys_desc[1];
-
-	for (u32 i = 0; i < sys_desc[3]; i++) {
-		ret = wmax_thermal_information(wdev, WMAX_OPERATION_LIST_IDS,
-					       i + first_mode, &out_data);
-
-		if (ret == -EIO)
-			return ret;
-
-		if (ret == -EBADRQC)
-			break;
-
-		if (!is_wmax_thermal_code(out_data))
-			continue;
-
-		mode = out_data & WMAX_THERMAL_MODE_MASK;
-		profile = wmax_mode_to_platform_profile[mode];
-		priv->supported_thermal_profiles[profile] = out_data;
-
-		set_bit(profile, priv->pp_handler.choices);
-	}
-
-	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
-		return -ENODEV;
-
-	if (awcc->gmode) {
-		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
-			WMAX_THERMAL_MODE_GMODE;
-
-		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
-	}
-
-	priv->pp_handler.profile_get = thermal_profile_get;
-	priv->pp_handler.profile_set = thermal_profile_set;
-	priv->pp_handler.name = "alienware-wmi";
-	priv->pp_handler.dev = &wdev->dev;
-
-	return platform_profile_register(&priv->pp_handler);
-}
-
-static int alienware_awcc_setup(struct wmi_device *wdev)
-{
-	struct awcc_priv *priv;
-	int ret;
-
-	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	dev_set_drvdata(&wdev->dev, priv);
-
-	priv->wdev = wdev;
-
-	ret = create_thermal_profile(wdev);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-static void alienware_awcc_exit(struct wmi_device *wdev)
-{
-	struct awcc_priv *priv;
-
-	priv = dev_get_drvdata(&wdev->dev);
-
-	platform_profile_remove(&priv->pp_handler);
-}
-
 /*
  * Platform Driver
  */
@@ -1097,189 +684,6 @@ void alienware_alienfx_exit(struct wmi_device *wdev)
 	platform_driver_unregister(&platform_driver);
 }
 
-/*
- * Legacy WMI driver
- */
-static int legacy_wmi_update_led(struct alienfx_priv *priv,
-				 struct wmi_device *wdev, u8 location)
-{
-	struct legacy_led_args legacy_args;
-	struct acpi_buffer input;
-	acpi_status status;
-
-	legacy_args.colors = priv->colors[location];
-	legacy_args.brightness = priv->global_brightness;
-	legacy_args.state = priv->lighting_control_state;
-
-	input.length = sizeof(legacy_args);
-	input.pointer = &legacy_args;
-
-	if (legacy_args.state == LEGACY_RUNNING)
-		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
-					       sizeof(legacy_args), NULL);
-	else
-		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
-					     location + 1, &input, NULL);
-
-	if (ACPI_FAILURE(status))
-		return -EIO;
-
-	return 0;
-}
-
-static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
-					struct wmi_device *wdev, u8 brightness)
-{
-	return legacy_wmi_update_led(priv, wdev, 0);
-}
-
-static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
-{
-	struct alienfx_platdata pdata = {
-		.wdev = wdev,
-		.ops = {
-			.upd_led = legacy_wmi_update_led,
-			.upd_brightness = legacy_wmi_update_brightness,
-		},
-	};
-
-	return alienware_alienfx_setup(&pdata);
-}
-
-static void legacy_wmi_remove(struct wmi_device *wdev)
-{
-	alienware_alienfx_exit(wdev);
-}
-
-static struct wmi_device_id alienware_legacy_device_id_table[] = {
-	{ LEGACY_CONTROL_GUID, NULL },
-	{ },
-};
-MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
-
-static struct wmi_driver alienware_legacy_wmi_driver = {
-	.driver = {
-		.name = "alienware-wmi-alienfx",
-		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
-	},
-	.id_table = alienware_legacy_device_id_table,
-	.probe = legacy_wmi_probe,
-	.remove = legacy_wmi_remove,
-};
-
-int __init alienware_legacy_wmi_init(void)
-{
-	return wmi_driver_register(&alienware_legacy_wmi_driver);
-}
-
-void __exit alienware_legacy_wmi_exit(void)
-{
-	wmi_driver_unregister(&alienware_legacy_wmi_driver);
-}
-
-/*
- * WMAX WMI driver
- */
-static int wmax_wmi_update_led(struct alienfx_priv *priv,
-			       struct wmi_device *wdev, u8 location)
-{
-	struct wmax_led_args in_args = {
-		.led_mask = 1 << location,
-		.colors = priv->colors[location],
-		.state = priv->lighting_control_state,
-	};
-	acpi_status status;
-
-	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
-				       &in_args, sizeof(in_args), NULL);
-	if (ACPI_FAILURE(status))
-		return -EIO;
-
-	return 0;
-}
-
-static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
-				      struct wmi_device *wdev, u8 brightness)
-{
-	struct wmax_brightness_args in_args = {
-		.led_mask = 0xFF,
-		.percentage = brightness,
-	};
-	acpi_status status;
-
-	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
-				       sizeof(in_args), NULL);
-	if (ACPI_FAILURE(status))
-		return -EIO;
-
-	return 0;
-}
-
-static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
-{
-	struct alienfx_platdata pdata = {
-		.wdev = wdev,
-		.ops = {
-			.upd_led = wmax_wmi_update_led,
-			.upd_brightness = wmax_wmi_update_brightness,
-		},
-	};
-	int ret = 0;
-
-	if (awcc)
-		ret = alienware_awcc_setup(wdev);
-	else
-		ret = alienware_alienfx_setup(&pdata);
-
-	return ret;
-}
-
-static void wmax_wmi_remove(struct wmi_device *wdev)
-{
-	if (awcc)
-		alienware_awcc_exit(wdev);
-	else
-		alienware_alienfx_exit(wdev);
-}
-
-static struct wmi_device_id alienware_wmax_device_id_table[] = {
-	{ WMAX_CONTROL_GUID, NULL },
-	{ },
-};
-MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
-
-static struct wmi_driver alienware_wmax_wmi_driver = {
-	.driver = {
-		.name = "alienware-wmi-wmax",
-		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
-	},
-	.id_table = alienware_wmax_device_id_table,
-	.probe = wmax_wmi_probe,
-	.remove = wmax_wmi_remove,
-};
-
-int __init alienware_wmax_wmi_init(void)
-{
-	const struct dmi_system_id *id;
-
-	id = dmi_first_match(awcc_dmi_table);
-	if (id)
-		awcc = id->driver_data;
-
-	if (force_platform_profile)
-		awcc = &x_series_features;
-
-	if (force_gmode)
-		awcc = &g_series_features;
-
-	return wmi_driver_register(&alienware_wmax_wmi_driver);
-}
-
-void __exit alienware_wmax_wmi_exit(void)
-{
-	wmi_driver_unregister(&alienware_wmax_wmi_driver);
-}
-
 static int __init alienware_wmi_init(void)
 {
 	int ret;
diff --git a/drivers/platform/x86/dell/alienware-wmi-legacy.c b/drivers/platform/x86/dell/alienware-wmi-legacy.c
new file mode 100644
index 000000000000..38dd2a602f34
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi-legacy.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Alienware LEGACY WMI device driver
+ *
+ * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#include <linux/wmi.h>
+#include "alienware-wmi.h"
+
+/*
+ * Legacy WMI driver
+ */
+static int legacy_wmi_update_led(struct alienfx_priv *priv,
+				 struct wmi_device *wdev, u8 location)
+{
+	struct legacy_led_args legacy_args;
+	struct acpi_buffer input;
+	acpi_status status;
+
+	legacy_args.colors = priv->colors[location];
+	legacy_args.brightness = priv->global_brightness;
+	legacy_args.state = priv->lighting_control_state;
+
+	input.length = sizeof(legacy_args);
+	input.pointer = &legacy_args;
+
+	if (legacy_args.state == LEGACY_RUNNING)
+		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
+					       sizeof(legacy_args), NULL);
+	else
+		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
+					     location + 1, &input, NULL);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	return 0;
+}
+
+static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
+					struct wmi_device *wdev, u8 brightness)
+{
+	return legacy_wmi_update_led(priv, wdev, 0);
+}
+
+static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+	struct alienfx_platdata pdata = {
+		.wdev = wdev,
+		.ops = {
+			.upd_led = legacy_wmi_update_led,
+			.upd_brightness = legacy_wmi_update_brightness,
+		},
+	};
+
+	return alienware_alienfx_setup(&pdata);
+}
+
+static void legacy_wmi_remove(struct wmi_device *wdev)
+{
+	alienware_alienfx_exit(wdev);
+}
+
+static struct wmi_device_id alienware_legacy_device_id_table[] = {
+	{ LEGACY_CONTROL_GUID, NULL },
+	{ },
+};
+MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
+
+static struct wmi_driver alienware_legacy_wmi_driver = {
+	.driver = {
+		.name = "alienware-wmi-alienfx",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.id_table = alienware_legacy_device_id_table,
+	.probe = legacy_wmi_probe,
+	.remove = legacy_wmi_remove,
+};
+
+int __init alienware_legacy_wmi_init(void)
+{
+	return wmi_driver_register(&alienware_legacy_wmi_driver);
+}
+
+void __exit alienware_legacy_wmi_exit(void)
+{
+	wmi_driver_unregister(&alienware_legacy_wmi_driver);
+}
diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c
new file mode 100644
index 000000000000..75b9a1f029b2
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c
@@ -0,0 +1,526 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Alienware WMAX WMI device driver
+ *
+ * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#include <linux/dmi.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_profile.h>
+#include <linux/wmi.h>
+#include "alienware-wmi.h"
+
+#define WMAX_THERMAL_TABLE_MASK		GENMASK(7, 4)
+#define WMAX_THERMAL_MODE_MASK		GENMASK(3, 0)
+#define WMAX_SENSOR_ID_MASK		BIT(8)
+
+static bool force_platform_profile;
+module_param_unsafe(force_platform_profile, bool, 0);
+MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
+
+static bool force_gmode;
+module_param_unsafe(force_gmode, bool, 0);
+MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
+
+enum WMAX_THERMAL_INFORMATION_OPERATIONS {
+	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
+	WMAX_OPERATION_LIST_IDS			= 0x03,
+	WMAX_OPERATION_CURRENT_PROFILE		= 0x0B,
+};
+
+enum WMAX_THERMAL_CONTROL_OPERATIONS {
+	WMAX_OPERATION_ACTIVATE_PROFILE		= 0x01,
+};
+
+enum WMAX_GAME_SHIFT_STATUS_OPERATIONS {
+	WMAX_OPERATION_TOGGLE_GAME_SHIFT	= 0x01,
+	WMAX_OPERATION_GET_GAME_SHIFT_STATUS	= 0x02,
+};
+
+enum WMAX_THERMAL_TABLES {
+	WMAX_THERMAL_TABLE_BASIC		= 0x90,
+	WMAX_THERMAL_TABLE_USTT			= 0xA0,
+};
+
+enum wmax_thermal_mode {
+	THERMAL_MODE_USTT_BALANCED,
+	THERMAL_MODE_USTT_BALANCED_PERFORMANCE,
+	THERMAL_MODE_USTT_COOL,
+	THERMAL_MODE_USTT_QUIET,
+	THERMAL_MODE_USTT_PERFORMANCE,
+	THERMAL_MODE_USTT_LOW_POWER,
+	THERMAL_MODE_BASIC_QUIET,
+	THERMAL_MODE_BASIC_BALANCED,
+	THERMAL_MODE_BASIC_BALANCED_PERFORMANCE,
+	THERMAL_MODE_BASIC_PERFORMANCE,
+	THERMAL_MODE_LAST,
+};
+
+struct wmax_u32_args {
+	u8 operation;
+	u8 arg1;
+	u8 arg2;
+	u8 arg3;
+};
+
+struct awcc_priv {
+	struct wmi_device *wdev;
+	struct platform_profile_handler pp_handler;
+	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
+};
+
+struct awcc_features {
+	bool gmode;
+};
+
+static struct awcc_features g_series_features = {
+	.gmode = true,
+};
+
+static struct awcc_features x_series_features = {
+	.gmode = false,
+};
+
+static const struct dmi_system_id awcc_dmi_table[] __initconst = {
+	{
+		.ident = "Alienware m17 R5",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
+		},
+		.driver_data = &x_series_features,
+	},
+	{
+		.ident = "Alienware m18 R2",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
+		},
+		.driver_data = &x_series_features,
+	},
+	{
+		.ident = "Alienware x15 R1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
+		},
+		.driver_data = &x_series_features,
+	},
+	{
+		.ident = "Alienware x17 R2",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
+		},
+		.driver_data = &x_series_features,
+	},
+	{
+		.ident = "Dell Inc. G15 5510",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
+		},
+		.driver_data = &g_series_features,
+	},
+	{
+		.ident = "Dell Inc. G15 5511",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
+		},
+		.driver_data = &g_series_features,
+	},
+	{
+		.ident = "Dell Inc. G15 5515",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
+		},
+		.driver_data = &g_series_features,
+	},
+	{
+		.ident = "Dell Inc. G3 3500",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
+		},
+		.driver_data = &g_series_features,
+	},
+	{
+		.ident = "Dell Inc. G3 3590",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
+		},
+		.driver_data = &g_series_features,
+	},
+	{
+		.ident = "Dell Inc. G5 5500",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
+		},
+		.driver_data = &g_series_features,
+	},
+};
+
+static const enum platform_profile_option wmax_mode_to_platform_profile[THERMAL_MODE_LAST] = {
+	[THERMAL_MODE_USTT_BALANCED]			= PLATFORM_PROFILE_BALANCED,
+	[THERMAL_MODE_USTT_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
+	[THERMAL_MODE_USTT_COOL]			= PLATFORM_PROFILE_COOL,
+	[THERMAL_MODE_USTT_QUIET]			= PLATFORM_PROFILE_QUIET,
+	[THERMAL_MODE_USTT_PERFORMANCE]			= PLATFORM_PROFILE_PERFORMANCE,
+	[THERMAL_MODE_USTT_LOW_POWER]			= PLATFORM_PROFILE_LOW_POWER,
+	[THERMAL_MODE_BASIC_QUIET]			= PLATFORM_PROFILE_QUIET,
+	[THERMAL_MODE_BASIC_BALANCED]			= PLATFORM_PROFILE_BALANCED,
+	[THERMAL_MODE_BASIC_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
+	[THERMAL_MODE_BASIC_PERFORMANCE]		= PLATFORM_PROFILE_PERFORMANCE,
+};
+
+struct awcc_features *awcc;
+
+/*
+ * Thermal Profile control
+ *  - Provides thermal profile control through the Platform Profile API
+ */
+static bool is_wmax_thermal_code(u32 code)
+{
+	if (code & WMAX_SENSOR_ID_MASK)
+		return false;
+
+	if ((code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_LAST)
+		return false;
+
+	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_BASIC &&
+	    (code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_BASIC_QUIET)
+		return true;
+
+	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_USTT &&
+	    (code & WMAX_THERMAL_MODE_MASK) <= THERMAL_MODE_USTT_LOW_POWER)
+		return true;
+
+	return false;
+}
+
+static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
+				    u8 arg, u32 *out_data)
+{
+	struct wmax_u32_args in_args = {
+		.operation = operation,
+		.arg1 = arg,
+		.arg2 = 0,
+		.arg3 = 0,
+	};
+	acpi_status status;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
+				       &in_args, sizeof(in_args), out_data);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	if (*out_data == WMAX_FAILURE_CODE)
+		return -EBADRQC;
+
+	return 0;
+}
+
+static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
+{
+	struct wmax_u32_args in_args = {
+		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
+		.arg1 = profile,
+		.arg2 = 0,
+		.arg3 = 0,
+	};
+	acpi_status status;
+	u32 out_data;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
+				       &in_args, sizeof(in_args), &out_data);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	if (out_data == WMAX_FAILURE_CODE)
+		return -EBADRQC;
+
+	return 0;
+}
+
+static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
+				  u32 *out_data)
+{
+	struct wmax_u32_args in_args = {
+		.operation = operation,
+		.arg1 = 0,
+		.arg2 = 0,
+		.arg3 = 0,
+	};
+	acpi_status status;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
+				       &in_args, sizeof(in_args), out_data);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	if (*out_data == WMAX_FAILURE_CODE)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static int thermal_profile_get(struct platform_profile_handler *pprof,
+			       enum platform_profile_option *profile)
+{
+	struct awcc_priv *priv;
+	u32 out_data;
+	int ret;
+
+	priv = container_of(pprof, struct awcc_priv, pp_handler);
+
+	ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
+				       0, &out_data);
+
+	if (ret < 0)
+		return ret;
+
+	if (out_data == WMAX_THERMAL_MODE_GMODE) {
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		return 0;
+	}
+
+	if (!is_wmax_thermal_code(out_data))
+		return -ENODATA;
+
+	out_data &= WMAX_THERMAL_MODE_MASK;
+	*profile = wmax_mode_to_platform_profile[out_data];
+
+	return 0;
+}
+
+static int thermal_profile_set(struct platform_profile_handler *pprof,
+			       enum platform_profile_option profile)
+{
+	struct awcc_priv *priv;
+
+	priv = container_of(pprof, struct awcc_priv, pp_handler);
+
+	if (awcc->gmode) {
+		u32 gmode_status;
+		int ret;
+
+		ret = wmax_game_shift_status(priv->wdev,
+					     WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
+					     &gmode_status);
+
+		if (ret < 0)
+			return ret;
+
+		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
+		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
+			ret = wmax_game_shift_status(priv->wdev,
+						     WMAX_OPERATION_TOGGLE_GAME_SHIFT,
+						     &gmode_status);
+
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return wmax_thermal_control(priv->wdev,
+				    priv->supported_thermal_profiles[profile]);
+}
+
+static int create_thermal_profile(struct wmi_device *wdev)
+{
+	enum platform_profile_option profile;
+	enum wmax_thermal_mode mode;
+	struct awcc_priv *priv;
+	u8 sys_desc[4];
+	u32 first_mode;
+	u32 out_data;
+	int ret;
+
+	priv = dev_get_drvdata(&wdev->dev);
+
+	ret = wmax_thermal_information(wdev, WMAX_OPERATION_SYS_DESCRIPTION,
+				       0, (u32 *) &sys_desc);
+	if (ret < 0)
+		return ret;
+
+	first_mode = sys_desc[0] + sys_desc[1];
+
+	for (u32 i = 0; i < sys_desc[3]; i++) {
+		ret = wmax_thermal_information(wdev, WMAX_OPERATION_LIST_IDS,
+					       i + first_mode, &out_data);
+
+		if (ret == -EIO)
+			return ret;
+
+		if (ret == -EBADRQC)
+			break;
+
+		if (!is_wmax_thermal_code(out_data))
+			continue;
+
+		mode = out_data & WMAX_THERMAL_MODE_MASK;
+		profile = wmax_mode_to_platform_profile[mode];
+		priv->supported_thermal_profiles[profile] = out_data;
+
+		set_bit(profile, priv->pp_handler.choices);
+	}
+
+	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
+		return -ENODEV;
+
+	if (awcc->gmode) {
+		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
+			WMAX_THERMAL_MODE_GMODE;
+
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
+	}
+
+	priv->pp_handler.profile_get = thermal_profile_get;
+	priv->pp_handler.profile_set = thermal_profile_set;
+	priv->pp_handler.name = "alienware-wmi";
+	priv->pp_handler.dev = &wdev->dev;
+
+	return platform_profile_register(&priv->pp_handler);
+}
+
+static int alienware_awcc_setup(struct wmi_device *wdev)
+{
+	struct awcc_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(&wdev->dev, priv);
+
+	priv->wdev = wdev;
+
+	ret = create_thermal_profile(wdev);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void alienware_awcc_exit(struct wmi_device *wdev)
+{
+	struct awcc_priv *priv;
+
+	priv = dev_get_drvdata(&wdev->dev);
+
+	platform_profile_remove(&priv->pp_handler);
+}
+
+/*
+ * WMAX WMI driver
+ */
+static int wmax_wmi_update_led(struct alienfx_priv *priv,
+			       struct wmi_device *wdev, u8 location)
+{
+	struct wmax_led_args in_args = {
+		.led_mask = 1 << location,
+		.colors = priv->colors[location],
+		.state = priv->lighting_control_state,
+	};
+	acpi_status status;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
+				       &in_args, sizeof(in_args), NULL);
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	return 0;
+}
+
+static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
+				      struct wmi_device *wdev, u8 brightness)
+{
+	struct wmax_brightness_args in_args = {
+		.led_mask = 0xFF,
+		.percentage = brightness,
+	};
+	acpi_status status;
+
+	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
+				       sizeof(in_args), NULL);
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	return 0;
+}
+
+static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+	struct alienfx_platdata pdata = {
+		.wdev = wdev,
+		.ops = {
+			.upd_led = wmax_wmi_update_led,
+			.upd_brightness = wmax_wmi_update_brightness,
+		},
+	};
+	int ret = 0;
+
+	if (awcc)
+		ret = alienware_awcc_setup(wdev);
+	else
+		ret = alienware_alienfx_setup(&pdata);
+
+	return ret;
+}
+
+static void wmax_wmi_remove(struct wmi_device *wdev)
+{
+	if (awcc)
+		alienware_awcc_exit(wdev);
+	else
+		alienware_alienfx_exit(wdev);
+}
+
+static struct wmi_device_id alienware_wmax_device_id_table[] = {
+	{ WMAX_CONTROL_GUID, NULL },
+	{ },
+};
+MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
+
+static struct wmi_driver alienware_wmax_wmi_driver = {
+	.driver = {
+		.name = "alienware-wmi-wmax",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.id_table = alienware_wmax_device_id_table,
+	.probe = wmax_wmi_probe,
+	.remove = wmax_wmi_remove,
+};
+
+int __init alienware_wmax_wmi_init(void)
+{
+	const struct dmi_system_id *id;
+
+	id = dmi_first_match(awcc_dmi_table);
+	if (id)
+		awcc = id->driver_data;
+
+	if (force_platform_profile)
+		awcc = &x_series_features;
+
+	if (force_gmode)
+		awcc = &g_series_features;
+
+	return wmi_driver_register(&alienware_wmax_wmi_driver);
+}
+
+void __exit alienware_wmax_wmi_exit(void)
+{
+	wmi_driver_unregister(&alienware_wmax_wmi_driver);
+}
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 18/20] platform/x86: dell: Modify Makefile alignment
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (16 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 17/20] platform-x86: Split the alienware-wmi driver Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  4:05   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 19/20] platform/x86: Update alienware-wmi config entries Kurt Borja
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Add one more TAB to each line to support upcoming changes.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/Makefile | 48 +++++++++++++++---------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
index 03ba459f3d31..d5718ef34c48 100644
--- a/drivers/platform/x86/dell/Makefile
+++ b/drivers/platform/x86/dell/Makefile
@@ -4,27 +4,27 @@
 # Dell x86 Platform-Specific Drivers
 #
 
-obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
-alienware-wmi-objs			:= alienware-wmi-base.o
-alienware-wmi-y				+= alienware-wmi-legacy.o
-alienware-wmi-y				+= alienware-wmi-wmax.o
-obj-$(CONFIG_DCDBAS)			+= dcdbas.o
-obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
-obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
-obj-$(CONFIG_DELL_RBU)			+= dell_rbu.o
-obj-$(CONFIG_DELL_PC)			+= dell-pc.o
-obj-$(CONFIG_DELL_SMBIOS)		+= dell-smbios.o
-dell-smbios-objs			:= dell-smbios-base.o
-dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)	+= dell-smbios-wmi.o
-dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)	+= dell-smbios-smm.o
-obj-$(CONFIG_DELL_SMO8800)		+= dell-smo8800.o
-obj-$(CONFIG_DELL_SMO8800)		+= dell-lis3lv02d.o
-obj-$(CONFIG_DELL_UART_BACKLIGHT)	+= dell-uart-backlight.o
-obj-$(CONFIG_DELL_WMI)			+= dell-wmi.o
-dell-wmi-objs				:= dell-wmi-base.o
-dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)	+= dell-wmi-privacy.o
-obj-$(CONFIG_DELL_WMI_AIO)		+= dell-wmi-aio.o
-obj-$(CONFIG_DELL_WMI_DESCRIPTOR)	+= dell-wmi-descriptor.o
-obj-$(CONFIG_DELL_WMI_DDV)		+= dell-wmi-ddv.o
-obj-$(CONFIG_DELL_WMI_LED)		+= dell-wmi-led.o
-obj-$(CONFIG_DELL_WMI_SYSMAN)		+= dell-wmi-sysman/
+obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
+alienware-wmi-objs				:= alienware-wmi-base.o
+alienware-wmi-y					+= alienware-wmi-legacy.o
+alienware-wmi-y					+= alienware-wmi-wmax.o
+obj-$(CONFIG_DCDBAS)				+= dcdbas.o
+obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
+obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
+obj-$(CONFIG_DELL_RBU)				+= dell_rbu.o
+obj-$(CONFIG_DELL_PC)				+= dell-pc.o
+obj-$(CONFIG_DELL_SMBIOS)			+= dell-smbios.o
+dell-smbios-objs				:= dell-smbios-base.o
+dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)		+= dell-smbios-wmi.o
+dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)		+= dell-smbios-smm.o
+obj-$(CONFIG_DELL_SMO8800)			+= dell-smo8800.o
+obj-$(CONFIG_DELL_SMO8800)			+= dell-lis3lv02d.o
+obj-$(CONFIG_DELL_UART_BACKLIGHT)		+= dell-uart-backlight.o
+obj-$(CONFIG_DELL_WMI)				+= dell-wmi.o
+dell-wmi-objs					:= dell-wmi-base.o
+dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)		+= dell-wmi-privacy.o
+obj-$(CONFIG_DELL_WMI_AIO)			+= dell-wmi-aio.o
+obj-$(CONFIG_DELL_WMI_DESCRIPTOR)		+= dell-wmi-descriptor.o
+obj-$(CONFIG_DELL_WMI_DDV)			+= dell-wmi-ddv.o
+obj-$(CONFIG_DELL_WMI_LED)			+= dell-wmi-led.o
+obj-$(CONFIG_DELL_WMI_SYSMAN)			+= dell-wmi-sysman/
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 19/20] platform/x86: Update alienware-wmi config entries
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (17 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 18/20] platform/x86: dell: Modify Makefile alignment Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  4:08   ` Armin Wolf
  2024-12-21  5:59 ` [PATCH 20/20] alienware-wmi: Update header and module information Kurt Borja
  2024-12-22 23:06 ` [PATCH 00/20] alienware-wmi driver rework Armin Wolf
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Add config entries for each WMI driver managed by the alienware-wmi
module to be able to conditionally compile them.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/Kconfig         | 30 +++++++++++++++++++----
 drivers/platform/x86/dell/Makefile        |  4 +--
 drivers/platform/x86/dell/alienware-wmi.h | 23 +++++++++++++++++
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
index d09060aedd3f..f8a0dffcaab7 100644
--- a/drivers/platform/x86/dell/Kconfig
+++ b/drivers/platform/x86/dell/Kconfig
@@ -18,15 +18,35 @@ config ALIENWARE_WMI
 	tristate "Alienware Special feature control"
 	default m
 	depends on ACPI
+	depends on ACPI_WMI
+	depends on DMI
 	depends on LEDS_CLASS
 	depends on NEW_LEDS
-	depends on ACPI_WMI
+	help
+	 This is a driver for controlling Alienware WMI driven features.
+
+	 On legacy devices, it exposes an interface for controlling the AlienFX
+	 zones on Alienware machines that don't contain a dedicated
+	 AlienFX USB MCU such as the X51 and X51-R2.
+
+	 On newer devices, it exposes the AWCC thermal control interface through
+	 known Kernel APIs.
+
+config ALIENWARE_WMI_LEGACY
+	bool "Alienware Legacy WMI device driver"
+	default y
+	depends on ALIENWARE_WMI
+	help
+	 Legacy Alienware WMI driver with AlienFX LED control capabilities.
+
+config ALIENWARE_WMI_WMAX
+	bool "Alienware WMAX WMI device driver"
+	default y
+	depends on ALIENWARE_WMI
 	select ACPI_PLATFORM_PROFILE
 	help
-	 This is a driver for controlling Alienware BIOS driven
-	 features.  It exposes an interface for controlling the AlienFX
-	 zones on Alienware machines that don't contain a dedicated AlienFX
-	 USB MCU such as the X51 and X51-R2.
+	 Alienware WMI driver with AlienFX LED, HDMI, amplifier, deep sleep and
+	 AWCC thermal control capabilities.
 
 config DCDBAS
 	tristate "Dell Systems Management Base Driver"
diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
index d5718ef34c48..8ac9a933c770 100644
--- a/drivers/platform/x86/dell/Makefile
+++ b/drivers/platform/x86/dell/Makefile
@@ -6,8 +6,8 @@
 
 obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
 alienware-wmi-objs				:= alienware-wmi-base.o
-alienware-wmi-y					+= alienware-wmi-legacy.o
-alienware-wmi-y					+= alienware-wmi-wmax.o
+alienware-wmi-$(CONFIG_ALIENWARE_WMI_LEGACY)	+= alienware-wmi-legacy.o
+alienware-wmi-$(CONFIG_ALIENWARE_WMI_WMAX)	+= alienware-wmi-wmax.o
 obj-$(CONFIG_DCDBAS)				+= dcdbas.o
 obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
 obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
index 78ac10122155..97b52e51cd7d 100644
--- a/drivers/platform/x86/dell/alienware-wmi.h
+++ b/drivers/platform/x86/dell/alienware-wmi.h
@@ -94,10 +94,33 @@ acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
 int alienware_alienfx_setup(struct alienfx_platdata *pdata);
 void alienware_alienfx_exit(struct wmi_device *wdev);
 
+#if IS_ENABLED(CONFIG_ALIENWARE_WMI_LEGACY)
 int __init alienware_legacy_wmi_init(void);
 void __exit alienware_legacy_wmi_exit(void);
+#else
+int __init alienware_legacy_wmi_init(void)
+{
+	return 0;
+}
+
+void __exit alienware_legacy_wmi_exit(void)
+{
+}
+#endif
 
+#if IS_ENABLED(CONFIG_ALIENWARE_WMI_WMAX)
 int __init alienware_wmax_wmi_init(void);
 void __exit alienware_wmax_wmi_exit(void);
+#else
+int __init alienware_wmax_wmi_init(void)
+{
+	return 0;
+}
+
+
+void __exit alienware_wmax_wmi_exit(void)
+{
+}
+#endif
 
 #endif
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 20/20] alienware-wmi: Update header and module information
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (18 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 19/20] platform/x86: Update alienware-wmi config entries Kurt Borja
@ 2024-12-21  5:59 ` Kurt Borja
  2024-12-27  4:08   ` Armin Wolf
  2024-12-22 23:06 ` [PATCH 00/20] alienware-wmi driver rework Armin Wolf
  20 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-21  5:59 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, w_armin, hdegoede, linux-kernel,
	Dell.Client.Kernel, Kurt Borja

Update module description and add myself as a module author.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
 drivers/platform/x86/dell/alienware-wmi-base.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
index 450ba0a48004..e8ccf9b277fa 100644
--- a/drivers/platform/x86/dell/alienware-wmi-base.c
+++ b/drivers/platform/x86/dell/alienware-wmi-base.c
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * Alienware AlienFX control
+ * Alienware special feature control
  *
  * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
+ * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -15,6 +16,7 @@
 #include "alienware-wmi.h"
 
 MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
+MODULE_AUTHOR("Kurt Borja <kuurtb@gmail.com>");
 MODULE_DESCRIPTION("Alienware special feature control");
 MODULE_LICENSE("GPL");
 
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* Re: [PATCH 00/20] alienware-wmi driver rework
  2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
                   ` (19 preceding siblings ...)
  2024-12-21  5:59 ` [PATCH 20/20] alienware-wmi: Update header and module information Kurt Borja
@ 2024-12-22 23:06 ` Armin Wolf
  2024-12-25 20:25   ` Armin Wolf
  20 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-22 23:06 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:58 schrieb Kurt Borja:

> Hi :)
>
> Hopefully these series are quite complete now. Your feedback is much
> appreciated!
>
> Previous discussions:
>
> [1] https://lore.kernel.org/platform-driver-x86/6m66cuivkzhcsvpjv4nunjyddqhr42bmjdhptu4bqm6rm7fvxf@qjwove4hg6gb/
> [2] https://lore.kernel.org/platform-driver-x86/20241205002733.2183537-3-kuurtb@gmail.com/
>
> Comments
> ========
>
> Patches 14 and 20 are proposals. Feel free to NACK them.
>
> ~ Kurt

Nice work, i will take a close look at those patches tomorrow.

Thanks,
Armin Wolf

>
> ---
> Changes since RFC:
>   - Incorporated comments from Ilpo which include style and organization
>     issues
>   - Instead of splitting functionallity blocks, split WMI drivers (Due to
>     Armin's comments)
>   - Replaced most of the patches near the end because of the above change
>   - Some patches were squashed into eachother where it made sense
>   - Rebased on top of recent platform_profile changes!
>
> Kurt Borja (20):
>    alienware-wmi: Remove unnecessary check at module exit
>    alienware-wmi: Move Lighting Control State
>    alienware-wmi: Modify parse_rgb() signature
>    alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation
>    alienware-wmi: Improve rgb-zones group creation
>    alienware_wmi: Clean variable declaration in thermal methods
>    alienware-wmi: Add a state container for LED control feature
>    alienware-wmi: Add WMI Drivers
>    alienware-wmi: Add a state container for thermal control methods
>    alienware-wmi: Refactor LED control methods
>    alienware-wmi: Refactor hdmi, amplifier, deepslp methods
>    alienware-wmi: Refactor thermal control methods
>    alienware-wmi: Split DMI table
>    MAINTAINERS: Update ALIENWARE WMI DRIVER entry
>    platform/x86: Rename alienware-wmi.c
>    platform/x86: Add alienware-wmi.h
>    platform-x86: Split the alienware-wmi driver
>    platform/x86: dell: Modify Makefile alignment
>    platform/x86: Update alienware-wmi config entries
>    alienware-wmi: Update header and module information
>
>   MAINTAINERS                                   |    4 +-
>   drivers/platform/x86/dell/Kconfig             |   30 +-
>   drivers/platform/x86/dell/Makefile            |   45 +-
>   .../platform/x86/dell/alienware-wmi-base.c    |  721 ++++++++++
>   .../platform/x86/dell/alienware-wmi-legacy.c  |   89 ++
>   .../platform/x86/dell/alienware-wmi-wmax.c    |  526 +++++++
>   drivers/platform/x86/dell/alienware-wmi.c     | 1269 -----------------
>   drivers/platform/x86/dell/alienware-wmi.h     |  103 ++
>   8 files changed, 1491 insertions(+), 1296 deletions(-)
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-base.c
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-legacy.c
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-wmax.c
>   delete mode 100644 drivers/platform/x86/dell/alienware-wmi.c
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi.h
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 00/20] alienware-wmi driver rework
  2024-12-22 23:06 ` [PATCH 00/20] alienware-wmi driver rework Armin Wolf
@ 2024-12-25 20:25   ` Armin Wolf
  2024-12-25 20:36     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-25 20:25 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 23.12.24 um 00:06 schrieb Armin Wolf:

> Am 21.12.24 um 06:58 schrieb Kurt Borja:
>
>> Hi :)
>>
>> Hopefully these series are quite complete now. Your feedback is much
>> appreciated!
>>
>> Previous discussions:
>>
>> [1]
>> https://lore.kernel.org/platform-driver-x86/6m66cuivkzhcsvpjv4nunjyddqhr42bmjdhptu4bqm6rm7fvxf@qjwove4hg6gb/
>> [2]
>> https://lore.kernel.org/platform-driver-x86/20241205002733.2183537-3-kuurtb@gmail.com/
>>
>> Comments
>> ========
>>
>> Patches 14 and 20 are proposals. Feel free to NACK them.
>>
>> ~ Kurt
>
> Nice work, i will take a close look at those patches tomorrow.
>
> Thanks,
> Armin Wolf
>
It seems that i overestimated my time schedule during the Christmas holidays, sorry.
I will try to review those patches till new year.

Thanks,
Armin Wolf

>>
>> ---
>> Changes since RFC:
>>   - Incorporated comments from Ilpo which include style and organization
>>     issues
>>   - Instead of splitting functionallity blocks, split WMI drivers
>> (Due to
>>     Armin's comments)
>>   - Replaced most of the patches near the end because of the above
>> change
>>   - Some patches were squashed into eachother where it made sense
>>   - Rebased on top of recent platform_profile changes!
>>
>> Kurt Borja (20):
>>    alienware-wmi: Remove unnecessary check at module exit
>>    alienware-wmi: Move Lighting Control State
>>    alienware-wmi: Modify parse_rgb() signature
>>    alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation
>>    alienware-wmi: Improve rgb-zones group creation
>>    alienware_wmi: Clean variable declaration in thermal methods
>>    alienware-wmi: Add a state container for LED control feature
>>    alienware-wmi: Add WMI Drivers
>>    alienware-wmi: Add a state container for thermal control methods
>>    alienware-wmi: Refactor LED control methods
>>    alienware-wmi: Refactor hdmi, amplifier, deepslp methods
>>    alienware-wmi: Refactor thermal control methods
>>    alienware-wmi: Split DMI table
>>    MAINTAINERS: Update ALIENWARE WMI DRIVER entry
>>    platform/x86: Rename alienware-wmi.c
>>    platform/x86: Add alienware-wmi.h
>>    platform-x86: Split the alienware-wmi driver
>>    platform/x86: dell: Modify Makefile alignment
>>    platform/x86: Update alienware-wmi config entries
>>    alienware-wmi: Update header and module information
>>
>>   MAINTAINERS                                   |    4 +-
>>   drivers/platform/x86/dell/Kconfig             |   30 +-
>>   drivers/platform/x86/dell/Makefile            |   45 +-
>>   .../platform/x86/dell/alienware-wmi-base.c    |  721 ++++++++++
>>   .../platform/x86/dell/alienware-wmi-legacy.c  |   89 ++
>>   .../platform/x86/dell/alienware-wmi-wmax.c    |  526 +++++++
>>   drivers/platform/x86/dell/alienware-wmi.c     | 1269 -----------------
>>   drivers/platform/x86/dell/alienware-wmi.h     |  103 ++
>>   8 files changed, 1491 insertions(+), 1296 deletions(-)
>>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-base.c
>>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-legacy.c
>>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-wmax.c
>>   delete mode 100644 drivers/platform/x86/dell/alienware-wmi.c
>>   create mode 100644 drivers/platform/x86/dell/alienware-wmi.h
>>
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 00/20] alienware-wmi driver rework
  2024-12-25 20:25   ` Armin Wolf
@ 2024-12-25 20:36     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-25 20:36 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Wed, Dec 25, 2024 at 09:25:35PM +0100, Armin Wolf wrote:
> Am 23.12.24 um 00:06 schrieb Armin Wolf:
> 
> > Am 21.12.24 um 06:58 schrieb Kurt Borja:
> > 
> > > Hi :)
> > > 
> > > Hopefully these series are quite complete now. Your feedback is much
> > > appreciated!
> > > 
> > > Previous discussions:
> > > 
> > > [1]
> > > https://lore.kernel.org/platform-driver-x86/6m66cuivkzhcsvpjv4nunjyddqhr42bmjdhptu4bqm6rm7fvxf@qjwove4hg6gb/
> > > [2]
> > > https://lore.kernel.org/platform-driver-x86/20241205002733.2183537-3-kuurtb@gmail.com/
> > > 
> > > Comments
> > > ========
> > > 
> > > Patches 14 and 20 are proposals. Feel free to NACK them.
> > > 
> > > ~ Kurt
> > 
> > Nice work, i will take a close look at those patches tomorrow.
> > 
> > Thanks,
> > Armin Wolf
> > 
> It seems that i overestimated my time schedule during the Christmas holidays, sorry.
> I will try to review those patches till new year.

Thanks, no worries :) Happy holidays!

~ Kurt

> 
> Thanks,
> Armin Wolf
> 
> > > 
> > > ---
> > > Changes since RFC:
> > >   - Incorporated comments from Ilpo which include style and organization
> > >     issues
> > >   - Instead of splitting functionallity blocks, split WMI drivers
> > > (Due to
> > >     Armin's comments)
> > >   - Replaced most of the patches near the end because of the above
> > > change
> > >   - Some patches were squashed into eachother where it made sense
> > >   - Rebased on top of recent platform_profile changes!
> > > 
> > > Kurt Borja (20):
> > >    alienware-wmi: Remove unnecessary check at module exit
> > >    alienware-wmi: Move Lighting Control State
> > >    alienware-wmi: Modify parse_rgb() signature
> > >    alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation
> > >    alienware-wmi: Improve rgb-zones group creation
> > >    alienware_wmi: Clean variable declaration in thermal methods
> > >    alienware-wmi: Add a state container for LED control feature
> > >    alienware-wmi: Add WMI Drivers
> > >    alienware-wmi: Add a state container for thermal control methods
> > >    alienware-wmi: Refactor LED control methods
> > >    alienware-wmi: Refactor hdmi, amplifier, deepslp methods
> > >    alienware-wmi: Refactor thermal control methods
> > >    alienware-wmi: Split DMI table
> > >    MAINTAINERS: Update ALIENWARE WMI DRIVER entry
> > >    platform/x86: Rename alienware-wmi.c
> > >    platform/x86: Add alienware-wmi.h
> > >    platform-x86: Split the alienware-wmi driver
> > >    platform/x86: dell: Modify Makefile alignment
> > >    platform/x86: Update alienware-wmi config entries
> > >    alienware-wmi: Update header and module information
> > > 
> > >   MAINTAINERS                                   |    4 +-
> > >   drivers/platform/x86/dell/Kconfig             |   30 +-
> > >   drivers/platform/x86/dell/Makefile            |   45 +-
> > >   .../platform/x86/dell/alienware-wmi-base.c    |  721 ++++++++++
> > >   .../platform/x86/dell/alienware-wmi-legacy.c  |   89 ++
> > >   .../platform/x86/dell/alienware-wmi-wmax.c    |  526 +++++++
> > >   drivers/platform/x86/dell/alienware-wmi.c     | 1269 -----------------
> > >   drivers/platform/x86/dell/alienware-wmi.h     |  103 ++
> > >   8 files changed, 1491 insertions(+), 1296 deletions(-)
> > >   create mode 100644 drivers/platform/x86/dell/alienware-wmi-base.c
> > >   create mode 100644 drivers/platform/x86/dell/alienware-wmi-legacy.c
> > >   create mode 100644 drivers/platform/x86/dell/alienware-wmi-wmax.c
> > >   delete mode 100644 drivers/platform/x86/dell/alienware-wmi.c
> > >   create mode 100644 drivers/platform/x86/dell/alienware-wmi.h
> > > 
> > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit
  2024-12-21  5:58 ` [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit Kurt Borja
@ 2024-12-27  0:32   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  0:32 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:58 schrieb Kurt Borja:

> Module initialization fails if platform device fails to register so it's
> always not NULL at exit.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 12 +++++-------
>   1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index e95d22c7b60c..ed66720260ab 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -1257,13 +1257,11 @@ module_init(alienware_wmi_init);
>
>   static void __exit alienware_wmi_exit(void)
>   {
> -	if (platform_device) {
> -		alienware_zone_exit(platform_device);
> -		remove_hdmi(platform_device);
> -		remove_thermal_profile();
> -		platform_device_unregister(platform_device);
> -		platform_driver_unregister(&platform_driver);
> -	}
> +	alienware_zone_exit(platform_device);
> +	remove_hdmi(platform_device);
> +	remove_thermal_profile();
> +	platform_device_unregister(platform_device);
> +	platform_driver_unregister(&platform_driver);
>   }
>
>   module_exit(alienware_wmi_exit);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 02/20] alienware-wmi: Move Lighting Control State
  2024-12-21  5:58 ` [PATCH 02/20] alienware-wmi: Move Lighting Control State Kurt Borja
@ 2024-12-27  0:35   ` Armin Wolf
  2024-12-27  4:32     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  0:35 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:58 schrieb Kurt Borja:

> Place Lighting Control State logic next to other attributes of the same
> sysfs group.
>
> While at it, rename:
>
> store_control_state()	-> lighting_control_state_store()
> show_control_state()	-> lighting_control_state_show()
>
> Replace DEVICE_ATTR_RW() with DEVICE_ATTR() and do a general style
> cleanup.

I think you mixed-up DEVICE_ATTR_RW() and DEVICE_ATTR() here.
Other than that:

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 74 ++++++++++++-----------
>   1 file changed, 39 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index ed66720260ab..c5ad0f95c442 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -545,6 +545,45 @@ static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
>   	return ret ? ret : count;
>   }
>
> +/*
> + * Lighting control state device attribute (Global)
> + */
> +static ssize_t lighting_control_state_show(struct device *dev,
> +					   struct device_attribute *attr,
> +					   char *buf)
> +{
> +	if (lighting_control_state == LEGACY_BOOTING)
> +		return sysfs_emit(buf, "[booting] running suspend\n");
> +	else if (lighting_control_state == LEGACY_SUSPEND)
> +		return sysfs_emit(buf, "booting running [suspend]\n");
> +
> +	return sysfs_emit(buf, "booting [running] suspend\n");
> +}
> +
> +static ssize_t lighting_control_state_store(struct device *dev,
> +					    struct device_attribute *attr,
> +					    const char *buf, size_t count)
> +{
> +	u8 val;
> +
> +	if (strcmp(buf, "booting\n") == 0)
> +		val = LEGACY_BOOTING;
> +	else if (strcmp(buf, "suspend\n") == 0)
> +		val = LEGACY_SUSPEND;
> +	else if (interface == LEGACY)
> +		val = LEGACY_RUNNING;
> +	else
> +		val = WMAX_RUNNING;
> +
> +	lighting_control_state = val;
> +	pr_debug("alienware-wmi: updated control state to %d\n",
> +		 lighting_control_state);
> +
> +	return count;
> +}
> +
> +static DEVICE_ATTR_RW(lighting_control_state);
> +
>   /*
>    * LED Brightness (Global)
>    */
> @@ -589,41 +628,6 @@ static struct led_classdev global_led = {
>   	.name = "alienware::global_brightness",
>   };
>
> -/*
> - * Lighting control state device attribute (Global)
> - */
> -static ssize_t show_control_state(struct device *dev,
> -				  struct device_attribute *attr, char *buf)
> -{
> -	if (lighting_control_state == LEGACY_BOOTING)
> -		return sysfs_emit(buf, "[booting] running suspend\n");
> -	else if (lighting_control_state == LEGACY_SUSPEND)
> -		return sysfs_emit(buf, "booting running [suspend]\n");
> -	return sysfs_emit(buf, "booting [running] suspend\n");
> -}
> -
> -static ssize_t store_control_state(struct device *dev,
> -				   struct device_attribute *attr,
> -				   const char *buf, size_t count)
> -{
> -	long unsigned int val;
> -	if (strcmp(buf, "booting\n") == 0)
> -		val = LEGACY_BOOTING;
> -	else if (strcmp(buf, "suspend\n") == 0)
> -		val = LEGACY_SUSPEND;
> -	else if (interface == LEGACY)
> -		val = LEGACY_RUNNING;
> -	else
> -		val = WMAX_RUNNING;
> -	lighting_control_state = val;
> -	pr_debug("alienware-wmi: updated control state to %d\n",
> -		 lighting_control_state);
> -	return count;
> -}
> -
> -static DEVICE_ATTR(lighting_control_state, 0644, show_control_state,
> -		   store_control_state);
> -
>   static int alienware_zone_init(struct platform_device *dev)
>   {
>   	u8 zone;

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 03/20] alienware-wmi: Modify parse_rgb() signature
  2024-12-21  5:59 ` [PATCH 03/20] alienware-wmi: Modify parse_rgb() signature Kurt Borja
@ 2024-12-27  0:36   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  0:36 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> parse_rgb() now takes struct color_platform instead of struct
> platform_zone to support upcoming refactor.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index c5ad0f95c442..273ce9b10765 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -434,7 +434,7 @@ static u8 global_brightness;
>   /*
>    * Helpers used for zone control
>    */
> -static int parse_rgb(const char *buf, struct platform_zone *zone)
> +static int parse_rgb(const char *buf, struct color_platform *colors)
>   {
>   	long unsigned int rgb;
>   	int ret;
> @@ -454,7 +454,7 @@ static int parse_rgb(const char *buf, struct platform_zone *zone)
>   	repackager.package = rgb & 0x0f0f0f0f;
>   	pr_debug("alienware-wmi: r: %d g:%d b: %d\n",
>   		 repackager.cp.red, repackager.cp.green, repackager.cp.blue);
> -	zone->colors = repackager.cp;
> +	*colors = repackager.cp;
>   	return 0;
>   }
>
> @@ -538,7 +538,7 @@ static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
>   		pr_err("alienware-wmi: invalid target zone\n");
>   		return 1;
>   	}
> -	ret = parse_rgb(buf, target_zone);
> +	ret = parse_rgb(buf, &target_zone->colors);
>   	if (ret)
>   		return ret;
>   	ret = alienware_update_led(target_zone);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 04/20] alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation
  2024-12-21  5:59 ` [PATCH 04/20] alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation Kurt Borja
@ 2024-12-27  0:44   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  0:44 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Devices with hdmi_mux, amplifier or deepslp quirks create a sysfs group
> for each available feature. To accomplish this, helper create/remove
> functions were called on module init, but they had the following
> problems:
>
>   - Create helpers called remove helpers on failure, which in turn tried
>     to remove the sysfs group that failed to be created
>   - If group creation failed mid way, previous successfully created groups
>     were not cleaned up
>   - Module exit only removed hdmi_mux group
>
> To improve this, drop all helpers and let the platform driver manage these
> sysfs groups, while controlling visibility with their respective quirks.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 114 ++++++++--------------
>   1 file changed, 38 insertions(+), 76 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index 273ce9b10765..e010c94555e8 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -417,12 +417,6 @@ static struct platform_zone *zone_data;
>   static struct platform_profile_handler pp_handler;
>   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>
> -static struct platform_driver platform_driver = {
> -	.driver = {
> -		.name = "alienware-wmi",
> -	}
> -};
> -
>   static struct attribute_group zone_attribute_group = {
>   	.name = "rgb_zones",
>   };
> @@ -804,6 +798,12 @@ static DEVICE_ATTR(cable, S_IRUGO, show_hdmi_cable, NULL);
>   static DEVICE_ATTR(source, S_IRUGO | S_IWUSR, show_hdmi_source,
>   		   toggle_hdmi_source);
>
> +static bool hdmi_group_visible(struct kobject *kobj)
> +{
> +	return quirks->hdmi_mux;
> +}
> +DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(hdmi);
> +
>   static struct attribute *hdmi_attrs[] = {
>   	&dev_attr_cable.attr,
>   	&dev_attr_source.attr,
> @@ -812,25 +812,10 @@ static struct attribute *hdmi_attrs[] = {
>
>   static const struct attribute_group hdmi_attribute_group = {
>   	.name = "hdmi",
> +	.is_visible = SYSFS_GROUP_VISIBLE(hdmi),
>   	.attrs = hdmi_attrs,
>   };
>
> -static void remove_hdmi(struct platform_device *dev)
> -{
> -	if (quirks->hdmi_mux > 0)
> -		sysfs_remove_group(&dev->dev.kobj, &hdmi_attribute_group);
> -}
> -
> -static int create_hdmi(struct platform_device *dev)
> -{
> -	int ret;
> -
> -	ret = sysfs_create_group(&dev->dev.kobj, &hdmi_attribute_group);
> -	if (ret)
> -		remove_hdmi(dev);
> -	return ret;
> -}
> -
>   /*
>    * Alienware GFX amplifier support
>    * - Currently supports reading cable status
> @@ -859,6 +844,12 @@ static ssize_t show_amplifier_status(struct device *dev,
>
>   static DEVICE_ATTR(status, S_IRUGO, show_amplifier_status, NULL);
>
> +static bool amplifier_group_visible(struct kobject *kobj)
> +{
> +	return quirks->amplifier;
> +}
> +DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(amplifier);
> +
>   static struct attribute *amplifier_attrs[] = {
>   	&dev_attr_status.attr,
>   	NULL,
> @@ -866,25 +857,10 @@ static struct attribute *amplifier_attrs[] = {
>
>   static const struct attribute_group amplifier_attribute_group = {
>   	.name = "amplifier",
> +	.is_visible = SYSFS_GROUP_VISIBLE(amplifier),
>   	.attrs = amplifier_attrs,
>   };
>
> -static void remove_amplifier(struct platform_device *dev)
> -{
> -	if (quirks->amplifier > 0)
> -		sysfs_remove_group(&dev->dev.kobj, &amplifier_attribute_group);
> -}
> -
> -static int create_amplifier(struct platform_device *dev)
> -{
> -	int ret;
> -
> -	ret = sysfs_create_group(&dev->dev.kobj, &amplifier_attribute_group);
> -	if (ret)
> -		remove_amplifier(dev);
> -	return ret;
> -}
> -
>   /*
>    * Deep Sleep Control support
>    * - Modifies BIOS setting for deep sleep control allowing extra wakeup events
> @@ -937,6 +913,12 @@ static ssize_t toggle_deepsleep(struct device *dev,
>
>   static DEVICE_ATTR(deepsleep, S_IRUGO | S_IWUSR, show_deepsleep_status, toggle_deepsleep);
>
> +static bool deepsleep_group_visible(struct kobject *kobj)
> +{
> +	return quirks->deepslp;
> +}
> +DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(deepsleep);
> +
>   static struct attribute *deepsleep_attrs[] = {
>   	&dev_attr_deepsleep.attr,
>   	NULL,
> @@ -944,25 +926,10 @@ static struct attribute *deepsleep_attrs[] = {
>
>   static const struct attribute_group deepsleep_attribute_group = {
>   	.name = "deepsleep",
> +	.is_visible = SYSFS_GROUP_VISIBLE(deepsleep),
>   	.attrs = deepsleep_attrs,
>   };
>
> -static void remove_deepsleep(struct platform_device *dev)
> -{
> -	if (quirks->deepslp > 0)
> -		sysfs_remove_group(&dev->dev.kobj, &deepsleep_attribute_group);
> -}
> -
> -static int create_deepsleep(struct platform_device *dev)
> -{
> -	int ret;
> -
> -	ret = sysfs_create_group(&dev->dev.kobj, &deepsleep_attribute_group);
> -	if (ret)
> -		remove_deepsleep(dev);
> -	return ret;
> -}
> -
>   /*
>    * Thermal Profile control
>    *  - Provides thermal profile control through the Platform Profile API
> @@ -1172,6 +1139,23 @@ static void remove_thermal_profile(void)
>   		platform_profile_remove(&pp_handler);
>   }
>
> +/*
> + * Platform Driver
> + */
> +static const struct attribute_group *alienfx_groups[] = {
> +	&hdmi_attribute_group,
> +	&amplifier_attribute_group,
> +	&deepsleep_attribute_group,
> +	NULL
> +};
> +
> +static struct platform_driver platform_driver = {
> +	.driver = {
> +		.name = "alienware-wmi",
> +		.dev_groups = alienfx_groups,
> +	},
> +};
> +
>   static int __init alienware_wmi_init(void)
>   {
>   	int ret;
> @@ -1211,24 +1195,6 @@ static int __init alienware_wmi_init(void)
>   	if (ret)
>   		goto fail_platform_device2;
>
> -	if (quirks->hdmi_mux > 0) {
> -		ret = create_hdmi(platform_device);
> -		if (ret)
> -			goto fail_prep_hdmi;
> -	}
> -
> -	if (quirks->amplifier > 0) {
> -		ret = create_amplifier(platform_device);
> -		if (ret)
> -			goto fail_prep_amplifier;
> -	}
> -
> -	if (quirks->deepslp > 0) {
> -		ret = create_deepsleep(platform_device);
> -		if (ret)
> -			goto fail_prep_deepsleep;
> -	}
> -
>   	if (quirks->thermal) {
>   		ret = create_thermal_profile(platform_device);
>   		if (ret)
> @@ -1245,9 +1211,6 @@ static int __init alienware_wmi_init(void)
>   	alienware_zone_exit(platform_device);
>   	remove_thermal_profile();
>   fail_prep_thermal_profile:
> -fail_prep_deepsleep:
> -fail_prep_amplifier:
> -fail_prep_hdmi:
>   	platform_device_del(platform_device);
>   fail_platform_device2:
>   	platform_device_put(platform_device);
> @@ -1262,7 +1225,6 @@ module_init(alienware_wmi_init);
>   static void __exit alienware_wmi_exit(void)
>   {
>   	alienware_zone_exit(platform_device);
> -	remove_hdmi(platform_device);
>   	remove_thermal_profile();
>   	platform_device_unregister(platform_device);
>   	platform_driver_unregister(&platform_driver);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 05/20] alienware-wmi: Improve rgb-zones group creation
  2024-12-21  5:59 ` [PATCH 05/20] alienware-wmi: Improve rgb-zones " Kurt Borja
@ 2024-12-27  1:04   ` Armin Wolf
  2024-12-27  4:37     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  1:04 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Define zone_attrs statically with the use of helper macros and
> initialize the zone_attribute_group with driver's .dev_groups.
>
> Drop match_zone() and instead pass a `location` argument to previous
> show/store methods to access the correct `zone` LED state. On top of
> that rename zone_set() -> zone_store() to be more consistent with sysfs
> conventions.
>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 179 +++++++++-------------
>   1 file changed, 72 insertions(+), 107 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index e010c94555e8..a431b1fec9fb 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -376,12 +376,6 @@ struct color_platform {
>   	u8 red;
>   } __packed;
>
> -struct platform_zone {
> -	u8 location;
> -	struct device_attribute *attr;
> -	struct color_platform colors;
> -};
> -
>   struct wmax_brightness_args {
>   	u32 led_mask;
>   	u32 percentage;
> @@ -411,16 +405,10 @@ struct wmax_u32_args {
>   };
>
>   static struct platform_device *platform_device;
> -static struct device_attribute *zone_dev_attrs;
> -static struct attribute **zone_attrs;
> -static struct platform_zone *zone_data;
> +static struct color_platform colors[4];
>   static struct platform_profile_handler pp_handler;
>   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>
> -static struct attribute_group zone_attribute_group = {
> -	.name = "rgb_zones",
> -};
> -
>   static u8 interface;
>   static u8 lighting_control_state;
>   static u8 global_brightness;
> @@ -452,24 +440,10 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
>   	return 0;
>   }
>
> -static struct platform_zone *match_zone(struct device_attribute *attr)
> -{
> -	u8 zone;
> -
> -	for (zone = 0; zone < quirks->num_zones; zone++) {
> -		if ((struct device_attribute *)zone_data[zone].attr == attr) {
> -			pr_debug("alienware-wmi: matched zone location: %d\n",
> -				 zone_data[zone].location);
> -			return &zone_data[zone];
> -		}
> -	}
> -	return NULL;
> -}
> -
>   /*
>    * Individual RGB zone control
>    */
> -static int alienware_update_led(struct platform_zone *zone)
> +static int alienware_update_led(u8 location)
>   {
>   	int method_id;
>   	acpi_status status;
> @@ -478,8 +452,8 @@ static int alienware_update_led(struct platform_zone *zone)
>   	struct legacy_led_args legacy_args;
>   	struct wmax_led_args wmax_basic_args;
>   	if (interface == WMAX) {
> -		wmax_basic_args.led_mask = 1 << zone->location;
> -		wmax_basic_args.colors = zone->colors;
> +		wmax_basic_args.led_mask = 1 << location;
> +		wmax_basic_args.colors = colors[location];
>   		wmax_basic_args.state = lighting_control_state;
>   		guid = WMAX_CONTROL_GUID;
>   		method_id = WMAX_METHOD_ZONE_CONTROL;
> @@ -487,7 +461,7 @@ static int alienware_update_led(struct platform_zone *zone)
>   		input.length = sizeof(wmax_basic_args);
>   		input.pointer = &wmax_basic_args;
>   	} else {
> -		legacy_args.colors = zone->colors;
> +		legacy_args.colors = colors[location];
>   		legacy_args.brightness = global_brightness;
>   		legacy_args.state = 0;
>   		if (lighting_control_state == LEGACY_BOOTING ||
> @@ -496,7 +470,7 @@ static int alienware_update_led(struct platform_zone *zone)
>   			legacy_args.state = lighting_control_state;
>   		} else
>   			guid = LEGACY_CONTROL_GUID;
> -		method_id = zone->location + 1;
> +		method_id = location + 1;
>
>   		input.length = sizeof(legacy_args);
>   		input.pointer = &legacy_args;
> @@ -510,35 +484,54 @@ static int alienware_update_led(struct platform_zone *zone)
>   }
>
>   static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
> -			 char *buf)
> +			 char *buf, u8 location)
>   {
> -	struct platform_zone *target_zone;
> -	target_zone = match_zone(attr);
> -	if (target_zone == NULL)
> -		return sprintf(buf, "red: -1, green: -1, blue: -1\n");
>   	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
> -		       target_zone->colors.red,
> -		       target_zone->colors.green, target_zone->colors.blue);
> +		       colors[location].red, colors[location].green,
> +		       colors[location].blue);
>
>   }
>
> -static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
> -			const char *buf, size_t count)
> +static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
> +			  const char *buf, size_t count, u8 location)
>   {
> -	struct platform_zone *target_zone;
>   	int ret;
> -	target_zone = match_zone(attr);
> -	if (target_zone == NULL) {
> -		pr_err("alienware-wmi: invalid target zone\n");
> -		return 1;
> -	}
> -	ret = parse_rgb(buf, &target_zone->colors);
> +
> +	ret = parse_rgb(buf, &colors[location]);
>   	if (ret)
>   		return ret;
> -	ret = alienware_update_led(target_zone);
> +
> +	ret = alienware_update_led(location);
> +
>   	return ret ? ret : count;
>   }
>
> +#define ALIENWARE_ZONE_SHOW_FUNC(_num)					\
> +	static ssize_t zone0##_num##_show(struct device *dev,		\
> +					struct device_attribute *attr,	\
> +					char *buf)			\
> +	{								\
> +		return zone_show(dev, attr, buf, _num);			\
> +	}
> +
> +#define ALIENWARE_ZONE_STORE_FUNC(_num)					\
> +	static ssize_t zone0##_num##_store(struct device *dev,		\
> +					struct device_attribute *attr,	\
> +					const char *buf, size_t count)	\
> +	{								\
> +		return zone_store(dev, attr, buf, count, _num);		\
> +	}
> +
> +#define ALIENWARE_ZONE_ATTR(_num)					\
> +	ALIENWARE_ZONE_SHOW_FUNC(_num)					\
> +	ALIENWARE_ZONE_STORE_FUNC(_num)					\
> +	static DEVICE_ATTR_RW(zone0##_num)
> +
> +ALIENWARE_ZONE_ATTR(0);
> +ALIENWARE_ZONE_ATTR(1);
> +ALIENWARE_ZONE_ATTR(2);
> +ALIENWARE_ZONE_ATTR(3);

I know that this will result in a bit of boilerplate code, but please do not use such macros.
They have a habit of confusing static code analysis tools.

> +
>   /*
>    * Lighting control state device attribute (Global)
>    */
> @@ -578,6 +571,33 @@ static ssize_t lighting_control_state_store(struct device *dev,
>
>   static DEVICE_ATTR_RW(lighting_control_state);
>
> +static umode_t zone_attr_visible(struct kobject *kobj,
> +				 struct attribute *attr, int n)
> +{
> +	return n < quirks->num_zones + 1 ? 0644 : 0;

Where is this function used?

Thanks,
Armin Wolf

> +}
> +
> +static bool zone_group_visible(struct kobject *kobj)
> +{
> +	return quirks->num_zones > 0;
> +}
> +DEFINE_SYSFS_GROUP_VISIBLE(zone);
> +
> +static struct attribute *zone_attrs[] = {
> +	&dev_attr_lighting_control_state.attr,
> +	&dev_attr_zone00.attr,
> +	&dev_attr_zone01.attr,
> +	&dev_attr_zone02.attr,
> +	&dev_attr_zone03.attr,
> +	NULL
> +};
> +
> +static struct attribute_group zone_attribute_group = {
> +	.name = "rgb_zones",
> +	.is_visible = SYSFS_GROUP_VISIBLE(zone),
> +	.attrs = zone_attrs,
> +};
> +
>   /*
>    * LED Brightness (Global)
>    */
> @@ -606,7 +626,7 @@ static void global_led_set(struct led_classdev *led_cdev,
>   	if (interface == WMAX)
>   		ret = wmax_brightness(brightness);
>   	else
> -		ret = alienware_update_led(&zone_data[0]);
> +		ret = alienware_update_led(0);
>   	if (ret)
>   		pr_err("LED brightness update failed\n");
>   }
> @@ -624,9 +644,6 @@ static struct led_classdev global_led = {
>
>   static int alienware_zone_init(struct platform_device *dev)
>   {
> -	u8 zone;
> -	char *name;
> -
>   	if (interface == WMAX) {
>   		lighting_control_state = WMAX_RUNNING;
>   	} else if (interface == LEGACY) {
> @@ -635,65 +652,12 @@ static int alienware_zone_init(struct platform_device *dev)
>   	global_led.max_brightness = 0x0F;
>   	global_brightness = global_led.max_brightness;
>
> -	/*
> -	 *      - zone_dev_attrs num_zones + 1 is for individual zones and then
> -	 *        null terminated
> -	 *      - zone_attrs num_zones + 2 is for all attrs in zone_dev_attrs +
> -	 *        the lighting control + null terminated
> -	 *      - zone_data num_zones is for the distinct zones
> -	 */
> -	zone_dev_attrs =
> -	    kcalloc(quirks->num_zones + 1, sizeof(struct device_attribute),
> -		    GFP_KERNEL);
> -	if (!zone_dev_attrs)
> -		return -ENOMEM;
> -
> -	zone_attrs =
> -	    kcalloc(quirks->num_zones + 2, sizeof(struct attribute *),
> -		    GFP_KERNEL);
> -	if (!zone_attrs)
> -		return -ENOMEM;
> -
> -	zone_data =
> -	    kcalloc(quirks->num_zones, sizeof(struct platform_zone),
> -		    GFP_KERNEL);
> -	if (!zone_data)
> -		return -ENOMEM;
> -
> -	for (zone = 0; zone < quirks->num_zones; zone++) {
> -		name = kasprintf(GFP_KERNEL, "zone%02hhX", zone);
> -		if (name == NULL)
> -			return 1;
> -		sysfs_attr_init(&zone_dev_attrs[zone].attr);
> -		zone_dev_attrs[zone].attr.name = name;
> -		zone_dev_attrs[zone].attr.mode = 0644;
> -		zone_dev_attrs[zone].show = zone_show;
> -		zone_dev_attrs[zone].store = zone_set;
> -		zone_data[zone].location = zone;
> -		zone_attrs[zone] = &zone_dev_attrs[zone].attr;
> -		zone_data[zone].attr = &zone_dev_attrs[zone];
> -	}
> -	zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
> -	zone_attribute_group.attrs = zone_attrs;
> -
> -	led_classdev_register(&dev->dev, &global_led);
> -
> -	return sysfs_create_group(&dev->dev.kobj, &zone_attribute_group);
> +	return led_classdev_register(&dev->dev, &global_led);
>   }
>
>   static void alienware_zone_exit(struct platform_device *dev)
>   {
> -	u8 zone;
> -
> -	sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
>   	led_classdev_unregister(&global_led);
> -	if (zone_dev_attrs) {
> -		for (zone = 0; zone < quirks->num_zones; zone++)
> -			kfree(zone_dev_attrs[zone].attr.name);
> -	}
> -	kfree(zone_dev_attrs);
> -	kfree(zone_data);
> -	kfree(zone_attrs);
>   }
>
>   static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
> @@ -1143,6 +1107,7 @@ static void remove_thermal_profile(void)
>    * Platform Driver
>    */
>   static const struct attribute_group *alienfx_groups[] = {
> +	&zone_attribute_group,
>   	&hdmi_attribute_group,
>   	&amplifier_attribute_group,
>   	&deepsleep_attribute_group,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 06/20] alienware_wmi: Clean variable declaration in thermal methods
  2024-12-21  5:59 ` [PATCH 06/20] alienware_wmi: Clean variable declaration in thermal methods Kurt Borja
@ 2024-12-27  1:06   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  1:06 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Reorder variable declaration from longest to shortest.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index a431b1fec9fb..67cf376df0f5 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -923,13 +923,13 @@ static bool is_wmax_thermal_code(u32 code)
>
>   static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
>   {
> -	acpi_status status;
>   	struct wmax_u32_args in_args = {
>   		.operation = operation,
>   		.arg1 = arg,
>   		.arg2 = 0,
>   		.arg3 = 0,
>   	};
> +	acpi_status status;
>
>   	status = alienware_wmax_command(&in_args, sizeof(in_args),
>   					WMAX_METHOD_THERMAL_INFORMATION,
> @@ -946,13 +946,13 @@ static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
>
>   static int wmax_thermal_control(u8 profile)
>   {
> -	acpi_status status;
>   	struct wmax_u32_args in_args = {
>   		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
>   		.arg1 = profile,
>   		.arg2 = 0,
>   		.arg3 = 0,
>   	};
> +	acpi_status status;
>   	u32 out_data;
>
>   	status = alienware_wmax_command(&in_args, sizeof(in_args),
> @@ -970,13 +970,13 @@ static int wmax_thermal_control(u8 profile)
>
>   static int wmax_game_shift_status(u8 operation, u32 *out_data)
>   {
> -	acpi_status status;
>   	struct wmax_u32_args in_args = {
>   		.operation = operation,
>   		.arg1 = 0,
>   		.arg2 = 0,
>   		.arg3 = 0,
>   	};
> +	acpi_status status;
>
>   	status = alienware_wmax_command(&in_args, sizeof(in_args),
>   					WMAX_METHOD_GAME_SHIFT_STATUS,
> @@ -1045,11 +1045,11 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>
>   static int create_thermal_profile(struct platform_device *platform_device)
>   {
> -	u32 out_data;
> +	enum platform_profile_option profile;
> +	enum wmax_thermal_mode mode;
>   	u8 sys_desc[4];
>   	u32 first_mode;
> -	enum wmax_thermal_mode mode;
> -	enum platform_profile_option profile;
> +	u32 out_data;
>   	int ret;
>
>   	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] alienware-wmi: Add a state container for LED control feature
  2024-12-21  5:59 ` [PATCH 07/20] alienware-wmi: Add a state container for LED control feature Kurt Borja
@ 2024-12-27  1:32   ` Armin Wolf
  2024-12-27  4:39     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  1:32 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Add a state container for the "alienware-wmi" platform device and
> initialize it on the new alienfx_probe(). Migrate all LED control functions
> to use this state container.
>
> Additionally move the led_classdev registration to the platform driver
> probe and make it device managed.
>
> Drop alienware_zone_init() and alienware_zone_exit() because they are no
> longer needed.
>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 128 +++++++++++++---------
>   1 file changed, 76 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index 67cf376df0f5..4b68d64bd742 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -404,14 +404,19 @@ struct wmax_u32_args {
>   	u8 arg3;
>   };
>
> +struct alienfx_priv {
> +	struct platform_device *pdev;
> +	struct led_classdev global_led;
> +	struct color_platform colors[4];
> +	u8 global_brightness;
> +	u8 lighting_control_state;
> +};
> +
>   static struct platform_device *platform_device;
> -static struct color_platform colors[4];
>   static struct platform_profile_handler pp_handler;
>   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>
>   static u8 interface;
> -static u8 lighting_control_state;
> -static u8 global_brightness;
>
>   /*
>    * Helpers used for zone control
> @@ -443,7 +448,7 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
>   /*
>    * Individual RGB zone control
>    */
> -static int alienware_update_led(u8 location)
> +static int alienware_update_led(struct alienfx_priv *priv, u8 location)
>   {
>   	int method_id;
>   	acpi_status status;
> @@ -453,21 +458,21 @@ static int alienware_update_led(u8 location)
>   	struct wmax_led_args wmax_basic_args;
>   	if (interface == WMAX) {
>   		wmax_basic_args.led_mask = 1 << location;
> -		wmax_basic_args.colors = colors[location];
> -		wmax_basic_args.state = lighting_control_state;
> +		wmax_basic_args.colors = priv->colors[location];
> +		wmax_basic_args.state = priv->lighting_control_state;
>   		guid = WMAX_CONTROL_GUID;
>   		method_id = WMAX_METHOD_ZONE_CONTROL;
>
>   		input.length = sizeof(wmax_basic_args);
>   		input.pointer = &wmax_basic_args;
>   	} else {
> -		legacy_args.colors = colors[location];
> -		legacy_args.brightness = global_brightness;
> +		legacy_args.colors = priv->colors[location];
> +		legacy_args.brightness = priv->global_brightness;
>   		legacy_args.state = 0;
> -		if (lighting_control_state == LEGACY_BOOTING ||
> -		    lighting_control_state == LEGACY_SUSPEND) {
> +		if (priv->lighting_control_state == LEGACY_BOOTING ||
> +		    priv->lighting_control_state == LEGACY_SUSPEND) {
>   			guid = LEGACY_POWER_CONTROL_GUID;
> -			legacy_args.state = lighting_control_state;
> +			legacy_args.state = priv->lighting_control_state;
>   		} else
>   			guid = LEGACY_CONTROL_GUID;
>   		method_id = location + 1;
> @@ -486,22 +491,32 @@ static int alienware_update_led(u8 location)
>   static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
>   			 char *buf, u8 location)
>   {
> +	struct color_platform *colors;
> +	struct alienfx_priv *priv;
> +
> +	priv = dev_get_drvdata(dev);

Please use "struct color_platform *colors = dev_get_drvdata(dev);" in such cases.

> +	colors = &priv->colors[location];
> +
>   	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
> -		       colors[location].red, colors[location].green,
> -		       colors[location].blue);
> +		       colors->red, colors->green, colors->blue);
>
>   }
>
>   static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
>   			  const char *buf, size_t count, u8 location)
>   {
> +	struct color_platform *colors;
> +	struct alienfx_priv *priv;
>   	int ret;
>
> -	ret = parse_rgb(buf, &colors[location]);
> +	priv = dev_get_drvdata(dev);

Same as above.

> +	colors = &priv->colors[location];
> +
> +	ret = parse_rgb(buf, colors);
>   	if (ret)
>   		return ret;
>
> -	ret = alienware_update_led(location);
> +	ret = alienware_update_led(priv, location);
>
>   	return ret ? ret : count;
>   }
> @@ -539,9 +554,13 @@ static ssize_t lighting_control_state_show(struct device *dev,
>   					   struct device_attribute *attr,
>   					   char *buf)
>   {
> -	if (lighting_control_state == LEGACY_BOOTING)
> +	struct alienfx_priv *priv;
> +
> +	priv = dev_get_drvdata(dev);

Same as above.

> +
> +	if (priv->lighting_control_state == LEGACY_BOOTING)
>   		return sysfs_emit(buf, "[booting] running suspend\n");
> -	else if (lighting_control_state == LEGACY_SUSPEND)
> +	else if (priv->lighting_control_state == LEGACY_SUSPEND)
>   		return sysfs_emit(buf, "booting running [suspend]\n");
>
>   	return sysfs_emit(buf, "booting [running] suspend\n");
> @@ -551,8 +570,11 @@ static ssize_t lighting_control_state_store(struct device *dev,
>   					    struct device_attribute *attr,
>   					    const char *buf, size_t count)
>   {
> +	struct alienfx_priv *priv;
>   	u8 val;
>
> +	priv = dev_get_drvdata(dev);

Same as above.

> +
>   	if (strcmp(buf, "booting\n") == 0)
>   		val = LEGACY_BOOTING;
>   	else if (strcmp(buf, "suspend\n") == 0)
> @@ -562,9 +584,9 @@ static ssize_t lighting_control_state_store(struct device *dev,
>   	else
>   		val = WMAX_RUNNING;
>
> -	lighting_control_state = val;
> +	priv->lighting_control_state = val;
>   	pr_debug("alienware-wmi: updated control state to %d\n",
> -		 lighting_control_state);
> +		 priv->lighting_control_state);
>
>   	return count;
>   }
> @@ -621,43 +643,26 @@ static int wmax_brightness(int brightness)
>   static void global_led_set(struct led_classdev *led_cdev,
>   			   enum led_brightness brightness)
>   {
> +	struct alienfx_priv *priv;
>   	int ret;
> -	global_brightness = brightness;
> +
> +	priv = container_of(led_cdev, struct alienfx_priv, global_led);

Same as above, but with container_of().

> +	priv->global_brightness = brightness;
>   	if (interface == WMAX)
>   		ret = wmax_brightness(brightness);
>   	else
> -		ret = alienware_update_led(0);
> +		ret = alienware_update_led(priv, 0);
>   	if (ret)
>   		pr_err("LED brightness update failed\n");
>   }
>
>   static enum led_brightness global_led_get(struct led_classdev *led_cdev)
>   {
> -	return global_brightness;
> -}
> -
> -static struct led_classdev global_led = {
> -	.brightness_set = global_led_set,
> -	.brightness_get = global_led_get,
> -	.name = "alienware::global_brightness",
> -};
> -
> -static int alienware_zone_init(struct platform_device *dev)
> -{
> -	if (interface == WMAX) {
> -		lighting_control_state = WMAX_RUNNING;
> -	} else if (interface == LEGACY) {
> -		lighting_control_state = LEGACY_RUNNING;
> -	}
> -	global_led.max_brightness = 0x0F;
> -	global_brightness = global_led.max_brightness;
> +	struct alienfx_priv *priv;
>
> -	return led_classdev_register(&dev->dev, &global_led);
> -}
> +	priv = container_of(led_cdev, struct alienfx_priv, global_led);

Same as above.

>
> -static void alienware_zone_exit(struct platform_device *dev)
> -{
> -	led_classdev_unregister(&global_led);
> +	return priv->global_brightness;
>   }
>
>   static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
> @@ -1106,6 +1111,32 @@ static void remove_thermal_profile(void)
>   /*
>    * Platform Driver
>    */
> +static int alienfx_probe(struct platform_device *pdev)
> +{
> +	struct alienfx_priv *priv;
> +	struct led_classdev *leds;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);

Missing error handling.

> +	platform_set_drvdata(pdev, priv);
> +
> +	priv->pdev = pdev;
> +
> +	if (interface == WMAX)
> +		priv->lighting_control_state = WMAX_RUNNING;
> +	else if (interface == LEGACY)
> +		priv->lighting_control_state = LEGACY_RUNNING;
> +
> +	leds = &priv->global_led;

I do not think that "leds" has any real benefit here, please use "priv->global_led" directly.

Thanks,
Armin Wolf

> +	leds->name = "alienware::global_brightness";
> +	leds->brightness_set = global_led_set;
> +	leds->brightness_get = global_led_get;
> +	leds->max_brightness = 0x0F;
> +
> +	priv->global_brightness = priv->global_led.max_brightness;
> +
> +	return devm_led_classdev_register(&pdev->dev, &priv->global_led);
> +}
> +
>   static const struct attribute_group *alienfx_groups[] = {
>   	&zone_attribute_group,
>   	&hdmi_attribute_group,
> @@ -1119,6 +1150,7 @@ static struct platform_driver platform_driver = {
>   		.name = "alienware-wmi",
>   		.dev_groups = alienfx_groups,
>   	},
> +	.probe = alienfx_probe,
>   };
>
>   static int __init alienware_wmi_init(void)
> @@ -1166,15 +1198,8 @@ static int __init alienware_wmi_init(void)
>   			goto fail_prep_thermal_profile;
>   	}
>
> -	ret = alienware_zone_init(platform_device);
> -	if (ret)
> -		goto fail_prep_zones;
> -
>   	return 0;
>
> -fail_prep_zones:
> -	alienware_zone_exit(platform_device);
> -	remove_thermal_profile();
>   fail_prep_thermal_profile:
>   	platform_device_del(platform_device);
>   fail_platform_device2:
> @@ -1189,7 +1214,6 @@ module_init(alienware_wmi_init);
>
>   static void __exit alienware_wmi_exit(void)
>   {
> -	alienware_zone_exit(platform_device);
>   	remove_thermal_profile();
>   	platform_device_unregister(platform_device);
>   	platform_driver_unregister(&platform_driver);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 08/20] alienware-wmi: Add WMI Drivers
  2024-12-21  5:59 ` [PATCH 08/20] alienware-wmi: Add WMI Drivers Kurt Borja
@ 2024-12-27  3:21   ` Armin Wolf
  2024-12-27  4:44     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:21 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Add WMI drivers for LEGACY and WMAX devices.
>
> This involves moving platform driver and device registration to a helper
> function, which is now called from the driver's preferred WMI device
> driver probe. However this is only done if !quirks->thermal because
> newer WMAX interface doesn't support any of the features exposed by this
> device.
>
> Only one driver is registered on module initialization to prevent
> registering duplicate platform driver and device.
>
> Aditionally, create_thermal_profile() now takes wmi_device * instead of
> platform_device *.

Since the HDMI, Amplifier and deepslp groups depend on the WMAX interface i would
register them inside wmax_wmi_probe() using device_add_groups() (you might need to
rework alienware_alienfx_setup() for that).

In the end the only code shared between both drivers should be related to the LED handling.
Everything else AFAIK depends on the WMAX interface and should therefore be inside the
WMAX driver.

Thanks,
Armin Wolf

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 186 +++++++++++++++++-----
>   1 file changed, 146 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index 4b68d64bd742..f2f6842e27e6 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -15,6 +15,7 @@
>   #include <linux/platform_profile.h>
>   #include <linux/dmi.h>
>   #include <linux/leds.h>
> +#include <linux/wmi.h>
>
>   #define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
>   #define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> @@ -39,8 +40,6 @@
>   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
>   MODULE_DESCRIPTION("Alienware special feature control");
>   MODULE_LICENSE("GPL");
> -MODULE_ALIAS("wmi:" LEGACY_CONTROL_GUID);
> -MODULE_ALIAS("wmi:" WMAX_CONTROL_GUID);
>
>   static bool force_platform_profile;
>   module_param_unsafe(force_platform_profile, bool, 0);
> @@ -412,7 +411,10 @@ struct alienfx_priv {
>   	u8 lighting_control_state;
>   };
>
> -static struct platform_device *platform_device;
> +struct alienfx_platdata {
> +	struct wmi_device *wdev;
> +};
> +
>   static struct platform_profile_handler pp_handler;
>   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>
> @@ -1048,7 +1050,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>   	return wmax_thermal_control(supported_thermal_profiles[profile]);
>   }
>
> -static int create_thermal_profile(struct platform_device *platform_device)
> +static int create_thermal_profile(struct wmi_device *wdev)
>   {
>   	enum platform_profile_option profile;
>   	enum wmax_thermal_mode mode;
> @@ -1097,7 +1099,7 @@ static int create_thermal_profile(struct platform_device *platform_device)
>   	pp_handler.profile_get = thermal_profile_get;
>   	pp_handler.profile_set = thermal_profile_set;
>   	pp_handler.name = "alienware-wmi";
> -	pp_handler.dev = &platform_device->dev;
> +	pp_handler.dev = &wdev->dev;
>
>   	return platform_profile_register(&pp_handler);
>   }
> @@ -1153,19 +1155,138 @@ static struct platform_driver platform_driver = {
>   	.probe = alienfx_probe,
>   };
>
> -static int __init alienware_wmi_init(void)
> +static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
>   {
> +	struct platform_device *pdev;
>   	int ret;
>
> -	if (wmi_has_guid(LEGACY_CONTROL_GUID))
> -		interface = LEGACY;
> -	else if (wmi_has_guid(WMAX_CONTROL_GUID))
> -		interface = WMAX;
> -	else {
> -		pr_warn("alienware-wmi: No known WMI GUID found\n");
> -		return -ENODEV;
> +	ret = platform_driver_register(&platform_driver);
> +	if (ret < 0)
> +		return ret;
> +
> +	pdev = platform_device_register_data(NULL, "alienware-wmi",
> +					     PLATFORM_DEVID_NONE, pdata,
> +					     sizeof(*pdata));
> +
> +	if (IS_ERR(pdev)) {
> +		platform_driver_unregister(&platform_driver);
> +		return PTR_ERR(pdev);
>   	}
>
> +	dev_set_drvdata(&pdata->wdev->dev, pdev);
> +
> +	return 0;
> +}
> +
> +static void alienware_alienfx_exit(struct wmi_device *wdev)
> +{
> +	struct platform_device *pdev;
> +
> +	pdev = dev_get_drvdata(&wdev->dev);
> +
> +	platform_device_unregister(pdev);
> +	platform_driver_unregister(&platform_driver);
> +}
> +
> +/*
> + * Legacy WMI driver
> + */
> +static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> +	struct alienfx_platdata pdata = {
> +		.wdev = wdev,
> +	};
> +
> +	return alienware_alienfx_setup(&pdata);
> +}
> +
> +static void legacy_wmi_remove(struct wmi_device *wdev)
> +{
> +	alienware_alienfx_exit(wdev);
> +}
> +
> +static struct wmi_device_id alienware_legacy_device_id_table[] = {
> +	{ LEGACY_CONTROL_GUID, NULL },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
> +
> +static struct wmi_driver alienware_legacy_wmi_driver = {
> +	.driver = {
> +		.name = "alienware-wmi-alienfx",
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> +	},
> +	.id_table = alienware_legacy_device_id_table,
> +	.probe = legacy_wmi_probe,
> +	.remove = legacy_wmi_remove,
> +};
> +
> +static int __init alienware_legacy_wmi_init(void)
> +{
> +	return wmi_driver_register(&alienware_legacy_wmi_driver);
> +}
> +
> +static void __exit alienware_legacy_wmi_exit(void)
> +{
> +	wmi_driver_unregister(&alienware_legacy_wmi_driver);
> +}
> +
> +/*
> + * WMAX WMI driver
> + */
> +static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> +	struct alienfx_platdata pdata = {
> +		.wdev = wdev,
> +	};
> +	int ret = 0;
> +
> +	if (quirks->thermal)
> +		ret = create_thermal_profile(wdev);
> +	else
> +		ret = alienware_alienfx_setup(&pdata);
> +
> +	return ret;
> +}
> +
> +static void wmax_wmi_remove(struct wmi_device *wdev)
> +{
> +	if (quirks->thermal)
> +		remove_thermal_profile();
> +	else
> +		alienware_alienfx_exit(wdev);
> +}
> +
> +static struct wmi_device_id alienware_wmax_device_id_table[] = {
> +	{ WMAX_CONTROL_GUID, NULL },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
> +
> +static struct wmi_driver alienware_wmax_wmi_driver = {
> +	.driver = {
> +		.name = "alienware-wmi-wmax",
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> +	},
> +	.id_table = alienware_wmax_device_id_table,
> +	.probe = wmax_wmi_probe,
> +	.remove = wmax_wmi_remove,
> +};
> +
> +static int __init alienware_wmax_wmi_init(void)
> +{
> +	return wmi_driver_register(&alienware_wmax_wmi_driver);
> +}
> +
> +static void __exit alienware_wmax_wmi_exit(void)
> +{
> +	wmi_driver_unregister(&alienware_wmax_wmi_driver);
> +}
> +
> +static int __init alienware_wmi_init(void)
> +{
> +	int ret;
> +
>   	dmi_check_system(alienware_quirks);
>   	if (quirks == NULL)
>   		quirks = &quirk_unknown;
> @@ -1180,43 +1301,28 @@ static int __init alienware_wmi_init(void)
>   			pr_warn("force_gmode requires platform profile support\n");
>   	}
>
> -	ret = platform_driver_register(&platform_driver);
> -	if (ret)
> -		goto fail_platform_driver;
> -	platform_device = platform_device_alloc("alienware-wmi", PLATFORM_DEVID_NONE);
> -	if (!platform_device) {
> -		ret = -ENOMEM;
> -		goto fail_platform_device1;
> +	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
> +		interface = WMAX;
> +		ret = alienware_wmax_wmi_init();
> +	} else {
> +		interface = LEGACY;
> +		ret = alienware_legacy_wmi_init();
>   	}
> -	ret = platform_device_add(platform_device);
> -	if (ret)
> -		goto fail_platform_device2;
>
> -	if (quirks->thermal) {
> -		ret = create_thermal_profile(platform_device);
> -		if (ret)
> -			goto fail_prep_thermal_profile;
> -	}
> +	if (ret < 0)
> +		return ret;
>
>   	return 0;
> -
> -fail_prep_thermal_profile:
> -	platform_device_del(platform_device);
> -fail_platform_device2:
> -	platform_device_put(platform_device);
> -fail_platform_device1:
> -	platform_driver_unregister(&platform_driver);
> -fail_platform_driver:
> -	return ret;
>   }
>
>   module_init(alienware_wmi_init);
>
>   static void __exit alienware_wmi_exit(void)
>   {
> -	remove_thermal_profile();
> -	platform_device_unregister(platform_device);
> -	platform_driver_unregister(&platform_driver);
> +	if (interface == WMAX)
> +		alienware_wmax_wmi_exit();
> +	else
> +		alienware_legacy_wmi_exit();
>   }
>
>   module_exit(alienware_wmi_exit);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods
  2024-12-21  5:59 ` [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods Kurt Borja
@ 2024-12-27  3:26   ` Armin Wolf
  2024-12-27  4:50     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:26 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Refactor all thermal control methods to use the newly defined awcc_priv
> state container instead of global variables.
>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 71 +++++++++++++++++------
>   1 file changed, 52 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index f2f6842e27e6..c4ca141d628e 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -403,6 +403,12 @@ struct wmax_u32_args {
>   	u8 arg3;
>   };
>
> +struct awcc_priv {
> +	struct wmi_device *wdev;
> +	struct platform_profile_handler pp_handler;
> +	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> +};
> +
>   struct alienfx_priv {
>   	struct platform_device *pdev;
>   	struct led_classdev global_led;
> @@ -415,9 +421,6 @@ struct alienfx_platdata {
>   	struct wmi_device *wdev;
>   };
>
> -static struct platform_profile_handler pp_handler;
> -static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> -
>   static u8 interface;
>
>   /*
> @@ -1027,6 +1030,10 @@ static int thermal_profile_get(struct platform_profile_handler *pprof,
>   static int thermal_profile_set(struct platform_profile_handler *pprof,
>   			       enum platform_profile_option profile)
>   {
> +	struct awcc_priv *priv;
> +
> +	priv = container_of(pprof, struct awcc_priv, pp_handler);

Please merge those two statements.

> +
>   	if (quirks->gmode) {
>   		u32 gmode_status;
>   		int ret;
> @@ -1047,18 +1054,21 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>   		}
>   	}
>
> -	return wmax_thermal_control(supported_thermal_profiles[profile]);
> +	return wmax_thermal_control(priv->supported_thermal_profiles[profile]);
>   }
>
>   static int create_thermal_profile(struct wmi_device *wdev)
>   {
>   	enum platform_profile_option profile;
>   	enum wmax_thermal_mode mode;
> +	struct awcc_priv *priv;
>   	u8 sys_desc[4];
>   	u32 first_mode;
>   	u32 out_data;
>   	int ret;
>
> +	priv = dev_get_drvdata(&wdev->dev);

Same as above.

> +
>   	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
>   				       0, (u32 *) &sys_desc);
>   	if (ret < 0)
> @@ -1081,33 +1091,56 @@ static int create_thermal_profile(struct wmi_device *wdev)
>
>   		mode = out_data & WMAX_THERMAL_MODE_MASK;
>   		profile = wmax_mode_to_platform_profile[mode];
> -		supported_thermal_profiles[profile] = out_data;
> +		priv->supported_thermal_profiles[profile] = out_data;
>
> -		set_bit(profile, pp_handler.choices);
> +		set_bit(profile, priv->pp_handler.choices);
>   	}
>
> -	if (bitmap_empty(pp_handler.choices, PLATFORM_PROFILE_LAST))
> +	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
>   		return -ENODEV;
>
>   	if (quirks->gmode) {
> -		supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
> +		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
>   			WMAX_THERMAL_MODE_GMODE;
>
> -		set_bit(PLATFORM_PROFILE_PERFORMANCE, pp_handler.choices);
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
>   	}
>
> -	pp_handler.profile_get = thermal_profile_get;
> -	pp_handler.profile_set = thermal_profile_set;
> -	pp_handler.name = "alienware-wmi";
> -	pp_handler.dev = &wdev->dev;
> +	priv->pp_handler.profile_get = thermal_profile_get;
> +	priv->pp_handler.profile_set = thermal_profile_set;
> +	priv->pp_handler.name = "alienware-wmi";
> +	priv->pp_handler.dev = &wdev->dev;
>
> -	return platform_profile_register(&pp_handler);
> +	return platform_profile_register(&priv->pp_handler);
>   }
>
> -static void remove_thermal_profile(void)
> +static int alienware_awcc_setup(struct wmi_device *wdev)
>   {
> -	if (quirks->thermal)
> -		platform_profile_remove(&pp_handler);
> +	struct awcc_priv *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(&wdev->dev, priv);
> +
> +	priv->wdev = wdev;
> +
> +	ret = create_thermal_profile(wdev);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;

Just directly return the result of create_thermal_profile() here.

With those minor issues being fixed:

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

> +}
> +
> +static void alienware_awcc_exit(struct wmi_device *wdev)
> +{
> +	struct awcc_priv *priv;
> +
> +	priv = dev_get_drvdata(&wdev->dev);

Please merge both statements.

> +
> +	platform_profile_remove(&priv->pp_handler);
>   }
>
>   /*
> @@ -1242,7 +1275,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>   	int ret = 0;
>
>   	if (quirks->thermal)
> -		ret = create_thermal_profile(wdev);
> +		ret = alienware_awcc_setup(wdev);
>   	else
>   		ret = alienware_alienfx_setup(&pdata);
>
> @@ -1252,7 +1285,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>   static void wmax_wmi_remove(struct wmi_device *wdev)
>   {
>   	if (quirks->thermal)
> -		remove_thermal_profile();
> +		alienware_awcc_exit(wdev);
>   	else
>   		alienware_alienfx_exit(wdev);
>   }

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] alienware-wmi: Refactor LED control methods
  2024-12-21  5:59 ` [PATCH 10/20] alienware-wmi: Refactor LED " Kurt Borja
@ 2024-12-27  3:41   ` Armin Wolf
  2024-12-27  4:52     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:41 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Both WMI devices handled by this module specify a distinct interface for
> LED control. Previously this module handled this by dynamically adapting
> arguments passed to wmi_evaluate_method() based on the `interface`
> global variable.
>
> To avoid the use of global variables, and enable the migration to
> non-deprecated WMI methods, let the WMI drivers define upd_led and
> upd_brightness operations, which completely replace
> alienware_update_led() and wmax_brightness().
>
> Also define alienware_wmi_command(), which serves as a wrapper for
> wmidev_evaluate_method(). This new method is very similar to
> alienware_wmax_command() but is WMI device agnostic.
>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 180 ++++++++++++++--------
>   1 file changed, 118 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index c4ca141d628e..bcf3b2f80dfd 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -417,12 +417,46 @@ struct alienfx_priv {
>   	u8 lighting_control_state;
>   };
>
> +struct alienfx_ops {
> +	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
> +		       u8 location);
> +	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
> +			      u8 brightness);
> +};
> +
>   struct alienfx_platdata {
>   	struct wmi_device *wdev;
> +	struct alienfx_ops ops;
>   };
>
>   static u8 interface;
>
> +static acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> +					 void *in_args, size_t in_size, u32 *out_data)

Please return a errno here instead of acpi_status.

> +{
> +	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
> +	struct acpi_buffer in = {in_size, in_args};
> +	union acpi_object *obj;
> +	acpi_status ret;
> +
> +	if (out_data) {
> +		ret = wmidev_evaluate_method(wdev, 0, method_id, &in, &out);
> +		if (ACPI_FAILURE(ret))
> +			goto out_free_ptr;

Just return -EIO here as out.pointer will contain no valid data in this case.

> +
> +		obj = (union acpi_object *)out.pointer;

Unnecessary cast.

> +
> +		if (obj && obj->type == ACPI_TYPE_INTEGER)
> +			*out_data = (u32)obj->integer.value;

Please move the code for freeing "obj" to this line.

> +	} else {
> +		ret = wmidev_evaluate_method(wdev, 0, method_id, &in, NULL);
> +	}
> +
> +out_free_ptr:
> +	kfree(out.pointer);
> +	return ret;
> +}
> +
>   /*
>    * Helpers used for zone control
>    */
> @@ -453,46 +487,6 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
>   /*
>    * Individual RGB zone control
>    */
> -static int alienware_update_led(struct alienfx_priv *priv, u8 location)
> -{
> -	int method_id;
> -	acpi_status status;
> -	char *guid;
> -	struct acpi_buffer input;
> -	struct legacy_led_args legacy_args;
> -	struct wmax_led_args wmax_basic_args;
> -	if (interface == WMAX) {
> -		wmax_basic_args.led_mask = 1 << location;
> -		wmax_basic_args.colors = priv->colors[location];
> -		wmax_basic_args.state = priv->lighting_control_state;
> -		guid = WMAX_CONTROL_GUID;
> -		method_id = WMAX_METHOD_ZONE_CONTROL;
> -
> -		input.length = sizeof(wmax_basic_args);
> -		input.pointer = &wmax_basic_args;
> -	} else {
> -		legacy_args.colors = priv->colors[location];
> -		legacy_args.brightness = priv->global_brightness;
> -		legacy_args.state = 0;
> -		if (priv->lighting_control_state == LEGACY_BOOTING ||
> -		    priv->lighting_control_state == LEGACY_SUSPEND) {
> -			guid = LEGACY_POWER_CONTROL_GUID;
> -			legacy_args.state = priv->lighting_control_state;
> -		} else
> -			guid = LEGACY_CONTROL_GUID;
> -		method_id = location + 1;
> -
> -		input.length = sizeof(legacy_args);
> -		input.pointer = &legacy_args;
> -	}
> -	pr_debug("alienware-wmi: guid %s method %d\n", guid, method_id);
> -
> -	status = wmi_evaluate_method(guid, 0, method_id, &input, NULL);
> -	if (ACPI_FAILURE(status))
> -		pr_err("alienware-wmi: zone set failure: %u\n", status);
> -	return ACPI_FAILURE(status);
> -}
> -
>   static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
>   			 char *buf, u8 location)
>   {
> @@ -510,18 +504,20 @@ static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
>   static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
>   			  const char *buf, size_t count, u8 location)
>   {
> +	struct alienfx_platdata *pdata;
>   	struct color_platform *colors;
>   	struct alienfx_priv *priv;
>   	int ret;
>
>   	priv = dev_get_drvdata(dev);
> +	pdata = dev_get_platdata(dev);
>   	colors = &priv->colors[location];
>
>   	ret = parse_rgb(buf, colors);
>   	if (ret)
>   		return ret;
>
> -	ret = alienware_update_led(priv, location);
> +	ret = pdata->ops.upd_led(priv, pdata->wdev, location);
>
>   	return ret ? ret : count;
>   }
> @@ -628,35 +624,19 @@ static struct attribute_group zone_attribute_group = {
>   /*
>    * LED Brightness (Global)
>    */
> -static int wmax_brightness(int brightness)
> -{
> -	acpi_status status;
> -	struct acpi_buffer input;
> -	struct wmax_brightness_args args = {
> -		.led_mask = 0xFF,
> -		.percentage = brightness,
> -	};
> -	input.length = sizeof(args);
> -	input.pointer = &args;
> -	status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
> -				     WMAX_METHOD_BRIGHTNESS, &input, NULL);
> -	if (ACPI_FAILURE(status))
> -		pr_err("alienware-wmi: brightness set failure: %u\n", status);
> -	return ACPI_FAILURE(status);
> -}
> -
>   static void global_led_set(struct led_classdev *led_cdev,
>   			   enum led_brightness brightness)
>   {
> +	struct alienfx_platdata *pdata;
>   	struct alienfx_priv *priv;
>   	int ret;
>
>   	priv = container_of(led_cdev, struct alienfx_priv, global_led);
> +	pdata = dev_get_platdata(&priv->pdev->dev);
> +
>   	priv->global_brightness = brightness;
> -	if (interface == WMAX)
> -		ret = wmax_brightness(brightness);
> -	else
> -		ret = alienware_update_led(priv, 0);
> +
> +	ret = pdata->ops.upd_brightness(priv, pdata->wdev, brightness);
>   	if (ret)
>   		pr_err("LED brightness update failed\n");
>   }
> @@ -1224,10 +1204,47 @@ static void alienware_alienfx_exit(struct wmi_device *wdev)
>   /*
>    * Legacy WMI driver
>    */
> +static int legacy_wmi_update_led(struct alienfx_priv *priv,
> +				 struct wmi_device *wdev, u8 location)
> +{
> +	struct legacy_led_args legacy_args;
> +	struct acpi_buffer input;
> +	acpi_status status;
> +
> +	legacy_args.colors = priv->colors[location];
> +	legacy_args.brightness = priv->global_brightness;
> +	legacy_args.state = priv->lighting_control_state;

The original code set "legacy_args.state" to "0" if "priv->lighting_control_state" was "LEGACY_RUNNING".
Please keep this behavior.

Thanks,
Armin Wolf

> +
> +	input.length = sizeof(legacy_args);
> +	input.pointer = &legacy_args;
> +
> +	if (legacy_args.state == LEGACY_RUNNING)
> +		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
> +					       sizeof(legacy_args), NULL);
> +	else
> +		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
> +					     location + 1, &input, NULL);
> +
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
> +					struct wmi_device *wdev, u8 brightness)
> +{
> +	return legacy_wmi_update_led(priv, wdev, 0);
> +}
> +
>   static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
>   {
>   	struct alienfx_platdata pdata = {
>   		.wdev = wdev,
> +		.ops = {
> +			.upd_led = legacy_wmi_update_led,
> +			.upd_brightness = legacy_wmi_update_brightness,
> +		},
>   	};
>
>   	return alienware_alienfx_setup(&pdata);
> @@ -1267,10 +1284,49 @@ static void __exit alienware_legacy_wmi_exit(void)
>   /*
>    * WMAX WMI driver
>    */
> +static int wmax_wmi_update_led(struct alienfx_priv *priv,
> +			       struct wmi_device *wdev, u8 location)
> +{
> +	struct wmax_led_args in_args = {
> +		.led_mask = 1 << location,
> +		.colors = priv->colors[location],
> +		.state = priv->lighting_control_state,
> +	};
> +	acpi_status status;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
> +				       &in_args, sizeof(in_args), NULL);
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
> +				      struct wmi_device *wdev, u8 brightness)
> +{
> +	struct wmax_brightness_args in_args = {
> +		.led_mask = 0xFF,
> +		.percentage = brightness,
> +	};
> +	acpi_status status;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
> +				       sizeof(in_args), NULL);
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
>   static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>   {
>   	struct alienfx_platdata pdata = {
>   		.wdev = wdev,
> +		.ops = {
> +			.upd_led = wmax_wmi_update_led,
> +			.upd_brightness = wmax_wmi_update_brightness,
> +		},
>   	};
>   	int ret = 0;
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 11/20] alienware-wmi: Refactor hdmi, amplifier, deepslp methods
  2024-12-21  5:59 ` [PATCH 11/20] alienware-wmi: Refactor hdmi, amplifier, deepslp methods Kurt Borja
@ 2024-12-27  3:43   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:43 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Refactor show/store methods for hdmi, amplifier, deepslp sysfs groups to
> use alienware_wmi_command() instead of alienware_wmax_command() which
> uses deprecated WMI methods.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 51 ++++++++++++++++-------
>   1 file changed, 36 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index bcf3b2f80dfd..b9da5fe657a9 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -685,14 +685,18 @@ static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
>   static ssize_t show_hdmi_cable(struct device *dev,
>   			       struct device_attribute *attr, char *buf)
>   {
> +	struct alienfx_platdata *pdata;
>   	acpi_status status;
>   	u32 out_data;
>   	struct wmax_basic_args in_args = {
>   		.arg = 0,
>   	};
> -	status =
> -	    alienware_wmax_command(&in_args, sizeof(in_args),
> -				   WMAX_METHOD_HDMI_CABLE, &out_data);
> +
> +	pdata = dev_get_platdata(dev);
> +
> +	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_CABLE,
> +				       &in_args, sizeof(in_args), &out_data);
> +
>   	if (ACPI_SUCCESS(status)) {
>   		if (out_data == 0)
>   			return sysfs_emit(buf, "[unconnected] connected unknown\n");
> @@ -706,14 +710,17 @@ static ssize_t show_hdmi_cable(struct device *dev,
>   static ssize_t show_hdmi_source(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
> +	struct alienfx_platdata *pdata;
>   	acpi_status status;
>   	u32 out_data;
>   	struct wmax_basic_args in_args = {
>   		.arg = 0,
>   	};
> -	status =
> -	    alienware_wmax_command(&in_args, sizeof(in_args),
> -				   WMAX_METHOD_HDMI_STATUS, &out_data);
> +
> +	pdata = dev_get_platdata(dev);
> +
> +	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_STATUS,
> +				       &in_args, sizeof(in_args), &out_data);
>
>   	if (ACPI_SUCCESS(status)) {
>   		if (out_data == 1)
> @@ -729,8 +736,12 @@ static ssize_t toggle_hdmi_source(struct device *dev,
>   				  struct device_attribute *attr,
>   				  const char *buf, size_t count)
>   {
> +	struct alienfx_platdata *pdata;
>   	acpi_status status;
>   	struct wmax_basic_args args;
> +
> +	pdata = dev_get_platdata(dev);
> +
>   	if (strcmp(buf, "gpu\n") == 0)
>   		args.arg = 1;
>   	else if (strcmp(buf, "input\n") == 0)
> @@ -739,8 +750,8 @@ static ssize_t toggle_hdmi_source(struct device *dev,
>   		args.arg = 3;
>   	pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf);
>
> -	status = alienware_wmax_command(&args, sizeof(args),
> -					WMAX_METHOD_HDMI_SOURCE, NULL);
> +	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_SOURCE,
> +				       &args, sizeof(args), NULL);
>
>   	if (ACPI_FAILURE(status))
>   		pr_err("alienware-wmi: HDMI toggle failed: results: %u\n",
> @@ -778,14 +789,17 @@ static const struct attribute_group hdmi_attribute_group = {
>   static ssize_t show_amplifier_status(struct device *dev,
>   				     struct device_attribute *attr, char *buf)
>   {
> +	struct alienfx_platdata *pdata;
>   	acpi_status status;
>   	u32 out_data;
>   	struct wmax_basic_args in_args = {
>   		.arg = 0,
>   	};
> -	status =
> -	    alienware_wmax_command(&in_args, sizeof(in_args),
> -				   WMAX_METHOD_AMPLIFIER_CABLE, &out_data);
> +
> +	pdata = dev_get_platdata(dev);
> +
> +	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_AMPLIFIER_CABLE,
> +				       &in_args, sizeof(in_args), &out_data);
>   	if (ACPI_SUCCESS(status)) {
>   		if (out_data == 0)
>   			return sysfs_emit(buf, "[unconnected] connected unknown\n");
> @@ -822,13 +836,17 @@ static const struct attribute_group amplifier_attribute_group = {
>   static ssize_t show_deepsleep_status(struct device *dev,
>   				     struct device_attribute *attr, char *buf)
>   {
> +	struct alienfx_platdata *pdata;
>   	acpi_status status;
>   	u32 out_data;
>   	struct wmax_basic_args in_args = {
>   		.arg = 0,
>   	};
> -	status = alienware_wmax_command(&in_args, sizeof(in_args),
> -					WMAX_METHOD_DEEP_SLEEP_STATUS, &out_data);
> +
> +	pdata = dev_get_platdata(dev);
> +
> +	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_STATUS,
> +				       &in_args, sizeof(in_args), &out_data);
>   	if (ACPI_SUCCESS(status)) {
>   		if (out_data == 0)
>   			return sysfs_emit(buf, "[disabled] s5 s5_s4\n");
> @@ -845,9 +863,12 @@ static ssize_t toggle_deepsleep(struct device *dev,
>   				struct device_attribute *attr,
>   				const char *buf, size_t count)
>   {
> +	struct alienfx_platdata *pdata;
>   	acpi_status status;
>   	struct wmax_basic_args args;
>
> +	pdata = dev_get_platdata(dev);
> +
>   	if (strcmp(buf, "disabled\n") == 0)
>   		args.arg = 0;
>   	else if (strcmp(buf, "s5\n") == 0)
> @@ -856,8 +877,8 @@ static ssize_t toggle_deepsleep(struct device *dev,
>   		args.arg = 2;
>   	pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf);
>
> -	status = alienware_wmax_command(&args, sizeof(args),
> -					WMAX_METHOD_DEEP_SLEEP_CONTROL, NULL);
> +	status = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_CONTROL,
> +				       &args, sizeof(args), NULL);
>
>   	if (ACPI_FAILURE(status))
>   		pr_err("alienware-wmi: deep sleep control failed: results: %u\n",

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 12/20] alienware-wmi: Refactor thermal control methods
  2024-12-21  5:59 ` [PATCH 12/20] alienware-wmi: Refactor thermal control methods Kurt Borja
@ 2024-12-27  3:45   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:45 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Refactor thermal control methods to use alienware_wmi_command() instead
> of alienware_wmax_command().
>
> Drop alienware_wmax_command() as there is no more users left.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 69 ++++++++---------------
>   1 file changed, 23 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index b9da5fe657a9..0a0b72dc61ea 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -650,34 +650,6 @@ static enum led_brightness global_led_get(struct led_classdev *led_cdev)
>   	return priv->global_brightness;
>   }
>
> -static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
> -					  u32 command, u32 *out_data)
> -{
> -	acpi_status status;
> -	union acpi_object *obj;
> -	struct acpi_buffer input;
> -	struct acpi_buffer output;
> -
> -	input.length = in_size;
> -	input.pointer = in_args;
> -	if (out_data) {
> -		output.length = ACPI_ALLOCATE_BUFFER;
> -		output.pointer = NULL;
> -		status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
> -					     command, &input, &output);
> -		if (ACPI_SUCCESS(status)) {
> -			obj = (union acpi_object *)output.pointer;
> -			if (obj && obj->type == ACPI_TYPE_INTEGER)
> -				*out_data = (u32)obj->integer.value;
> -		}
> -		kfree(output.pointer);
> -	} else {
> -		status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
> -					     command, &input, NULL);
> -	}
> -	return status;
> -}
> -
>   /*
>    *	The HDMI mux sysfs node indicates the status of the HDMI input mux.
>    *	It can toggle between standard system GPU output and HDMI input.
> @@ -932,7 +904,8 @@ static bool is_wmax_thermal_code(u32 code)
>   	return false;
>   }
>
> -static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
> +static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
> +				    u8 arg, u32 *out_data)
>   {
>   	struct wmax_u32_args in_args = {
>   		.operation = operation,
> @@ -942,9 +915,8 @@ static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
>   	};
>   	acpi_status status;
>
> -	status = alienware_wmax_command(&in_args, sizeof(in_args),
> -					WMAX_METHOD_THERMAL_INFORMATION,
> -					out_data);
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
> +				       &in_args, sizeof(in_args), out_data);
>
>   	if (ACPI_FAILURE(status))
>   		return -EIO;
> @@ -955,7 +927,7 @@ static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
>   	return 0;
>   }
>
> -static int wmax_thermal_control(u8 profile)
> +static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
>   {
>   	struct wmax_u32_args in_args = {
>   		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
> @@ -966,9 +938,8 @@ static int wmax_thermal_control(u8 profile)
>   	acpi_status status;
>   	u32 out_data;
>
> -	status = alienware_wmax_command(&in_args, sizeof(in_args),
> -					WMAX_METHOD_THERMAL_CONTROL,
> -					&out_data);
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
> +				       &in_args, sizeof(in_args), &out_data);
>
>   	if (ACPI_FAILURE(status))
>   		return -EIO;
> @@ -979,7 +950,8 @@ static int wmax_thermal_control(u8 profile)
>   	return 0;
>   }
>
> -static int wmax_game_shift_status(u8 operation, u32 *out_data)
> +static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
> +				  u32 *out_data)
>   {
>   	struct wmax_u32_args in_args = {
>   		.operation = operation,
> @@ -989,9 +961,8 @@ static int wmax_game_shift_status(u8 operation, u32 *out_data)
>   	};
>   	acpi_status status;
>
> -	status = alienware_wmax_command(&in_args, sizeof(in_args),
> -					WMAX_METHOD_GAME_SHIFT_STATUS,
> -					out_data);
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
> +				       &in_args, sizeof(in_args), out_data);
>
>   	if (ACPI_FAILURE(status))
>   		return -EIO;
> @@ -1005,10 +976,13 @@ static int wmax_game_shift_status(u8 operation, u32 *out_data)
>   static int thermal_profile_get(struct platform_profile_handler *pprof,
>   			       enum platform_profile_option *profile)
>   {
> +	struct awcc_priv *priv;
>   	u32 out_data;
>   	int ret;
>
> -	ret = wmax_thermal_information(WMAX_OPERATION_CURRENT_PROFILE,
> +	priv = container_of(pprof, struct awcc_priv, pp_handler);
> +
> +	ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
>   				       0, &out_data);
>
>   	if (ret < 0)
> @@ -1039,7 +1013,8 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>   		u32 gmode_status;
>   		int ret;
>
> -		ret = wmax_game_shift_status(WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
> +		ret = wmax_game_shift_status(priv->wdev,
> +					     WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
>   					     &gmode_status);
>
>   		if (ret < 0)
> @@ -1047,7 +1022,8 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>
>   		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
>   		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
> -			ret = wmax_game_shift_status(WMAX_OPERATION_TOGGLE_GAME_SHIFT,
> +			ret = wmax_game_shift_status(priv->wdev,
> +						     WMAX_OPERATION_TOGGLE_GAME_SHIFT,
>   						     &gmode_status);
>
>   			if (ret < 0)
> @@ -1055,7 +1031,8 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>   		}
>   	}
>
> -	return wmax_thermal_control(priv->supported_thermal_profiles[profile]);
> +	return wmax_thermal_control(priv->wdev,
> +				    priv->supported_thermal_profiles[profile]);
>   }
>
>   static int create_thermal_profile(struct wmi_device *wdev)
> @@ -1070,7 +1047,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
>
>   	priv = dev_get_drvdata(&wdev->dev);
>
> -	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
> +	ret = wmax_thermal_information(wdev, WMAX_OPERATION_SYS_DESCRIPTION,
>   				       0, (u32 *) &sys_desc);
>   	if (ret < 0)
>   		return ret;
> @@ -1078,7 +1055,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
>   	first_mode = sys_desc[0] + sys_desc[1];
>
>   	for (u32 i = 0; i < sys_desc[3]; i++) {
> -		ret = wmax_thermal_information(WMAX_OPERATION_LIST_IDS,
> +		ret = wmax_thermal_information(wdev, WMAX_OPERATION_LIST_IDS,
>   					       i + first_mode, &out_data);
>
>   		if (ret == -EIO)

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] alienware-wmi: Split DMI table
  2024-12-21  5:59 ` [PATCH 13/20] alienware-wmi: Split DMI table Kurt Borja
@ 2024-12-27  3:55   ` Armin Wolf
  2024-12-27  4:55     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:55 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Split thermal features into a new DMI table to support upcoming file
> split.

Could it be that you also decided to reorder the quirk entries?

Thanks,
Armin WOlf

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi.c | 163 +++++++++-------------
>   1 file changed, 69 insertions(+), 94 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> index 0a0b72dc61ea..8ea08f5f8810 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.c
> +++ b/drivers/platform/x86/dell/alienware-wmi.c
> @@ -118,8 +118,6 @@ struct quirk_entry {
>   	u8 hdmi_mux;
>   	u8 amplifier;
>   	u8 deepslp;
> -	bool thermal;
> -	bool gmode;
>   };
>
>   static struct quirk_entry *quirks;
> @@ -130,8 +128,6 @@ static struct quirk_entry quirk_inspiron5675 = {
>   	.hdmi_mux = 0,
>   	.amplifier = 0,
>   	.deepslp = 0,
> -	.thermal = false,
> -	.gmode = false,
>   };
>
>   static struct quirk_entry quirk_unknown = {
> @@ -139,8 +135,6 @@ static struct quirk_entry quirk_unknown = {
>   	.hdmi_mux = 0,
>   	.amplifier = 0,
>   	.deepslp = 0,
> -	.thermal = false,
> -	.gmode = false,
>   };
>
>   static struct quirk_entry quirk_x51_r1_r2 = {
> @@ -148,8 +142,6 @@ static struct quirk_entry quirk_x51_r1_r2 = {
>   	.hdmi_mux = 0,
>   	.amplifier = 0,
>   	.deepslp = 0,
> -	.thermal = false,
> -	.gmode = false,
>   };
>
>   static struct quirk_entry quirk_x51_r3 = {
> @@ -157,8 +149,6 @@ static struct quirk_entry quirk_x51_r3 = {
>   	.hdmi_mux = 0,
>   	.amplifier = 1,
>   	.deepslp = 0,
> -	.thermal = false,
> -	.gmode = false,
>   };
>
>   static struct quirk_entry quirk_asm100 = {
> @@ -166,8 +156,6 @@ static struct quirk_entry quirk_asm100 = {
>   	.hdmi_mux = 1,
>   	.amplifier = 0,
>   	.deepslp = 0,
> -	.thermal = false,
> -	.gmode = false,
>   };
>
>   static struct quirk_entry quirk_asm200 = {
> @@ -175,8 +163,6 @@ static struct quirk_entry quirk_asm200 = {
>   	.hdmi_mux = 1,
>   	.amplifier = 0,
>   	.deepslp = 1,
> -	.thermal = false,
> -	.gmode = false,
>   };
>
>   static struct quirk_entry quirk_asm201 = {
> @@ -184,26 +170,6 @@ static struct quirk_entry quirk_asm201 = {
>   	.hdmi_mux = 1,
>   	.amplifier = 1,
>   	.deepslp = 1,
> -	.thermal = false,
> -	.gmode = false,
> -};
> -
> -static struct quirk_entry quirk_g_series = {
> -	.num_zones = 2,
> -	.hdmi_mux = 0,
> -	.amplifier = 0,
> -	.deepslp = 0,
> -	.thermal = true,
> -	.gmode = true,
> -};
> -
> -static struct quirk_entry quirk_x_series = {
> -	.num_zones = 2,
> -	.hdmi_mux = 0,
> -	.amplifier = 0,
> -	.deepslp = 0,
> -	.thermal = true,
> -	.gmode = false,
>   };
>
>   static int __init dmi_matched(const struct dmi_system_id *dmi)
> @@ -242,133 +208,140 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
>   	},
>   	{
>   		.callback = dmi_matched,
> -		.ident = "Alienware m17 R5",
> +		.ident = "Alienware X51 R1",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
>   		},
> -		.driver_data = &quirk_x_series,
> +		.driver_data = &quirk_x51_r1_r2,
>   	},
>   	{
>   		.callback = dmi_matched,
> -		.ident = "Alienware m18 R2",
> +		.ident = "Alienware X51 R2",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
>   		},
> -		.driver_data = &quirk_x_series,
> +		.driver_data = &quirk_x51_r1_r2,
>   	},
>   	{
>   		.callback = dmi_matched,
> -		.ident = "Alienware x15 R1",
> +		.ident = "Alienware X51 R3",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
>   		},
> -		.driver_data = &quirk_x_series,
> +		.driver_data = &quirk_x51_r3,
>   	},
>   	{
>   		.callback = dmi_matched,
> -		.ident = "Alienware x17 R2",
> +		.ident = "Dell Inc. Inspiron 5675",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
> +		},
> +		.driver_data = &quirk_inspiron5675,
> +	},
> +	{}
> +};
> +
> +struct awcc_features {
> +	bool gmode;
> +};
> +
> +static struct awcc_features g_series_features = {
> +	.gmode = true,
> +};
> +
> +static struct awcc_features x_series_features = {
> +	.gmode = false,
> +};
> +
> +static const struct dmi_system_id awcc_dmi_table[] __initconst = {
> +	{
> +		.ident = "Alienware m17 R5",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
>   		},
> -		.driver_data = &quirk_x_series,
> +		.driver_data = &x_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
> -		.ident = "Alienware X51 R1",
> +		.ident = "Alienware m18 R2",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
>   		},
> -		.driver_data = &quirk_x51_r1_r2,
> +		.driver_data = &x_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
> -		.ident = "Alienware X51 R2",
> +		.ident = "Alienware x15 R1",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
>   		},
> -		.driver_data = &quirk_x51_r1_r2,
> +		.driver_data = &x_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
> -		.ident = "Alienware X51 R3",
> +		.ident = "Alienware x17 R2",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
>   		},
> -		.driver_data = &quirk_x51_r3,
> +		.driver_data = &x_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
>   		.ident = "Dell Inc. G15 5510",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>   			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
>   		},
> -		.driver_data = &quirk_g_series,
> +		.driver_data = &g_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
>   		.ident = "Dell Inc. G15 5511",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>   			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
>   		},
> -		.driver_data = &quirk_g_series,
> +		.driver_data = &g_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
>   		.ident = "Dell Inc. G15 5515",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>   			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
>   		},
> -		.driver_data = &quirk_g_series,
> +		.driver_data = &g_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
>   		.ident = "Dell Inc. G3 3500",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>   			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
>   		},
> -		.driver_data = &quirk_g_series,
> +		.driver_data = &g_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
>   		.ident = "Dell Inc. G3 3590",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>   			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
>   		},
> -		.driver_data = &quirk_g_series,
> +		.driver_data = &g_series_features,
>   	},
>   	{
> -		.callback = dmi_matched,
>   		.ident = "Dell Inc. G5 5500",
>   		.matches = {
>   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>   			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
>   		},
> -		.driver_data = &quirk_g_series,
> -	},
> -	{
> -		.callback = dmi_matched,
> -		.ident = "Dell Inc. Inspiron 5675",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
> -		},
> -		.driver_data = &quirk_inspiron5675,
> +		.driver_data = &g_series_features,
>   	},
> -	{}
>   };
>
> +struct awcc_features *awcc;
> +
>   struct color_platform {
>   	u8 blue;
>   	u8 green;
> @@ -1009,7 +982,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>
>   	priv = container_of(pprof, struct awcc_priv, pp_handler);
>
> -	if (quirks->gmode) {
> +	if (awcc->gmode) {
>   		u32 gmode_status;
>   		int ret;
>
> @@ -1077,7 +1050,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
>   	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
>   		return -ENODEV;
>
> -	if (quirks->gmode) {
> +	if (awcc->gmode) {
>   		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
>   			WMAX_THERMAL_MODE_GMODE;
>
> @@ -1328,7 +1301,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>   	};
>   	int ret = 0;
>
> -	if (quirks->thermal)
> +	if (awcc)
>   		ret = alienware_awcc_setup(wdev);
>   	else
>   		ret = alienware_alienfx_setup(&pdata);
> @@ -1338,7 +1311,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>
>   static void wmax_wmi_remove(struct wmi_device *wdev)
>   {
> -	if (quirks->thermal)
> +	if (awcc)
>   		alienware_awcc_exit(wdev);
>   	else
>   		alienware_alienfx_exit(wdev);
> @@ -1362,6 +1335,18 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
>
>   static int __init alienware_wmax_wmi_init(void)
>   {
> +	const struct dmi_system_id *id;
> +
> +	id = dmi_first_match(awcc_dmi_table);
> +	if (id)
> +		awcc = id->driver_data;
> +
> +	if (force_platform_profile)
> +		awcc = &x_series_features;
> +
> +	if (force_gmode)
> +		awcc = &g_series_features;
> +
>   	return wmi_driver_register(&alienware_wmax_wmi_driver);
>   }
>
> @@ -1378,16 +1363,6 @@ static int __init alienware_wmi_init(void)
>   	if (quirks == NULL)
>   		quirks = &quirk_unknown;
>
> -	if (force_platform_profile)
> -		quirks->thermal = true;
> -
> -	if (force_gmode) {
> -		if (quirks->thermal)
> -			quirks->gmode = true;
> -		else
> -			pr_warn("force_gmode requires platform profile support\n");
> -	}
> -
>   	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
>   		interface = WMAX;
>   		ret = alienware_wmax_wmi_init();

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 14/20] MAINTAINERS: Update ALIENWARE WMI DRIVER entry
  2024-12-21  5:59 ` [PATCH 14/20] MAINTAINERS: Update ALIENWARE WMI DRIVER entry Kurt Borja
@ 2024-12-27  3:56   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:56 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Dell has been inactive in its maintainership role of this driver since
> around 2021. Due to this, add myself as a maintainer.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   MAINTAINERS | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3809931b9240..596c6a46478c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -784,10 +784,12 @@ F:	Documentation/admin-guide/perf/alibaba_pmu.rst
>   F:	drivers/perf/alibaba_uncore_drw_pmu.c
>
>   ALIENWARE WMI DRIVER
> +M:	Kurt Borja <kuurtb@gmail.com>
> +L:	platform-driver-x86@vger.kernel.org
>   L:	Dell.Client.Kernel@dell.com
>   S:	Maintained
>   F:	Documentation/wmi/devices/alienware-wmi.rst
> -F:	drivers/platform/x86/dell/alienware-wmi.c
> +F:	drivers/platform/x86/dell/alienware-wmi*
>
>   ALLEGRO DVT VIDEO IP CORE DRIVER
>   M:	Michael Tretter <m.tretter@pengutronix.de>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 15/20] platform/x86: Rename alienware-wmi.c
  2024-12-21  5:59 ` [PATCH 15/20] platform/x86: Rename alienware-wmi.c Kurt Borja
@ 2024-12-27  3:57   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  3:57 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Rename alienware-wmi to support upcoming split.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/Makefile                               | 1 +
>   .../platform/x86/dell/{alienware-wmi.c => alienware-wmi-base.c}  | 0
>   2 files changed, 1 insertion(+)
>   rename drivers/platform/x86/dell/{alienware-wmi.c => alienware-wmi-base.c} (100%)
>
> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> index bb3cbd470a46..f8aec8502c2f 100644
> --- a/drivers/platform/x86/dell/Makefile
> +++ b/drivers/platform/x86/dell/Makefile
> @@ -5,6 +5,7 @@
>   #
>
>   obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
> +alienware-wmi-objs			:= alienware-wmi-base.o
>   obj-$(CONFIG_DCDBAS)			+= dcdbas.o
>   obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
>   obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi-base.c
> similarity index 100%
> rename from drivers/platform/x86/dell/alienware-wmi.c
> rename to drivers/platform/x86/dell/alienware-wmi-base.c

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 16/20] platform/x86: Add alienware-wmi.h
  2024-12-21  5:59 ` [PATCH 16/20] platform/x86: Add alienware-wmi.h Kurt Borja
@ 2024-12-27  4:02   ` Armin Wolf
  2024-12-27  4:56     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  4:02 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Add a header file for alienware-wmi with shared resources to support the
> upcoming file split.

I am OK with this, but only common definitions should be moved inside this header file.
Definitions only used by a single driver should remain inside the driver file.

Thanks,
Armin Wolf

> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   .../platform/x86/dell/alienware-wmi-base.c    |  93 ++--------------
>   drivers/platform/x86/dell/alienware-wmi.h     | 103 ++++++++++++++++++
>   2 files changed, 112 insertions(+), 84 deletions(-)
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi.h
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
> index 8ea08f5f8810..e8d470bbb608 100644
> --- a/drivers/platform/x86/dell/alienware-wmi-base.c
> +++ b/drivers/platform/x86/dell/alienware-wmi-base.c
> @@ -16,26 +16,7 @@
>   #include <linux/dmi.h>
>   #include <linux/leds.h>
>   #include <linux/wmi.h>
> -
> -#define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
> -#define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> -#define WMAX_CONTROL_GUID		"A70591CE-A997-11DA-B012-B622A1EF5492"
> -
> -#define WMAX_METHOD_HDMI_SOURCE		0x1
> -#define WMAX_METHOD_HDMI_STATUS		0x2
> -#define WMAX_METHOD_BRIGHTNESS		0x3
> -#define WMAX_METHOD_ZONE_CONTROL	0x4
> -#define WMAX_METHOD_HDMI_CABLE		0x5
> -#define WMAX_METHOD_AMPLIFIER_CABLE	0x6
> -#define WMAX_METHOD_DEEP_SLEEP_CONTROL	0x0B
> -#define WMAX_METHOD_DEEP_SLEEP_STATUS	0x0C
> -#define WMAX_METHOD_THERMAL_INFORMATION	0x14
> -#define WMAX_METHOD_THERMAL_CONTROL	0x15
> -#define WMAX_METHOD_GAME_SHIFT_STATUS	0x25
> -
> -#define WMAX_THERMAL_MODE_GMODE		0xAB
> -
> -#define WMAX_FAILURE_CODE		0xFFFFFFFF
> +#include "alienware-wmi.h"
>
>   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
>   MODULE_DESCRIPTION("Alienware special feature control");
> @@ -54,18 +35,6 @@ enum INTERFACE_FLAGS {
>   	WMAX,
>   };
>
> -enum LEGACY_CONTROL_STATES {
> -	LEGACY_RUNNING = 1,
> -	LEGACY_BOOTING = 0,
> -	LEGACY_SUSPEND = 3,
> -};
> -
> -enum WMAX_CONTROL_STATES {
> -	WMAX_RUNNING = 0xFF,
> -	WMAX_BOOTING = 0,
> -	WMAX_SUSPEND = 3,
> -};
> -
>   enum WMAX_THERMAL_INFORMATION_OPERATIONS {
>   	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
>   	WMAX_OPERATION_LIST_IDS			= 0x03,
> @@ -122,7 +91,6 @@ struct quirk_entry {
>
>   static struct quirk_entry *quirks;
>
> -
>   static struct quirk_entry quirk_inspiron5675 = {
>   	.num_zones = 2,
>   	.hdmi_mux = 0,
> @@ -342,33 +310,10 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {
>
>   struct awcc_features *awcc;
>
> -struct color_platform {
> -	u8 blue;
> -	u8 green;
> -	u8 red;
> -} __packed;
> -
> -struct wmax_brightness_args {
> -	u32 led_mask;
> -	u32 percentage;
> -};
> -
>   struct wmax_basic_args {
>   	u8 arg;
>   };
>
> -struct legacy_led_args {
> -	struct color_platform colors;
> -	u8 brightness;
> -	u8 state;
> -} __packed;
> -
> -struct wmax_led_args {
> -	u32 led_mask;
> -	struct color_platform colors;
> -	u8 state;
> -} __packed;
> -
>   struct wmax_u32_args {
>   	u8 operation;
>   	u8 arg1;
> @@ -382,30 +327,10 @@ struct awcc_priv {
>   	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>   };
>
> -struct alienfx_priv {
> -	struct platform_device *pdev;
> -	struct led_classdev global_led;
> -	struct color_platform colors[4];
> -	u8 global_brightness;
> -	u8 lighting_control_state;
> -};
> -
> -struct alienfx_ops {
> -	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
> -		       u8 location);
> -	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
> -			      u8 brightness);
> -};
> -
> -struct alienfx_platdata {
> -	struct wmi_device *wdev;
> -	struct alienfx_ops ops;
> -};
> -
>   static u8 interface;
>
> -static acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> -					 void *in_args, size_t in_size, u32 *out_data)
> +acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> +				  void *in_args, size_t in_size, u32 *out_data)
>   {
>   	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
>   	struct acpi_buffer in = {in_size, in_args};
> @@ -1139,7 +1064,7 @@ static struct platform_driver platform_driver = {
>   	.probe = alienfx_probe,
>   };
>
> -static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
> +int alienware_alienfx_setup(struct alienfx_platdata *pdata)
>   {
>   	struct platform_device *pdev;
>   	int ret;
> @@ -1162,7 +1087,7 @@ static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
>   	return 0;
>   }
>
> -static void alienware_alienfx_exit(struct wmi_device *wdev)
> +void alienware_alienfx_exit(struct wmi_device *wdev)
>   {
>   	struct platform_device *pdev;
>
> @@ -1242,12 +1167,12 @@ static struct wmi_driver alienware_legacy_wmi_driver = {
>   	.remove = legacy_wmi_remove,
>   };
>
> -static int __init alienware_legacy_wmi_init(void)
> +int __init alienware_legacy_wmi_init(void)
>   {
>   	return wmi_driver_register(&alienware_legacy_wmi_driver);
>   }
>
> -static void __exit alienware_legacy_wmi_exit(void)
> +void __exit alienware_legacy_wmi_exit(void)
>   {
>   	wmi_driver_unregister(&alienware_legacy_wmi_driver);
>   }
> @@ -1333,7 +1258,7 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
>   	.remove = wmax_wmi_remove,
>   };
>
> -static int __init alienware_wmax_wmi_init(void)
> +int __init alienware_wmax_wmi_init(void)
>   {
>   	const struct dmi_system_id *id;
>
> @@ -1350,7 +1275,7 @@ static int __init alienware_wmax_wmi_init(void)
>   	return wmi_driver_register(&alienware_wmax_wmi_driver);
>   }
>
> -static void __exit alienware_wmax_wmi_exit(void)
> +void __exit alienware_wmax_wmi_exit(void)
>   {
>   	wmi_driver_unregister(&alienware_wmax_wmi_driver);
>   }
> diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
> new file mode 100644
> index 000000000000..78ac10122155
> --- /dev/null
> +++ b/drivers/platform/x86/dell/alienware-wmi.h
> @@ -0,0 +1,103 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Alienware WMI special features driver
> + *
> + * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
> + * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
> + */
> +
> +#ifndef _ALIENWARE_WMI_H_
> +#define _ALIENWARE_WMI_H_
> +
> +#include <linux/leds.h>
> +#include <linux/platform_device.h>
> +#include <linux/wmi.h>
> +
> +#define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
> +#define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> +#define WMAX_CONTROL_GUID		"A70591CE-A997-11DA-B012-B622A1EF5492"
> +
> +#define WMAX_METHOD_HDMI_SOURCE			0x1
> +#define WMAX_METHOD_HDMI_STATUS			0x2
> +#define WMAX_METHOD_BRIGHTNESS			0x3
> +#define WMAX_METHOD_ZONE_CONTROL		0x4
> +#define WMAX_METHOD_HDMI_CABLE			0x5
> +#define WMAX_METHOD_AMPLIFIER_CABLE		0x6
> +#define WMAX_METHOD_DEEP_SLEEP_CONTROL		0x0B
> +#define WMAX_METHOD_DEEP_SLEEP_STATUS		0x0C
> +#define WMAX_METHOD_THERMAL_INFORMATION		0x14
> +#define WMAX_METHOD_THERMAL_CONTROL		0x15
> +#define WMAX_METHOD_GAME_SHIFT_STATUS		0x25
> +
> +#define WMAX_THERMAL_MODE_GMODE			0xAB
> +
> +#define WMAX_FAILURE_CODE			0xFFFFFFFF
> +
> +enum LEGACY_CONTROL_STATES {
> +	LEGACY_RUNNING = 1,
> +	LEGACY_BOOTING = 0,
> +	LEGACY_SUSPEND = 3,
> +};
> +
> +enum WMAX_CONTROL_STATES {
> +	WMAX_RUNNING = 0xFF,
> +	WMAX_BOOTING = 0,
> +	WMAX_SUSPEND = 3,
> +};
> +
> +struct color_platform {
> +	u8 blue;
> +	u8 green;
> +	u8 red;
> +} __packed;
> +
> +struct wmax_brightness_args {
> +	u32 led_mask;
> +	u32 percentage;
> +};
> +
> +struct legacy_led_args {
> +	struct color_platform colors;
> +	u8 brightness;
> +	u8 state;
> +} __packed;
> +
> +struct wmax_led_args {
> +	u32 led_mask;
> +	struct color_platform colors;
> +	u8 state;
> +} __packed;
> +
> +struct alienfx_priv {
> +	struct platform_device *pdev;
> +	struct led_classdev global_led;
> +	struct color_platform colors[4];
> +	u8 global_brightness;
> +	u8 lighting_control_state;
> +};
> +
> +struct alienfx_ops {
> +	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
> +		       u8 location);
> +	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
> +			      u8 brightness);
> +};
> +
> +struct alienfx_platdata {
> +	struct wmi_device *wdev;
> +	struct alienfx_ops ops;
> +};
> +
> +acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> +				  void *in_args, size_t in_size, u32 *out_data);
> +
> +int alienware_alienfx_setup(struct alienfx_platdata *pdata);
> +void alienware_alienfx_exit(struct wmi_device *wdev);
> +
> +int __init alienware_legacy_wmi_init(void);
> +void __exit alienware_legacy_wmi_exit(void);
> +
> +int __init alienware_wmax_wmi_init(void);
> +void __exit alienware_wmax_wmi_exit(void);
> +
> +#endif

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 17/20] platform-x86: Split the alienware-wmi driver
  2024-12-21  5:59 ` [PATCH 17/20] platform-x86: Split the alienware-wmi driver Kurt Borja
@ 2024-12-27  4:04   ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  4:04 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Split alienware-wmi WMI drivers into different files. This is done
> seamlessly by copying and pasting.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/Makefile            |   2 +
>   .../platform/x86/dell/alienware-wmi-base.c    | 596 ------------------
>   .../platform/x86/dell/alienware-wmi-legacy.c  |  89 +++
>   .../platform/x86/dell/alienware-wmi-wmax.c    | 526 ++++++++++++++++
>   4 files changed, 617 insertions(+), 596 deletions(-)
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-legacy.c
>   create mode 100644 drivers/platform/x86/dell/alienware-wmi-wmax.c
>
> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> index f8aec8502c2f..03ba459f3d31 100644
> --- a/drivers/platform/x86/dell/Makefile
> +++ b/drivers/platform/x86/dell/Makefile
> @@ -6,6 +6,8 @@
>
>   obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
>   alienware-wmi-objs			:= alienware-wmi-base.o
> +alienware-wmi-y				+= alienware-wmi-legacy.o
> +alienware-wmi-y				+= alienware-wmi-wmax.o
>   obj-$(CONFIG_DCDBAS)			+= dcdbas.o
>   obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
>   obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
> diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
> index e8d470bbb608..450ba0a48004 100644
> --- a/drivers/platform/x86/dell/alienware-wmi-base.c
> +++ b/drivers/platform/x86/dell/alienware-wmi-base.c
> @@ -8,80 +8,21 @@
>   #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>
>   #include <linux/acpi.h>
> -#include <linux/bitfield.h>
> -#include <linux/bits.h>
>   #include <linux/module.h>
>   #include <linux/platform_device.h>
> -#include <linux/platform_profile.h>
>   #include <linux/dmi.h>
>   #include <linux/leds.h>
> -#include <linux/wmi.h>
>   #include "alienware-wmi.h"
>
>   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
>   MODULE_DESCRIPTION("Alienware special feature control");
>   MODULE_LICENSE("GPL");
>
> -static bool force_platform_profile;
> -module_param_unsafe(force_platform_profile, bool, 0);
> -MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
> -
> -static bool force_gmode;
> -module_param_unsafe(force_gmode, bool, 0);
> -MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
> -
>   enum INTERFACE_FLAGS {
>   	LEGACY,
>   	WMAX,
>   };
>
> -enum WMAX_THERMAL_INFORMATION_OPERATIONS {
> -	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
> -	WMAX_OPERATION_LIST_IDS			= 0x03,
> -	WMAX_OPERATION_CURRENT_PROFILE		= 0x0B,
> -};
> -
> -enum WMAX_THERMAL_CONTROL_OPERATIONS {
> -	WMAX_OPERATION_ACTIVATE_PROFILE		= 0x01,
> -};
> -
> -enum WMAX_GAME_SHIFT_STATUS_OPERATIONS {
> -	WMAX_OPERATION_TOGGLE_GAME_SHIFT	= 0x01,
> -	WMAX_OPERATION_GET_GAME_SHIFT_STATUS	= 0x02,
> -};
> -
> -enum WMAX_THERMAL_TABLES {
> -	WMAX_THERMAL_TABLE_BASIC		= 0x90,
> -	WMAX_THERMAL_TABLE_USTT			= 0xA0,
> -};
> -
> -enum wmax_thermal_mode {
> -	THERMAL_MODE_USTT_BALANCED,
> -	THERMAL_MODE_USTT_BALANCED_PERFORMANCE,
> -	THERMAL_MODE_USTT_COOL,
> -	THERMAL_MODE_USTT_QUIET,
> -	THERMAL_MODE_USTT_PERFORMANCE,
> -	THERMAL_MODE_USTT_LOW_POWER,
> -	THERMAL_MODE_BASIC_QUIET,
> -	THERMAL_MODE_BASIC_BALANCED,
> -	THERMAL_MODE_BASIC_BALANCED_PERFORMANCE,
> -	THERMAL_MODE_BASIC_PERFORMANCE,
> -	THERMAL_MODE_LAST,
> -};
> -
> -static const enum platform_profile_option wmax_mode_to_platform_profile[THERMAL_MODE_LAST] = {
> -	[THERMAL_MODE_USTT_BALANCED]			= PLATFORM_PROFILE_BALANCED,
> -	[THERMAL_MODE_USTT_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
> -	[THERMAL_MODE_USTT_COOL]			= PLATFORM_PROFILE_COOL,
> -	[THERMAL_MODE_USTT_QUIET]			= PLATFORM_PROFILE_QUIET,
> -	[THERMAL_MODE_USTT_PERFORMANCE]			= PLATFORM_PROFILE_PERFORMANCE,
> -	[THERMAL_MODE_USTT_LOW_POWER]			= PLATFORM_PROFILE_LOW_POWER,
> -	[THERMAL_MODE_BASIC_QUIET]			= PLATFORM_PROFILE_QUIET,
> -	[THERMAL_MODE_BASIC_BALANCED]			= PLATFORM_PROFILE_BALANCED,
> -	[THERMAL_MODE_BASIC_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
> -	[THERMAL_MODE_BASIC_PERFORMANCE]		= PLATFORM_PROFILE_PERFORMANCE,
> -};
> -
>   struct quirk_entry {
>   	u8 num_zones;
>   	u8 hdmi_mux;
> @@ -213,120 +154,10 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
>   	{}
>   };
>
> -struct awcc_features {
> -	bool gmode;
> -};
> -
> -static struct awcc_features g_series_features = {
> -	.gmode = true,
> -};
> -
> -static struct awcc_features x_series_features = {
> -	.gmode = false,
> -};
> -
> -static const struct dmi_system_id awcc_dmi_table[] __initconst = {
> -	{
> -		.ident = "Alienware m17 R5",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
> -		},
> -		.driver_data = &x_series_features,
> -	},
> -	{
> -		.ident = "Alienware m18 R2",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
> -		},
> -		.driver_data = &x_series_features,
> -	},
> -	{
> -		.ident = "Alienware x15 R1",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
> -		},
> -		.driver_data = &x_series_features,
> -	},
> -	{
> -		.ident = "Alienware x17 R2",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
> -		},
> -		.driver_data = &x_series_features,
> -	},
> -	{
> -		.ident = "Dell Inc. G15 5510",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
> -		},
> -		.driver_data = &g_series_features,
> -	},
> -	{
> -		.ident = "Dell Inc. G15 5511",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
> -		},
> -		.driver_data = &g_series_features,
> -	},
> -	{
> -		.ident = "Dell Inc. G15 5515",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
> -		},
> -		.driver_data = &g_series_features,
> -	},
> -	{
> -		.ident = "Dell Inc. G3 3500",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
> -		},
> -		.driver_data = &g_series_features,
> -	},
> -	{
> -		.ident = "Dell Inc. G3 3590",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
> -		},
> -		.driver_data = &g_series_features,
> -	},
> -	{
> -		.ident = "Dell Inc. G5 5500",
> -		.matches = {
> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> -			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
> -		},
> -		.driver_data = &g_series_features,
> -	},
> -};
> -
> -struct awcc_features *awcc;
> -
>   struct wmax_basic_args {
>   	u8 arg;
>   };
>
> -struct wmax_u32_args {
> -	u8 operation;
> -	u8 arg1;
> -	u8 arg2;
> -	u8 arg3;
> -};
> -
> -struct awcc_priv {
> -	struct wmi_device *wdev;
> -	struct platform_profile_handler pp_handler;
> -	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> -};
> -
>   static u8 interface;
>
>   acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> @@ -775,250 +606,6 @@ static const struct attribute_group deepsleep_attribute_group = {
>   	.attrs = deepsleep_attrs,
>   };
>
> -/*
> - * Thermal Profile control
> - *  - Provides thermal profile control through the Platform Profile API
> - */
> -#define WMAX_THERMAL_TABLE_MASK		GENMASK(7, 4)
> -#define WMAX_THERMAL_MODE_MASK		GENMASK(3, 0)
> -#define WMAX_SENSOR_ID_MASK		BIT(8)
> -
> -static bool is_wmax_thermal_code(u32 code)
> -{
> -	if (code & WMAX_SENSOR_ID_MASK)
> -		return false;
> -
> -	if ((code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_LAST)
> -		return false;
> -
> -	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_BASIC &&
> -	    (code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_BASIC_QUIET)
> -		return true;
> -
> -	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_USTT &&
> -	    (code & WMAX_THERMAL_MODE_MASK) <= THERMAL_MODE_USTT_LOW_POWER)
> -		return true;
> -
> -	return false;
> -}
> -
> -static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
> -				    u8 arg, u32 *out_data)
> -{
> -	struct wmax_u32_args in_args = {
> -		.operation = operation,
> -		.arg1 = arg,
> -		.arg2 = 0,
> -		.arg3 = 0,
> -	};
> -	acpi_status status;
> -
> -	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
> -				       &in_args, sizeof(in_args), out_data);
> -
> -	if (ACPI_FAILURE(status))
> -		return -EIO;
> -
> -	if (*out_data == WMAX_FAILURE_CODE)
> -		return -EBADRQC;
> -
> -	return 0;
> -}
> -
> -static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
> -{
> -	struct wmax_u32_args in_args = {
> -		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
> -		.arg1 = profile,
> -		.arg2 = 0,
> -		.arg3 = 0,
> -	};
> -	acpi_status status;
> -	u32 out_data;
> -
> -	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
> -				       &in_args, sizeof(in_args), &out_data);
> -
> -	if (ACPI_FAILURE(status))
> -		return -EIO;
> -
> -	if (out_data == WMAX_FAILURE_CODE)
> -		return -EBADRQC;
> -
> -	return 0;
> -}
> -
> -static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
> -				  u32 *out_data)
> -{
> -	struct wmax_u32_args in_args = {
> -		.operation = operation,
> -		.arg1 = 0,
> -		.arg2 = 0,
> -		.arg3 = 0,
> -	};
> -	acpi_status status;
> -
> -	status = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
> -				       &in_args, sizeof(in_args), out_data);
> -
> -	if (ACPI_FAILURE(status))
> -		return -EIO;
> -
> -	if (*out_data == WMAX_FAILURE_CODE)
> -		return -EOPNOTSUPP;
> -
> -	return 0;
> -}
> -
> -static int thermal_profile_get(struct platform_profile_handler *pprof,
> -			       enum platform_profile_option *profile)
> -{
> -	struct awcc_priv *priv;
> -	u32 out_data;
> -	int ret;
> -
> -	priv = container_of(pprof, struct awcc_priv, pp_handler);
> -
> -	ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
> -				       0, &out_data);
> -
> -	if (ret < 0)
> -		return ret;
> -
> -	if (out_data == WMAX_THERMAL_MODE_GMODE) {
> -		*profile = PLATFORM_PROFILE_PERFORMANCE;
> -		return 0;
> -	}
> -
> -	if (!is_wmax_thermal_code(out_data))
> -		return -ENODATA;
> -
> -	out_data &= WMAX_THERMAL_MODE_MASK;
> -	*profile = wmax_mode_to_platform_profile[out_data];
> -
> -	return 0;
> -}
> -
> -static int thermal_profile_set(struct platform_profile_handler *pprof,
> -			       enum platform_profile_option profile)
> -{
> -	struct awcc_priv *priv;
> -
> -	priv = container_of(pprof, struct awcc_priv, pp_handler);
> -
> -	if (awcc->gmode) {
> -		u32 gmode_status;
> -		int ret;
> -
> -		ret = wmax_game_shift_status(priv->wdev,
> -					     WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
> -					     &gmode_status);
> -
> -		if (ret < 0)
> -			return ret;
> -
> -		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
> -		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
> -			ret = wmax_game_shift_status(priv->wdev,
> -						     WMAX_OPERATION_TOGGLE_GAME_SHIFT,
> -						     &gmode_status);
> -
> -			if (ret < 0)
> -				return ret;
> -		}
> -	}
> -
> -	return wmax_thermal_control(priv->wdev,
> -				    priv->supported_thermal_profiles[profile]);
> -}
> -
> -static int create_thermal_profile(struct wmi_device *wdev)
> -{
> -	enum platform_profile_option profile;
> -	enum wmax_thermal_mode mode;
> -	struct awcc_priv *priv;
> -	u8 sys_desc[4];
> -	u32 first_mode;
> -	u32 out_data;
> -	int ret;
> -
> -	priv = dev_get_drvdata(&wdev->dev);
> -
> -	ret = wmax_thermal_information(wdev, WMAX_OPERATION_SYS_DESCRIPTION,
> -				       0, (u32 *) &sys_desc);
> -	if (ret < 0)
> -		return ret;
> -
> -	first_mode = sys_desc[0] + sys_desc[1];
> -
> -	for (u32 i = 0; i < sys_desc[3]; i++) {
> -		ret = wmax_thermal_information(wdev, WMAX_OPERATION_LIST_IDS,
> -					       i + first_mode, &out_data);
> -
> -		if (ret == -EIO)
> -			return ret;
> -
> -		if (ret == -EBADRQC)
> -			break;
> -
> -		if (!is_wmax_thermal_code(out_data))
> -			continue;
> -
> -		mode = out_data & WMAX_THERMAL_MODE_MASK;
> -		profile = wmax_mode_to_platform_profile[mode];
> -		priv->supported_thermal_profiles[profile] = out_data;
> -
> -		set_bit(profile, priv->pp_handler.choices);
> -	}
> -
> -	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
> -		return -ENODEV;
> -
> -	if (awcc->gmode) {
> -		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
> -			WMAX_THERMAL_MODE_GMODE;
> -
> -		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
> -	}
> -
> -	priv->pp_handler.profile_get = thermal_profile_get;
> -	priv->pp_handler.profile_set = thermal_profile_set;
> -	priv->pp_handler.name = "alienware-wmi";
> -	priv->pp_handler.dev = &wdev->dev;
> -
> -	return platform_profile_register(&priv->pp_handler);
> -}
> -
> -static int alienware_awcc_setup(struct wmi_device *wdev)
> -{
> -	struct awcc_priv *priv;
> -	int ret;
> -
> -	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -
> -	dev_set_drvdata(&wdev->dev, priv);
> -
> -	priv->wdev = wdev;
> -
> -	ret = create_thermal_profile(wdev);
> -	if (ret < 0)
> -		return ret;
> -
> -	return 0;
> -}
> -
> -static void alienware_awcc_exit(struct wmi_device *wdev)
> -{
> -	struct awcc_priv *priv;
> -
> -	priv = dev_get_drvdata(&wdev->dev);
> -
> -	platform_profile_remove(&priv->pp_handler);
> -}
> -
>   /*
>    * Platform Driver
>    */
> @@ -1097,189 +684,6 @@ void alienware_alienfx_exit(struct wmi_device *wdev)
>   	platform_driver_unregister(&platform_driver);
>   }
>
> -/*
> - * Legacy WMI driver
> - */
> -static int legacy_wmi_update_led(struct alienfx_priv *priv,
> -				 struct wmi_device *wdev, u8 location)
> -{
> -	struct legacy_led_args legacy_args;
> -	struct acpi_buffer input;
> -	acpi_status status;
> -
> -	legacy_args.colors = priv->colors[location];
> -	legacy_args.brightness = priv->global_brightness;
> -	legacy_args.state = priv->lighting_control_state;
> -
> -	input.length = sizeof(legacy_args);
> -	input.pointer = &legacy_args;
> -
> -	if (legacy_args.state == LEGACY_RUNNING)
> -		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
> -					       sizeof(legacy_args), NULL);
> -	else
> -		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
> -					     location + 1, &input, NULL);
> -
> -	if (ACPI_FAILURE(status))
> -		return -EIO;
> -
> -	return 0;
> -}
> -
> -static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
> -					struct wmi_device *wdev, u8 brightness)
> -{
> -	return legacy_wmi_update_led(priv, wdev, 0);
> -}
> -
> -static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
> -{
> -	struct alienfx_platdata pdata = {
> -		.wdev = wdev,
> -		.ops = {
> -			.upd_led = legacy_wmi_update_led,
> -			.upd_brightness = legacy_wmi_update_brightness,
> -		},
> -	};
> -
> -	return alienware_alienfx_setup(&pdata);
> -}
> -
> -static void legacy_wmi_remove(struct wmi_device *wdev)
> -{
> -	alienware_alienfx_exit(wdev);
> -}
> -
> -static struct wmi_device_id alienware_legacy_device_id_table[] = {
> -	{ LEGACY_CONTROL_GUID, NULL },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
> -
> -static struct wmi_driver alienware_legacy_wmi_driver = {
> -	.driver = {
> -		.name = "alienware-wmi-alienfx",
> -		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> -	},
> -	.id_table = alienware_legacy_device_id_table,
> -	.probe = legacy_wmi_probe,
> -	.remove = legacy_wmi_remove,
> -};
> -
> -int __init alienware_legacy_wmi_init(void)
> -{
> -	return wmi_driver_register(&alienware_legacy_wmi_driver);
> -}
> -
> -void __exit alienware_legacy_wmi_exit(void)
> -{
> -	wmi_driver_unregister(&alienware_legacy_wmi_driver);
> -}
> -
> -/*
> - * WMAX WMI driver
> - */
> -static int wmax_wmi_update_led(struct alienfx_priv *priv,
> -			       struct wmi_device *wdev, u8 location)
> -{
> -	struct wmax_led_args in_args = {
> -		.led_mask = 1 << location,
> -		.colors = priv->colors[location],
> -		.state = priv->lighting_control_state,
> -	};
> -	acpi_status status;
> -
> -	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
> -				       &in_args, sizeof(in_args), NULL);
> -	if (ACPI_FAILURE(status))
> -		return -EIO;
> -
> -	return 0;
> -}
> -
> -static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
> -				      struct wmi_device *wdev, u8 brightness)
> -{
> -	struct wmax_brightness_args in_args = {
> -		.led_mask = 0xFF,
> -		.percentage = brightness,
> -	};
> -	acpi_status status;
> -
> -	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
> -				       sizeof(in_args), NULL);
> -	if (ACPI_FAILURE(status))
> -		return -EIO;
> -
> -	return 0;
> -}
> -
> -static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> -{
> -	struct alienfx_platdata pdata = {
> -		.wdev = wdev,
> -		.ops = {
> -			.upd_led = wmax_wmi_update_led,
> -			.upd_brightness = wmax_wmi_update_brightness,
> -		},
> -	};
> -	int ret = 0;
> -
> -	if (awcc)
> -		ret = alienware_awcc_setup(wdev);
> -	else
> -		ret = alienware_alienfx_setup(&pdata);
> -
> -	return ret;
> -}
> -
> -static void wmax_wmi_remove(struct wmi_device *wdev)
> -{
> -	if (awcc)
> -		alienware_awcc_exit(wdev);
> -	else
> -		alienware_alienfx_exit(wdev);
> -}
> -
> -static struct wmi_device_id alienware_wmax_device_id_table[] = {
> -	{ WMAX_CONTROL_GUID, NULL },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
> -
> -static struct wmi_driver alienware_wmax_wmi_driver = {
> -	.driver = {
> -		.name = "alienware-wmi-wmax",
> -		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> -	},
> -	.id_table = alienware_wmax_device_id_table,
> -	.probe = wmax_wmi_probe,
> -	.remove = wmax_wmi_remove,
> -};
> -
> -int __init alienware_wmax_wmi_init(void)
> -{
> -	const struct dmi_system_id *id;
> -
> -	id = dmi_first_match(awcc_dmi_table);
> -	if (id)
> -		awcc = id->driver_data;
> -
> -	if (force_platform_profile)
> -		awcc = &x_series_features;
> -
> -	if (force_gmode)
> -		awcc = &g_series_features;
> -
> -	return wmi_driver_register(&alienware_wmax_wmi_driver);
> -}
> -
> -void __exit alienware_wmax_wmi_exit(void)
> -{
> -	wmi_driver_unregister(&alienware_wmax_wmi_driver);
> -}
> -
>   static int __init alienware_wmi_init(void)
>   {
>   	int ret;
> diff --git a/drivers/platform/x86/dell/alienware-wmi-legacy.c b/drivers/platform/x86/dell/alienware-wmi-legacy.c
> new file mode 100644
> index 000000000000..38dd2a602f34
> --- /dev/null
> +++ b/drivers/platform/x86/dell/alienware-wmi-legacy.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Alienware LEGACY WMI device driver
> + *
> + * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
> + */
> +
> +#include <linux/wmi.h>
> +#include "alienware-wmi.h"
> +
> +/*
> + * Legacy WMI driver
> + */
> +static int legacy_wmi_update_led(struct alienfx_priv *priv,
> +				 struct wmi_device *wdev, u8 location)
> +{
> +	struct legacy_led_args legacy_args;
> +	struct acpi_buffer input;
> +	acpi_status status;
> +
> +	legacy_args.colors = priv->colors[location];
> +	legacy_args.brightness = priv->global_brightness;
> +	legacy_args.state = priv->lighting_control_state;
> +
> +	input.length = sizeof(legacy_args);
> +	input.pointer = &legacy_args;
> +
> +	if (legacy_args.state == LEGACY_RUNNING)
> +		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
> +					       sizeof(legacy_args), NULL);
> +	else
> +		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
> +					     location + 1, &input, NULL);
> +
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
> +					struct wmi_device *wdev, u8 brightness)
> +{
> +	return legacy_wmi_update_led(priv, wdev, 0);
> +}
> +
> +static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> +	struct alienfx_platdata pdata = {
> +		.wdev = wdev,
> +		.ops = {
> +			.upd_led = legacy_wmi_update_led,
> +			.upd_brightness = legacy_wmi_update_brightness,
> +		},
> +	};
> +
> +	return alienware_alienfx_setup(&pdata);
> +}
> +
> +static void legacy_wmi_remove(struct wmi_device *wdev)
> +{
> +	alienware_alienfx_exit(wdev);
> +}
> +
> +static struct wmi_device_id alienware_legacy_device_id_table[] = {
> +	{ LEGACY_CONTROL_GUID, NULL },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
> +
> +static struct wmi_driver alienware_legacy_wmi_driver = {
> +	.driver = {
> +		.name = "alienware-wmi-alienfx",
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> +	},
> +	.id_table = alienware_legacy_device_id_table,
> +	.probe = legacy_wmi_probe,
> +	.remove = legacy_wmi_remove,
> +};
> +
> +int __init alienware_legacy_wmi_init(void)
> +{
> +	return wmi_driver_register(&alienware_legacy_wmi_driver);
> +}
> +
> +void __exit alienware_legacy_wmi_exit(void)
> +{
> +	wmi_driver_unregister(&alienware_legacy_wmi_driver);
> +}
> diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c
> new file mode 100644
> index 000000000000..75b9a1f029b2
> --- /dev/null
> +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c
> @@ -0,0 +1,526 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Alienware WMAX WMI device driver
> + *
> + * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
> + */
> +
> +#include <linux/dmi.h>
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/moduleparam.h>
> +#include <linux/platform_profile.h>
> +#include <linux/wmi.h>
> +#include "alienware-wmi.h"
> +
> +#define WMAX_THERMAL_TABLE_MASK		GENMASK(7, 4)
> +#define WMAX_THERMAL_MODE_MASK		GENMASK(3, 0)
> +#define WMAX_SENSOR_ID_MASK		BIT(8)
> +
> +static bool force_platform_profile;
> +module_param_unsafe(force_platform_profile, bool, 0);
> +MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
> +
> +static bool force_gmode;
> +module_param_unsafe(force_gmode, bool, 0);
> +MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
> +
> +enum WMAX_THERMAL_INFORMATION_OPERATIONS {
> +	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
> +	WMAX_OPERATION_LIST_IDS			= 0x03,
> +	WMAX_OPERATION_CURRENT_PROFILE		= 0x0B,
> +};
> +
> +enum WMAX_THERMAL_CONTROL_OPERATIONS {
> +	WMAX_OPERATION_ACTIVATE_PROFILE		= 0x01,
> +};
> +
> +enum WMAX_GAME_SHIFT_STATUS_OPERATIONS {
> +	WMAX_OPERATION_TOGGLE_GAME_SHIFT	= 0x01,
> +	WMAX_OPERATION_GET_GAME_SHIFT_STATUS	= 0x02,
> +};
> +
> +enum WMAX_THERMAL_TABLES {
> +	WMAX_THERMAL_TABLE_BASIC		= 0x90,
> +	WMAX_THERMAL_TABLE_USTT			= 0xA0,
> +};
> +
> +enum wmax_thermal_mode {
> +	THERMAL_MODE_USTT_BALANCED,
> +	THERMAL_MODE_USTT_BALANCED_PERFORMANCE,
> +	THERMAL_MODE_USTT_COOL,
> +	THERMAL_MODE_USTT_QUIET,
> +	THERMAL_MODE_USTT_PERFORMANCE,
> +	THERMAL_MODE_USTT_LOW_POWER,
> +	THERMAL_MODE_BASIC_QUIET,
> +	THERMAL_MODE_BASIC_BALANCED,
> +	THERMAL_MODE_BASIC_BALANCED_PERFORMANCE,
> +	THERMAL_MODE_BASIC_PERFORMANCE,
> +	THERMAL_MODE_LAST,
> +};
> +
> +struct wmax_u32_args {
> +	u8 operation;
> +	u8 arg1;
> +	u8 arg2;
> +	u8 arg3;
> +};
> +
> +struct awcc_priv {
> +	struct wmi_device *wdev;
> +	struct platform_profile_handler pp_handler;
> +	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> +};
> +
> +struct awcc_features {
> +	bool gmode;
> +};
> +
> +static struct awcc_features g_series_features = {
> +	.gmode = true,
> +};
> +
> +static struct awcc_features x_series_features = {
> +	.gmode = false,
> +};
> +
> +static const struct dmi_system_id awcc_dmi_table[] __initconst = {
> +	{
> +		.ident = "Alienware m17 R5",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
> +		},
> +		.driver_data = &x_series_features,
> +	},
> +	{
> +		.ident = "Alienware m18 R2",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
> +		},
> +		.driver_data = &x_series_features,
> +	},
> +	{
> +		.ident = "Alienware x15 R1",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
> +		},
> +		.driver_data = &x_series_features,
> +	},
> +	{
> +		.ident = "Alienware x17 R2",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
> +		},
> +		.driver_data = &x_series_features,
> +	},
> +	{
> +		.ident = "Dell Inc. G15 5510",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
> +		},
> +		.driver_data = &g_series_features,
> +	},
> +	{
> +		.ident = "Dell Inc. G15 5511",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
> +		},
> +		.driver_data = &g_series_features,
> +	},
> +	{
> +		.ident = "Dell Inc. G15 5515",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
> +		},
> +		.driver_data = &g_series_features,
> +	},
> +	{
> +		.ident = "Dell Inc. G3 3500",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
> +		},
> +		.driver_data = &g_series_features,
> +	},
> +	{
> +		.ident = "Dell Inc. G3 3590",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
> +		},
> +		.driver_data = &g_series_features,
> +	},
> +	{
> +		.ident = "Dell Inc. G5 5500",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
> +		},
> +		.driver_data = &g_series_features,
> +	},
> +};
> +
> +static const enum platform_profile_option wmax_mode_to_platform_profile[THERMAL_MODE_LAST] = {
> +	[THERMAL_MODE_USTT_BALANCED]			= PLATFORM_PROFILE_BALANCED,
> +	[THERMAL_MODE_USTT_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
> +	[THERMAL_MODE_USTT_COOL]			= PLATFORM_PROFILE_COOL,
> +	[THERMAL_MODE_USTT_QUIET]			= PLATFORM_PROFILE_QUIET,
> +	[THERMAL_MODE_USTT_PERFORMANCE]			= PLATFORM_PROFILE_PERFORMANCE,
> +	[THERMAL_MODE_USTT_LOW_POWER]			= PLATFORM_PROFILE_LOW_POWER,
> +	[THERMAL_MODE_BASIC_QUIET]			= PLATFORM_PROFILE_QUIET,
> +	[THERMAL_MODE_BASIC_BALANCED]			= PLATFORM_PROFILE_BALANCED,
> +	[THERMAL_MODE_BASIC_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
> +	[THERMAL_MODE_BASIC_PERFORMANCE]		= PLATFORM_PROFILE_PERFORMANCE,
> +};
> +
> +struct awcc_features *awcc;
> +
> +/*
> + * Thermal Profile control
> + *  - Provides thermal profile control through the Platform Profile API
> + */
> +static bool is_wmax_thermal_code(u32 code)
> +{
> +	if (code & WMAX_SENSOR_ID_MASK)
> +		return false;
> +
> +	if ((code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_LAST)
> +		return false;
> +
> +	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_BASIC &&
> +	    (code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_BASIC_QUIET)
> +		return true;
> +
> +	if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_USTT &&
> +	    (code & WMAX_THERMAL_MODE_MASK) <= THERMAL_MODE_USTT_LOW_POWER)
> +		return true;
> +
> +	return false;
> +}
> +
> +static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
> +				    u8 arg, u32 *out_data)
> +{
> +	struct wmax_u32_args in_args = {
> +		.operation = operation,
> +		.arg1 = arg,
> +		.arg2 = 0,
> +		.arg3 = 0,
> +	};
> +	acpi_status status;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
> +				       &in_args, sizeof(in_args), out_data);
> +
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	if (*out_data == WMAX_FAILURE_CODE)
> +		return -EBADRQC;
> +
> +	return 0;
> +}
> +
> +static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
> +{
> +	struct wmax_u32_args in_args = {
> +		.operation = WMAX_OPERATION_ACTIVATE_PROFILE,
> +		.arg1 = profile,
> +		.arg2 = 0,
> +		.arg3 = 0,
> +	};
> +	acpi_status status;
> +	u32 out_data;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
> +				       &in_args, sizeof(in_args), &out_data);
> +
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	if (out_data == WMAX_FAILURE_CODE)
> +		return -EBADRQC;
> +
> +	return 0;
> +}
> +
> +static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
> +				  u32 *out_data)
> +{
> +	struct wmax_u32_args in_args = {
> +		.operation = operation,
> +		.arg1 = 0,
> +		.arg2 = 0,
> +		.arg3 = 0,
> +	};
> +	acpi_status status;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
> +				       &in_args, sizeof(in_args), out_data);
> +
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	if (*out_data == WMAX_FAILURE_CODE)
> +		return -EOPNOTSUPP;
> +
> +	return 0;
> +}
> +
> +static int thermal_profile_get(struct platform_profile_handler *pprof,
> +			       enum platform_profile_option *profile)
> +{
> +	struct awcc_priv *priv;
> +	u32 out_data;
> +	int ret;
> +
> +	priv = container_of(pprof, struct awcc_priv, pp_handler);
> +
> +	ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
> +				       0, &out_data);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (out_data == WMAX_THERMAL_MODE_GMODE) {
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		return 0;
> +	}
> +
> +	if (!is_wmax_thermal_code(out_data))
> +		return -ENODATA;
> +
> +	out_data &= WMAX_THERMAL_MODE_MASK;
> +	*profile = wmax_mode_to_platform_profile[out_data];
> +
> +	return 0;
> +}
> +
> +static int thermal_profile_set(struct platform_profile_handler *pprof,
> +			       enum platform_profile_option profile)
> +{
> +	struct awcc_priv *priv;
> +
> +	priv = container_of(pprof, struct awcc_priv, pp_handler);
> +
> +	if (awcc->gmode) {
> +		u32 gmode_status;
> +		int ret;
> +
> +		ret = wmax_game_shift_status(priv->wdev,
> +					     WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
> +					     &gmode_status);
> +
> +		if (ret < 0)
> +			return ret;
> +
> +		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
> +		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
> +			ret = wmax_game_shift_status(priv->wdev,
> +						     WMAX_OPERATION_TOGGLE_GAME_SHIFT,
> +						     &gmode_status);
> +
> +			if (ret < 0)
> +				return ret;
> +		}
> +	}
> +
> +	return wmax_thermal_control(priv->wdev,
> +				    priv->supported_thermal_profiles[profile]);
> +}
> +
> +static int create_thermal_profile(struct wmi_device *wdev)
> +{
> +	enum platform_profile_option profile;
> +	enum wmax_thermal_mode mode;
> +	struct awcc_priv *priv;
> +	u8 sys_desc[4];
> +	u32 first_mode;
> +	u32 out_data;
> +	int ret;
> +
> +	priv = dev_get_drvdata(&wdev->dev);
> +
> +	ret = wmax_thermal_information(wdev, WMAX_OPERATION_SYS_DESCRIPTION,
> +				       0, (u32 *) &sys_desc);
> +	if (ret < 0)
> +		return ret;
> +
> +	first_mode = sys_desc[0] + sys_desc[1];
> +
> +	for (u32 i = 0; i < sys_desc[3]; i++) {
> +		ret = wmax_thermal_information(wdev, WMAX_OPERATION_LIST_IDS,
> +					       i + first_mode, &out_data);
> +
> +		if (ret == -EIO)
> +			return ret;
> +
> +		if (ret == -EBADRQC)
> +			break;
> +
> +		if (!is_wmax_thermal_code(out_data))
> +			continue;
> +
> +		mode = out_data & WMAX_THERMAL_MODE_MASK;
> +		profile = wmax_mode_to_platform_profile[mode];
> +		priv->supported_thermal_profiles[profile] = out_data;
> +
> +		set_bit(profile, priv->pp_handler.choices);
> +	}
> +
> +	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
> +		return -ENODEV;
> +
> +	if (awcc->gmode) {
> +		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
> +			WMAX_THERMAL_MODE_GMODE;
> +
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
> +	}
> +
> +	priv->pp_handler.profile_get = thermal_profile_get;
> +	priv->pp_handler.profile_set = thermal_profile_set;
> +	priv->pp_handler.name = "alienware-wmi";
> +	priv->pp_handler.dev = &wdev->dev;
> +
> +	return platform_profile_register(&priv->pp_handler);
> +}
> +
> +static int alienware_awcc_setup(struct wmi_device *wdev)
> +{
> +	struct awcc_priv *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(&wdev->dev, priv);
> +
> +	priv->wdev = wdev;
> +
> +	ret = create_thermal_profile(wdev);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static void alienware_awcc_exit(struct wmi_device *wdev)
> +{
> +	struct awcc_priv *priv;
> +
> +	priv = dev_get_drvdata(&wdev->dev);
> +
> +	platform_profile_remove(&priv->pp_handler);
> +}
> +
> +/*
> + * WMAX WMI driver
> + */
> +static int wmax_wmi_update_led(struct alienfx_priv *priv,
> +			       struct wmi_device *wdev, u8 location)
> +{
> +	struct wmax_led_args in_args = {
> +		.led_mask = 1 << location,
> +		.colors = priv->colors[location],
> +		.state = priv->lighting_control_state,
> +	};
> +	acpi_status status;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
> +				       &in_args, sizeof(in_args), NULL);
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
> +				      struct wmi_device *wdev, u8 brightness)
> +{
> +	struct wmax_brightness_args in_args = {
> +		.led_mask = 0xFF,
> +		.percentage = brightness,
> +	};
> +	acpi_status status;
> +
> +	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
> +				       sizeof(in_args), NULL);
> +	if (ACPI_FAILURE(status))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> +	struct alienfx_platdata pdata = {
> +		.wdev = wdev,
> +		.ops = {
> +			.upd_led = wmax_wmi_update_led,
> +			.upd_brightness = wmax_wmi_update_brightness,
> +		},
> +	};
> +	int ret = 0;
> +
> +	if (awcc)
> +		ret = alienware_awcc_setup(wdev);
> +	else
> +		ret = alienware_alienfx_setup(&pdata);
> +
> +	return ret;
> +}
> +
> +static void wmax_wmi_remove(struct wmi_device *wdev)
> +{
> +	if (awcc)
> +		alienware_awcc_exit(wdev);
> +	else
> +		alienware_alienfx_exit(wdev);
> +}
> +
> +static struct wmi_device_id alienware_wmax_device_id_table[] = {
> +	{ WMAX_CONTROL_GUID, NULL },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
> +
> +static struct wmi_driver alienware_wmax_wmi_driver = {
> +	.driver = {
> +		.name = "alienware-wmi-wmax",
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> +	},
> +	.id_table = alienware_wmax_device_id_table,
> +	.probe = wmax_wmi_probe,
> +	.remove = wmax_wmi_remove,
> +};
> +
> +int __init alienware_wmax_wmi_init(void)
> +{
> +	const struct dmi_system_id *id;
> +
> +	id = dmi_first_match(awcc_dmi_table);
> +	if (id)
> +		awcc = id->driver_data;
> +
> +	if (force_platform_profile)
> +		awcc = &x_series_features;
> +
> +	if (force_gmode)
> +		awcc = &g_series_features;
> +
> +	return wmi_driver_register(&alienware_wmax_wmi_driver);
> +}
> +
> +void __exit alienware_wmax_wmi_exit(void)
> +{
> +	wmi_driver_unregister(&alienware_wmax_wmi_driver);
> +}

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 18/20] platform/x86: dell: Modify Makefile alignment
  2024-12-21  5:59 ` [PATCH 18/20] platform/x86: dell: Modify Makefile alignment Kurt Borja
@ 2024-12-27  4:05   ` Armin Wolf
  2024-12-27  4:57     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  4:05 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Add one more TAB to each line to support upcoming changes.

Please merge this with patch 19.

Thanks,
Armin Wolf

>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/Makefile | 48 +++++++++++++++---------------
>   1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> index 03ba459f3d31..d5718ef34c48 100644
> --- a/drivers/platform/x86/dell/Makefile
> +++ b/drivers/platform/x86/dell/Makefile
> @@ -4,27 +4,27 @@
>   # Dell x86 Platform-Specific Drivers
>   #
>
> -obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
> -alienware-wmi-objs			:= alienware-wmi-base.o
> -alienware-wmi-y				+= alienware-wmi-legacy.o
> -alienware-wmi-y				+= alienware-wmi-wmax.o
> -obj-$(CONFIG_DCDBAS)			+= dcdbas.o
> -obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
> -obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
> -obj-$(CONFIG_DELL_RBU)			+= dell_rbu.o
> -obj-$(CONFIG_DELL_PC)			+= dell-pc.o
> -obj-$(CONFIG_DELL_SMBIOS)		+= dell-smbios.o
> -dell-smbios-objs			:= dell-smbios-base.o
> -dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)	+= dell-smbios-wmi.o
> -dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)	+= dell-smbios-smm.o
> -obj-$(CONFIG_DELL_SMO8800)		+= dell-smo8800.o
> -obj-$(CONFIG_DELL_SMO8800)		+= dell-lis3lv02d.o
> -obj-$(CONFIG_DELL_UART_BACKLIGHT)	+= dell-uart-backlight.o
> -obj-$(CONFIG_DELL_WMI)			+= dell-wmi.o
> -dell-wmi-objs				:= dell-wmi-base.o
> -dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)	+= dell-wmi-privacy.o
> -obj-$(CONFIG_DELL_WMI_AIO)		+= dell-wmi-aio.o
> -obj-$(CONFIG_DELL_WMI_DESCRIPTOR)	+= dell-wmi-descriptor.o
> -obj-$(CONFIG_DELL_WMI_DDV)		+= dell-wmi-ddv.o
> -obj-$(CONFIG_DELL_WMI_LED)		+= dell-wmi-led.o
> -obj-$(CONFIG_DELL_WMI_SYSMAN)		+= dell-wmi-sysman/
> +obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
> +alienware-wmi-objs				:= alienware-wmi-base.o
> +alienware-wmi-y					+= alienware-wmi-legacy.o
> +alienware-wmi-y					+= alienware-wmi-wmax.o
> +obj-$(CONFIG_DCDBAS)				+= dcdbas.o
> +obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
> +obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
> +obj-$(CONFIG_DELL_RBU)				+= dell_rbu.o
> +obj-$(CONFIG_DELL_PC)				+= dell-pc.o
> +obj-$(CONFIG_DELL_SMBIOS)			+= dell-smbios.o
> +dell-smbios-objs				:= dell-smbios-base.o
> +dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)		+= dell-smbios-wmi.o
> +dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)		+= dell-smbios-smm.o
> +obj-$(CONFIG_DELL_SMO8800)			+= dell-smo8800.o
> +obj-$(CONFIG_DELL_SMO8800)			+= dell-lis3lv02d.o
> +obj-$(CONFIG_DELL_UART_BACKLIGHT)		+= dell-uart-backlight.o
> +obj-$(CONFIG_DELL_WMI)				+= dell-wmi.o
> +dell-wmi-objs					:= dell-wmi-base.o
> +dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)		+= dell-wmi-privacy.o
> +obj-$(CONFIG_DELL_WMI_AIO)			+= dell-wmi-aio.o
> +obj-$(CONFIG_DELL_WMI_DESCRIPTOR)		+= dell-wmi-descriptor.o
> +obj-$(CONFIG_DELL_WMI_DDV)			+= dell-wmi-ddv.o
> +obj-$(CONFIG_DELL_WMI_LED)			+= dell-wmi-led.o
> +obj-$(CONFIG_DELL_WMI_SYSMAN)			+= dell-wmi-sysman/

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 19/20] platform/x86: Update alienware-wmi config entries
  2024-12-21  5:59 ` [PATCH 19/20] platform/x86: Update alienware-wmi config entries Kurt Borja
@ 2024-12-27  4:08   ` Armin Wolf
  2024-12-27  4:59     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  4:08 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Add config entries for each WMI driver managed by the alienware-wmi
> module to be able to conditionally compile them.
>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/Kconfig         | 30 +++++++++++++++++++----
>   drivers/platform/x86/dell/Makefile        |  4 +--
>   drivers/platform/x86/dell/alienware-wmi.h | 23 +++++++++++++++++
>   3 files changed, 50 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
> index d09060aedd3f..f8a0dffcaab7 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -18,15 +18,35 @@ config ALIENWARE_WMI
>   	tristate "Alienware Special feature control"
>   	default m
>   	depends on ACPI
> +	depends on ACPI_WMI
> +	depends on DMI
>   	depends on LEDS_CLASS
>   	depends on NEW_LEDS
> -	depends on ACPI_WMI
> +	help
> +	 This is a driver for controlling Alienware WMI driven features.
> +
> +	 On legacy devices, it exposes an interface for controlling the AlienFX
> +	 zones on Alienware machines that don't contain a dedicated
> +	 AlienFX USB MCU such as the X51 and X51-R2.
> +
> +	 On newer devices, it exposes the AWCC thermal control interface through
> +	 known Kernel APIs.
> +
> +config ALIENWARE_WMI_LEGACY
> +	bool "Alienware Legacy WMI device driver"
> +	default y
> +	depends on ALIENWARE_WMI
> +	help
> +	 Legacy Alienware WMI driver with AlienFX LED control capabilities.
> +
> +config ALIENWARE_WMI_WMAX
> +	bool "Alienware WMAX WMI device driver"
> +	default y
> +	depends on ALIENWARE_WMI
>   	select ACPI_PLATFORM_PROFILE
>   	help
> -	 This is a driver for controlling Alienware BIOS driven
> -	 features.  It exposes an interface for controlling the AlienFX
> -	 zones on Alienware machines that don't contain a dedicated AlienFX
> -	 USB MCU such as the X51 and X51-R2.
> +	 Alienware WMI driver with AlienFX LED, HDMI, amplifier, deep sleep and
> +	 AWCC thermal control capabilities.
>
>   config DCDBAS
>   	tristate "Dell Systems Management Base Driver"
> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> index d5718ef34c48..8ac9a933c770 100644
> --- a/drivers/platform/x86/dell/Makefile
> +++ b/drivers/platform/x86/dell/Makefile
> @@ -6,8 +6,8 @@
>
>   obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
>   alienware-wmi-objs				:= alienware-wmi-base.o
> -alienware-wmi-y					+= alienware-wmi-legacy.o
> -alienware-wmi-y					+= alienware-wmi-wmax.o
> +alienware-wmi-$(CONFIG_ALIENWARE_WMI_LEGACY)	+= alienware-wmi-legacy.o
> +alienware-wmi-$(CONFIG_ALIENWARE_WMI_WMAX)	+= alienware-wmi-wmax.o
>   obj-$(CONFIG_DCDBAS)				+= dcdbas.o
>   obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
>   obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
> diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
> index 78ac10122155..97b52e51cd7d 100644
> --- a/drivers/platform/x86/dell/alienware-wmi.h
> +++ b/drivers/platform/x86/dell/alienware-wmi.h
> @@ -94,10 +94,33 @@ acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
>   int alienware_alienfx_setup(struct alienfx_platdata *pdata);
>   void alienware_alienfx_exit(struct wmi_device *wdev);
>
> +#if IS_ENABLED(CONFIG_ALIENWARE_WMI_LEGACY)
>   int __init alienware_legacy_wmi_init(void);
>   void __exit alienware_legacy_wmi_exit(void);
> +#else
> +int __init alienware_legacy_wmi_init(void)
> +{
> +	return 0;

Please return -EOPNOTSUPP here.

> +}
> +
> +void __exit alienware_legacy_wmi_exit(void)
> +{
> +}
> +#endif
>
> +#if IS_ENABLED(CONFIG_ALIENWARE_WMI_WMAX)
>   int __init alienware_wmax_wmi_init(void);
>   void __exit alienware_wmax_wmi_exit(void);
> +#else
> +int __init alienware_wmax_wmi_init(void)
> +{
> +	return 0;

Same as above.

Thanks,
Armin Wolf

> +}
> +
> +
> +void __exit alienware_wmax_wmi_exit(void)
> +{
> +}
> +#endif
>
>   #endif

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 20/20] alienware-wmi: Update header and module information
  2024-12-21  5:59 ` [PATCH 20/20] alienware-wmi: Update header and module information Kurt Borja
@ 2024-12-27  4:08   ` Armin Wolf
  2024-12-27  5:01     ` Kurt Borja
  0 siblings, 1 reply; 61+ messages in thread
From: Armin Wolf @ 2024-12-27  4:08 UTC (permalink / raw)
  To: Kurt Borja, platform-driver-x86
  Cc: ilpo.jarvinen, mario.limonciello, hdegoede, linux-kernel,
	Dell.Client.Kernel

Am 21.12.24 um 06:59 schrieb Kurt Borja:

> Update module description and add myself as a module author.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
>   drivers/platform/x86/dell/alienware-wmi-base.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
> index 450ba0a48004..e8ccf9b277fa 100644
> --- a/drivers/platform/x86/dell/alienware-wmi-base.c
> +++ b/drivers/platform/x86/dell/alienware-wmi-base.c
> @@ -1,8 +1,9 @@
>   // SPDX-License-Identifier: GPL-2.0-or-later
>   /*
> - * Alienware AlienFX control
> + * Alienware special feature control
>    *
>    * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
> + * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
>    */
>
>   #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> @@ -15,6 +16,7 @@
>   #include "alienware-wmi.h"
>
>   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
> +MODULE_AUTHOR("Kurt Borja <kuurtb@gmail.com>");
>   MODULE_DESCRIPTION("Alienware special feature control");
>   MODULE_LICENSE("GPL");
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 02/20] alienware-wmi: Move Lighting Control State
  2024-12-27  0:35   ` Armin Wolf
@ 2024-12-27  4:32     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:32 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 01:35:03AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:58 schrieb Kurt Borja:
> 
> > Place Lighting Control State logic next to other attributes of the same
> > sysfs group.
> > 
> > While at it, rename:
> > 
> > store_control_state()	-> lighting_control_state_store()
> > show_control_state()	-> lighting_control_state_show()
> > 
> > Replace DEVICE_ATTR_RW() with DEVICE_ATTR() and do a general style
> > cleanup.
> 
> I think you mixed-up DEVICE_ATTR_RW() and DEVICE_ATTR() here.
> Other than that:

Fixed in v2!

> 
> Reviewed-by: Armin Wolf <W_Armin@gmx.de>
> 
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 74 ++++++++++++-----------
> >   1 file changed, 39 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index ed66720260ab..c5ad0f95c442 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -545,6 +545,45 @@ static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
> >   	return ret ? ret : count;
> >   }
> > 
> > +/*
> > + * Lighting control state device attribute (Global)
> > + */
> > +static ssize_t lighting_control_state_show(struct device *dev,
> > +					   struct device_attribute *attr,
> > +					   char *buf)
> > +{
> > +	if (lighting_control_state == LEGACY_BOOTING)
> > +		return sysfs_emit(buf, "[booting] running suspend\n");
> > +	else if (lighting_control_state == LEGACY_SUSPEND)
> > +		return sysfs_emit(buf, "booting running [suspend]\n");
> > +
> > +	return sysfs_emit(buf, "booting [running] suspend\n");
> > +}
> > +
> > +static ssize_t lighting_control_state_store(struct device *dev,
> > +					    struct device_attribute *attr,
> > +					    const char *buf, size_t count)
> > +{
> > +	u8 val;
> > +
> > +	if (strcmp(buf, "booting\n") == 0)
> > +		val = LEGACY_BOOTING;
> > +	else if (strcmp(buf, "suspend\n") == 0)
> > +		val = LEGACY_SUSPEND;
> > +	else if (interface == LEGACY)
> > +		val = LEGACY_RUNNING;
> > +	else
> > +		val = WMAX_RUNNING;
> > +
> > +	lighting_control_state = val;
> > +	pr_debug("alienware-wmi: updated control state to %d\n",
> > +		 lighting_control_state);
> > +
> > +	return count;
> > +}
> > +
> > +static DEVICE_ATTR_RW(lighting_control_state);
> > +
> >   /*
> >    * LED Brightness (Global)
> >    */
> > @@ -589,41 +628,6 @@ static struct led_classdev global_led = {
> >   	.name = "alienware::global_brightness",
> >   };
> > 
> > -/*
> > - * Lighting control state device attribute (Global)
> > - */
> > -static ssize_t show_control_state(struct device *dev,
> > -				  struct device_attribute *attr, char *buf)
> > -{
> > -	if (lighting_control_state == LEGACY_BOOTING)
> > -		return sysfs_emit(buf, "[booting] running suspend\n");
> > -	else if (lighting_control_state == LEGACY_SUSPEND)
> > -		return sysfs_emit(buf, "booting running [suspend]\n");
> > -	return sysfs_emit(buf, "booting [running] suspend\n");
> > -}
> > -
> > -static ssize_t store_control_state(struct device *dev,
> > -				   struct device_attribute *attr,
> > -				   const char *buf, size_t count)
> > -{
> > -	long unsigned int val;
> > -	if (strcmp(buf, "booting\n") == 0)
> > -		val = LEGACY_BOOTING;
> > -	else if (strcmp(buf, "suspend\n") == 0)
> > -		val = LEGACY_SUSPEND;
> > -	else if (interface == LEGACY)
> > -		val = LEGACY_RUNNING;
> > -	else
> > -		val = WMAX_RUNNING;
> > -	lighting_control_state = val;
> > -	pr_debug("alienware-wmi: updated control state to %d\n",
> > -		 lighting_control_state);
> > -	return count;
> > -}
> > -
> > -static DEVICE_ATTR(lighting_control_state, 0644, show_control_state,
> > -		   store_control_state);
> > -
> >   static int alienware_zone_init(struct platform_device *dev)
> >   {
> >   	u8 zone;

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 05/20] alienware-wmi: Improve rgb-zones group creation
  2024-12-27  1:04   ` Armin Wolf
@ 2024-12-27  4:37     ` Kurt Borja
  2024-12-29  0:17       ` Armin Wolf
  0 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:37 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 02:04:51AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Define zone_attrs statically with the use of helper macros and
> > initialize the zone_attribute_group with driver's .dev_groups.
> > 
> > Drop match_zone() and instead pass a `location` argument to previous
> > show/store methods to access the correct `zone` LED state. On top of
> > that rename zone_set() -> zone_store() to be more consistent with sysfs
> > conventions.
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 179 +++++++++-------------
> >   1 file changed, 72 insertions(+), 107 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index e010c94555e8..a431b1fec9fb 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -376,12 +376,6 @@ struct color_platform {
> >   	u8 red;
> >   } __packed;
> > 
> > -struct platform_zone {
> > -	u8 location;
> > -	struct device_attribute *attr;
> > -	struct color_platform colors;
> > -};
> > -
> >   struct wmax_brightness_args {
> >   	u32 led_mask;
> >   	u32 percentage;
> > @@ -411,16 +405,10 @@ struct wmax_u32_args {
> >   };
> > 
> >   static struct platform_device *platform_device;
> > -static struct device_attribute *zone_dev_attrs;
> > -static struct attribute **zone_attrs;
> > -static struct platform_zone *zone_data;
> > +static struct color_platform colors[4];
> >   static struct platform_profile_handler pp_handler;
> >   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> > 
> > -static struct attribute_group zone_attribute_group = {
> > -	.name = "rgb_zones",
> > -};
> > -
> >   static u8 interface;
> >   static u8 lighting_control_state;
> >   static u8 global_brightness;
> > @@ -452,24 +440,10 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
> >   	return 0;
> >   }
> > 
> > -static struct platform_zone *match_zone(struct device_attribute *attr)
> > -{
> > -	u8 zone;
> > -
> > -	for (zone = 0; zone < quirks->num_zones; zone++) {
> > -		if ((struct device_attribute *)zone_data[zone].attr == attr) {
> > -			pr_debug("alienware-wmi: matched zone location: %d\n",
> > -				 zone_data[zone].location);
> > -			return &zone_data[zone];
> > -		}
> > -	}
> > -	return NULL;
> > -}
> > -
> >   /*
> >    * Individual RGB zone control
> >    */
> > -static int alienware_update_led(struct platform_zone *zone)
> > +static int alienware_update_led(u8 location)
> >   {
> >   	int method_id;
> >   	acpi_status status;
> > @@ -478,8 +452,8 @@ static int alienware_update_led(struct platform_zone *zone)
> >   	struct legacy_led_args legacy_args;
> >   	struct wmax_led_args wmax_basic_args;
> >   	if (interface == WMAX) {
> > -		wmax_basic_args.led_mask = 1 << zone->location;
> > -		wmax_basic_args.colors = zone->colors;
> > +		wmax_basic_args.led_mask = 1 << location;
> > +		wmax_basic_args.colors = colors[location];
> >   		wmax_basic_args.state = lighting_control_state;
> >   		guid = WMAX_CONTROL_GUID;
> >   		method_id = WMAX_METHOD_ZONE_CONTROL;
> > @@ -487,7 +461,7 @@ static int alienware_update_led(struct platform_zone *zone)
> >   		input.length = sizeof(wmax_basic_args);
> >   		input.pointer = &wmax_basic_args;
> >   	} else {
> > -		legacy_args.colors = zone->colors;
> > +		legacy_args.colors = colors[location];
> >   		legacy_args.brightness = global_brightness;
> >   		legacy_args.state = 0;
> >   		if (lighting_control_state == LEGACY_BOOTING ||
> > @@ -496,7 +470,7 @@ static int alienware_update_led(struct platform_zone *zone)
> >   			legacy_args.state = lighting_control_state;
> >   		} else
> >   			guid = LEGACY_CONTROL_GUID;
> > -		method_id = zone->location + 1;
> > +		method_id = location + 1;
> > 
> >   		input.length = sizeof(legacy_args);
> >   		input.pointer = &legacy_args;
> > @@ -510,35 +484,54 @@ static int alienware_update_led(struct platform_zone *zone)
> >   }
> > 
> >   static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
> > -			 char *buf)
> > +			 char *buf, u8 location)
> >   {
> > -	struct platform_zone *target_zone;
> > -	target_zone = match_zone(attr);
> > -	if (target_zone == NULL)
> > -		return sprintf(buf, "red: -1, green: -1, blue: -1\n");
> >   	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
> > -		       target_zone->colors.red,
> > -		       target_zone->colors.green, target_zone->colors.blue);
> > +		       colors[location].red, colors[location].green,
> > +		       colors[location].blue);
> > 
> >   }
> > 
> > -static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
> > -			const char *buf, size_t count)
> > +static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
> > +			  const char *buf, size_t count, u8 location)
> >   {
> > -	struct platform_zone *target_zone;
> >   	int ret;
> > -	target_zone = match_zone(attr);
> > -	if (target_zone == NULL) {
> > -		pr_err("alienware-wmi: invalid target zone\n");
> > -		return 1;
> > -	}
> > -	ret = parse_rgb(buf, &target_zone->colors);
> > +
> > +	ret = parse_rgb(buf, &colors[location]);
> >   	if (ret)
> >   		return ret;
> > -	ret = alienware_update_led(target_zone);
> > +
> > +	ret = alienware_update_led(location);
> > +
> >   	return ret ? ret : count;
> >   }
> > 
> > +#define ALIENWARE_ZONE_SHOW_FUNC(_num)					\
> > +	static ssize_t zone0##_num##_show(struct device *dev,		\
> > +					struct device_attribute *attr,	\
> > +					char *buf)			\
> > +	{								\
> > +		return zone_show(dev, attr, buf, _num);			\
> > +	}
> > +
> > +#define ALIENWARE_ZONE_STORE_FUNC(_num)					\
> > +	static ssize_t zone0##_num##_store(struct device *dev,		\
> > +					struct device_attribute *attr,	\
> > +					const char *buf, size_t count)	\
> > +	{								\
> > +		return zone_store(dev, attr, buf, count, _num);		\
> > +	}
> > +
> > +#define ALIENWARE_ZONE_ATTR(_num)					\
> > +	ALIENWARE_ZONE_SHOW_FUNC(_num)					\
> > +	ALIENWARE_ZONE_STORE_FUNC(_num)					\
> > +	static DEVICE_ATTR_RW(zone0##_num)
> > +
> > +ALIENWARE_ZONE_ATTR(0);
> > +ALIENWARE_ZONE_ATTR(1);
> > +ALIENWARE_ZONE_ATTR(2);
> > +ALIENWARE_ZONE_ATTR(3);
> 
> I know that this will result in a bit of boilerplate code, but please do not use such macros.
> They have a habit of confusing static code analysis tools.

Ack.

I'll drop this macros, checkpatch also hates the last one.

> 
> > +
> >   /*
> >    * Lighting control state device attribute (Global)
> >    */
> > @@ -578,6 +571,33 @@ static ssize_t lighting_control_state_store(struct device *dev,
> > 
> >   static DEVICE_ATTR_RW(lighting_control_state);
> > 
> > +static umode_t zone_attr_visible(struct kobject *kobj,
> > +				 struct attribute *attr, int n)
> > +{
> > +	return n < quirks->num_zones + 1 ? 0644 : 0;
> 
> Where is this function used?

It gets picked up by DEFINE_SYSFS_GROUP_VISIBLE to manage individual
attributes permissions.

> 
> Thanks,
> Armin Wolf
> 
> > +}
> > +
> > +static bool zone_group_visible(struct kobject *kobj)
> > +{
> > +	return quirks->num_zones > 0;
> > +}
> > +DEFINE_SYSFS_GROUP_VISIBLE(zone);
> > +
> > +static struct attribute *zone_attrs[] = {
> > +	&dev_attr_lighting_control_state.attr,
> > +	&dev_attr_zone00.attr,
> > +	&dev_attr_zone01.attr,
> > +	&dev_attr_zone02.attr,
> > +	&dev_attr_zone03.attr,
> > +	NULL
> > +};
> > +
> > +static struct attribute_group zone_attribute_group = {
> > +	.name = "rgb_zones",
> > +	.is_visible = SYSFS_GROUP_VISIBLE(zone),
> > +	.attrs = zone_attrs,
> > +};
> > +
> >   /*
> >    * LED Brightness (Global)
> >    */
> > @@ -606,7 +626,7 @@ static void global_led_set(struct led_classdev *led_cdev,
> >   	if (interface == WMAX)
> >   		ret = wmax_brightness(brightness);
> >   	else
> > -		ret = alienware_update_led(&zone_data[0]);
> > +		ret = alienware_update_led(0);
> >   	if (ret)
> >   		pr_err("LED brightness update failed\n");
> >   }
> > @@ -624,9 +644,6 @@ static struct led_classdev global_led = {
> > 
> >   static int alienware_zone_init(struct platform_device *dev)
> >   {
> > -	u8 zone;
> > -	char *name;
> > -
> >   	if (interface == WMAX) {
> >   		lighting_control_state = WMAX_RUNNING;
> >   	} else if (interface == LEGACY) {
> > @@ -635,65 +652,12 @@ static int alienware_zone_init(struct platform_device *dev)
> >   	global_led.max_brightness = 0x0F;
> >   	global_brightness = global_led.max_brightness;
> > 
> > -	/*
> > -	 *      - zone_dev_attrs num_zones + 1 is for individual zones and then
> > -	 *        null terminated
> > -	 *      - zone_attrs num_zones + 2 is for all attrs in zone_dev_attrs +
> > -	 *        the lighting control + null terminated
> > -	 *      - zone_data num_zones is for the distinct zones
> > -	 */
> > -	zone_dev_attrs =
> > -	    kcalloc(quirks->num_zones + 1, sizeof(struct device_attribute),
> > -		    GFP_KERNEL);
> > -	if (!zone_dev_attrs)
> > -		return -ENOMEM;
> > -
> > -	zone_attrs =
> > -	    kcalloc(quirks->num_zones + 2, sizeof(struct attribute *),
> > -		    GFP_KERNEL);
> > -	if (!zone_attrs)
> > -		return -ENOMEM;
> > -
> > -	zone_data =
> > -	    kcalloc(quirks->num_zones, sizeof(struct platform_zone),
> > -		    GFP_KERNEL);
> > -	if (!zone_data)
> > -		return -ENOMEM;
> > -
> > -	for (zone = 0; zone < quirks->num_zones; zone++) {
> > -		name = kasprintf(GFP_KERNEL, "zone%02hhX", zone);
> > -		if (name == NULL)
> > -			return 1;
> > -		sysfs_attr_init(&zone_dev_attrs[zone].attr);
> > -		zone_dev_attrs[zone].attr.name = name;
> > -		zone_dev_attrs[zone].attr.mode = 0644;
> > -		zone_dev_attrs[zone].show = zone_show;
> > -		zone_dev_attrs[zone].store = zone_set;
> > -		zone_data[zone].location = zone;
> > -		zone_attrs[zone] = &zone_dev_attrs[zone].attr;
> > -		zone_data[zone].attr = &zone_dev_attrs[zone];
> > -	}
> > -	zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
> > -	zone_attribute_group.attrs = zone_attrs;
> > -
> > -	led_classdev_register(&dev->dev, &global_led);
> > -
> > -	return sysfs_create_group(&dev->dev.kobj, &zone_attribute_group);
> > +	return led_classdev_register(&dev->dev, &global_led);
> >   }
> > 
> >   static void alienware_zone_exit(struct platform_device *dev)
> >   {
> > -	u8 zone;
> > -
> > -	sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
> >   	led_classdev_unregister(&global_led);
> > -	if (zone_dev_attrs) {
> > -		for (zone = 0; zone < quirks->num_zones; zone++)
> > -			kfree(zone_dev_attrs[zone].attr.name);
> > -	}
> > -	kfree(zone_dev_attrs);
> > -	kfree(zone_data);
> > -	kfree(zone_attrs);
> >   }
> > 
> >   static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
> > @@ -1143,6 +1107,7 @@ static void remove_thermal_profile(void)
> >    * Platform Driver
> >    */
> >   static const struct attribute_group *alienfx_groups[] = {
> > +	&zone_attribute_group,
> >   	&hdmi_attribute_group,
> >   	&amplifier_attribute_group,
> >   	&deepsleep_attribute_group,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] alienware-wmi: Add a state container for LED control feature
  2024-12-27  1:32   ` Armin Wolf
@ 2024-12-27  4:39     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:39 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 02:32:24AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Add a state container for the "alienware-wmi" platform device and
> > initialize it on the new alienfx_probe(). Migrate all LED control functions
> > to use this state container.
> > 
> > Additionally move the led_classdev registration to the platform driver
> > probe and make it device managed.
> > 
> > Drop alienware_zone_init() and alienware_zone_exit() because they are no
> > longer needed.
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 128 +++++++++++++---------
> >   1 file changed, 76 insertions(+), 52 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index 67cf376df0f5..4b68d64bd742 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -404,14 +404,19 @@ struct wmax_u32_args {
> >   	u8 arg3;
> >   };
> > 
> > +struct alienfx_priv {
> > +	struct platform_device *pdev;
> > +	struct led_classdev global_led;
> > +	struct color_platform colors[4];
> > +	u8 global_brightness;
> > +	u8 lighting_control_state;
> > +};
> > +
> >   static struct platform_device *platform_device;
> > -static struct color_platform colors[4];
> >   static struct platform_profile_handler pp_handler;
> >   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> > 
> >   static u8 interface;
> > -static u8 lighting_control_state;
> > -static u8 global_brightness;
> > 
> >   /*
> >    * Helpers used for zone control
> > @@ -443,7 +448,7 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
> >   /*
> >    * Individual RGB zone control
> >    */
> > -static int alienware_update_led(u8 location)
> > +static int alienware_update_led(struct alienfx_priv *priv, u8 location)
> >   {
> >   	int method_id;
> >   	acpi_status status;
> > @@ -453,21 +458,21 @@ static int alienware_update_led(u8 location)
> >   	struct wmax_led_args wmax_basic_args;
> >   	if (interface == WMAX) {
> >   		wmax_basic_args.led_mask = 1 << location;
> > -		wmax_basic_args.colors = colors[location];
> > -		wmax_basic_args.state = lighting_control_state;
> > +		wmax_basic_args.colors = priv->colors[location];
> > +		wmax_basic_args.state = priv->lighting_control_state;
> >   		guid = WMAX_CONTROL_GUID;
> >   		method_id = WMAX_METHOD_ZONE_CONTROL;
> > 
> >   		input.length = sizeof(wmax_basic_args);
> >   		input.pointer = &wmax_basic_args;
> >   	} else {
> > -		legacy_args.colors = colors[location];
> > -		legacy_args.brightness = global_brightness;
> > +		legacy_args.colors = priv->colors[location];
> > +		legacy_args.brightness = priv->global_brightness;
> >   		legacy_args.state = 0;
> > -		if (lighting_control_state == LEGACY_BOOTING ||
> > -		    lighting_control_state == LEGACY_SUSPEND) {
> > +		if (priv->lighting_control_state == LEGACY_BOOTING ||
> > +		    priv->lighting_control_state == LEGACY_SUSPEND) {
> >   			guid = LEGACY_POWER_CONTROL_GUID;
> > -			legacy_args.state = lighting_control_state;
> > +			legacy_args.state = priv->lighting_control_state;
> >   		} else
> >   			guid = LEGACY_CONTROL_GUID;
> >   		method_id = location + 1;
> > @@ -486,22 +491,32 @@ static int alienware_update_led(u8 location)
> >   static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
> >   			 char *buf, u8 location)
> >   {
> > +	struct color_platform *colors;
> > +	struct alienfx_priv *priv;
> > +
> > +	priv = dev_get_drvdata(dev);
> 
> Please use "struct color_platform *colors = dev_get_drvdata(dev);" in such cases.
> 
> > +	colors = &priv->colors[location];
> > +
> >   	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
> > -		       colors[location].red, colors[location].green,
> > -		       colors[location].blue);
> > +		       colors->red, colors->green, colors->blue);
> > 
> >   }
> > 
> >   static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
> >   			  const char *buf, size_t count, u8 location)
> >   {
> > +	struct color_platform *colors;
> > +	struct alienfx_priv *priv;
> >   	int ret;
> > 
> > -	ret = parse_rgb(buf, &colors[location]);
> > +	priv = dev_get_drvdata(dev);
> 
> Same as above.
> 
> > +	colors = &priv->colors[location];
> > +
> > +	ret = parse_rgb(buf, colors);
> >   	if (ret)
> >   		return ret;
> > 
> > -	ret = alienware_update_led(location);
> > +	ret = alienware_update_led(priv, location);
> > 
> >   	return ret ? ret : count;
> >   }
> > @@ -539,9 +554,13 @@ static ssize_t lighting_control_state_show(struct device *dev,
> >   					   struct device_attribute *attr,
> >   					   char *buf)
> >   {
> > -	if (lighting_control_state == LEGACY_BOOTING)
> > +	struct alienfx_priv *priv;
> > +
> > +	priv = dev_get_drvdata(dev);
> 
> Same as above.
> 
> > +
> > +	if (priv->lighting_control_state == LEGACY_BOOTING)
> >   		return sysfs_emit(buf, "[booting] running suspend\n");
> > -	else if (lighting_control_state == LEGACY_SUSPEND)
> > +	else if (priv->lighting_control_state == LEGACY_SUSPEND)
> >   		return sysfs_emit(buf, "booting running [suspend]\n");
> > 
> >   	return sysfs_emit(buf, "booting [running] suspend\n");
> > @@ -551,8 +570,11 @@ static ssize_t lighting_control_state_store(struct device *dev,
> >   					    struct device_attribute *attr,
> >   					    const char *buf, size_t count)
> >   {
> > +	struct alienfx_priv *priv;
> >   	u8 val;
> > 
> > +	priv = dev_get_drvdata(dev);
> 
> Same as above.
> 
> > +
> >   	if (strcmp(buf, "booting\n") == 0)
> >   		val = LEGACY_BOOTING;
> >   	else if (strcmp(buf, "suspend\n") == 0)
> > @@ -562,9 +584,9 @@ static ssize_t lighting_control_state_store(struct device *dev,
> >   	else
> >   		val = WMAX_RUNNING;
> > 
> > -	lighting_control_state = val;
> > +	priv->lighting_control_state = val;
> >   	pr_debug("alienware-wmi: updated control state to %d\n",
> > -		 lighting_control_state);
> > +		 priv->lighting_control_state);
> > 
> >   	return count;
> >   }
> > @@ -621,43 +643,26 @@ static int wmax_brightness(int brightness)
> >   static void global_led_set(struct led_classdev *led_cdev,
> >   			   enum led_brightness brightness)
> >   {
> > +	struct alienfx_priv *priv;
> >   	int ret;
> > -	global_brightness = brightness;
> > +
> > +	priv = container_of(led_cdev, struct alienfx_priv, global_led);
> 
> Same as above, but with container_of().
> 
> > +	priv->global_brightness = brightness;
> >   	if (interface == WMAX)
> >   		ret = wmax_brightness(brightness);
> >   	else
> > -		ret = alienware_update_led(0);
> > +		ret = alienware_update_led(priv, 0);
> >   	if (ret)
> >   		pr_err("LED brightness update failed\n");
> >   }
> > 
> >   static enum led_brightness global_led_get(struct led_classdev *led_cdev)
> >   {
> > -	return global_brightness;
> > -}
> > -
> > -static struct led_classdev global_led = {
> > -	.brightness_set = global_led_set,
> > -	.brightness_get = global_led_get,
> > -	.name = "alienware::global_brightness",
> > -};
> > -
> > -static int alienware_zone_init(struct platform_device *dev)
> > -{
> > -	if (interface == WMAX) {
> > -		lighting_control_state = WMAX_RUNNING;
> > -	} else if (interface == LEGACY) {
> > -		lighting_control_state = LEGACY_RUNNING;
> > -	}
> > -	global_led.max_brightness = 0x0F;
> > -	global_brightness = global_led.max_brightness;
> > +	struct alienfx_priv *priv;
> > 
> > -	return led_classdev_register(&dev->dev, &global_led);
> > -}
> > +	priv = container_of(led_cdev, struct alienfx_priv, global_led);
> 
> Same as above.

Ack all of these.

> 
> > 
> > -static void alienware_zone_exit(struct platform_device *dev)
> > -{
> > -	led_classdev_unregister(&global_led);
> > +	return priv->global_brightness;
> >   }
> > 
> >   static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
> > @@ -1106,6 +1111,32 @@ static void remove_thermal_profile(void)
> >   /*
> >    * Platform Driver
> >    */
> > +static int alienfx_probe(struct platform_device *pdev)
> > +{
> > +	struct alienfx_priv *priv;
> > +	struct led_classdev *leds;
> > +
> > +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> 
> Missing error handling.

Thanks!

> 
> > +	platform_set_drvdata(pdev, priv);
> > +
> > +	priv->pdev = pdev;
> > +
> > +	if (interface == WMAX)
> > +		priv->lighting_control_state = WMAX_RUNNING;
> > +	else if (interface == LEGACY)
> > +		priv->lighting_control_state = LEGACY_RUNNING;
> > +
> > +	leds = &priv->global_led;
> 
> I do not think that "leds" has any real benefit here, please use "priv->global_led" directly.

Removed.

> 
> Thanks,
> Armin Wolf
> 
> > +	leds->name = "alienware::global_brightness";
> > +	leds->brightness_set = global_led_set;
> > +	leds->brightness_get = global_led_get;
> > +	leds->max_brightness = 0x0F;
> > +
> > +	priv->global_brightness = priv->global_led.max_brightness;
> > +
> > +	return devm_led_classdev_register(&pdev->dev, &priv->global_led);
> > +}
> > +
> >   static const struct attribute_group *alienfx_groups[] = {
> >   	&zone_attribute_group,
> >   	&hdmi_attribute_group,
> > @@ -1119,6 +1150,7 @@ static struct platform_driver platform_driver = {
> >   		.name = "alienware-wmi",
> >   		.dev_groups = alienfx_groups,
> >   	},
> > +	.probe = alienfx_probe,
> >   };
> > 
> >   static int __init alienware_wmi_init(void)
> > @@ -1166,15 +1198,8 @@ static int __init alienware_wmi_init(void)
> >   			goto fail_prep_thermal_profile;
> >   	}
> > 
> > -	ret = alienware_zone_init(platform_device);
> > -	if (ret)
> > -		goto fail_prep_zones;
> > -
> >   	return 0;
> > 
> > -fail_prep_zones:
> > -	alienware_zone_exit(platform_device);
> > -	remove_thermal_profile();
> >   fail_prep_thermal_profile:
> >   	platform_device_del(platform_device);
> >   fail_platform_device2:
> > @@ -1189,7 +1214,6 @@ module_init(alienware_wmi_init);
> > 
> >   static void __exit alienware_wmi_exit(void)
> >   {
> > -	alienware_zone_exit(platform_device);
> >   	remove_thermal_profile();
> >   	platform_device_unregister(platform_device);
> >   	platform_driver_unregister(&platform_driver);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 08/20] alienware-wmi: Add WMI Drivers
  2024-12-27  3:21   ` Armin Wolf
@ 2024-12-27  4:44     ` Kurt Borja
  2024-12-27  4:48       ` Kurt Borja
  2024-12-29  0:26       ` Armin Wolf
  0 siblings, 2 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:44 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 04:21:14AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Add WMI drivers for LEGACY and WMAX devices.
> > 
> > This involves moving platform driver and device registration to a helper
> > function, which is now called from the driver's preferred WMI device
> > driver probe. However this is only done if !quirks->thermal because
> > newer WMAX interface doesn't support any of the features exposed by this
> > device.
> > 
> > Only one driver is registered on module initialization to prevent
> > registering duplicate platform driver and device.
> > 
> > Aditionally, create_thermal_profile() now takes wmi_device * instead of
> > platform_device *.
> 
> Since the HDMI, Amplifier and deepslp groups depend on the WMAX interface i would
> register them inside wmax_wmi_probe() using device_add_groups() (you might need to
> rework alienware_alienfx_setup() for that).
> 
> In the end the only code shared between both drivers should be related to the LED handling.
> Everything else AFAIK depends on the WMAX interface and should therefore be inside the
> WMAX driver.

Unfortunately this breaks old user-space interface, as the path to this
attributes would change :(. This is why I can't even set a parent dev
for the platform_device.

I only know of one project which interefaces with this driver [1], and
it does use the /sys/devices/platform/alienware-wmi path. Maybe I could
send a pull req, but it would still break old unknown projects and
scripts.

[1] https://crates.io/crates/alienware

> 
> Thanks,
> Armin Wolf
> 
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 186 +++++++++++++++++-----
> >   1 file changed, 146 insertions(+), 40 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index 4b68d64bd742..f2f6842e27e6 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -15,6 +15,7 @@
> >   #include <linux/platform_profile.h>
> >   #include <linux/dmi.h>
> >   #include <linux/leds.h>
> > +#include <linux/wmi.h>
> > 
> >   #define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
> >   #define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> > @@ -39,8 +40,6 @@
> >   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
> >   MODULE_DESCRIPTION("Alienware special feature control");
> >   MODULE_LICENSE("GPL");
> > -MODULE_ALIAS("wmi:" LEGACY_CONTROL_GUID);
> > -MODULE_ALIAS("wmi:" WMAX_CONTROL_GUID);
> > 
> >   static bool force_platform_profile;
> >   module_param_unsafe(force_platform_profile, bool, 0);
> > @@ -412,7 +411,10 @@ struct alienfx_priv {
> >   	u8 lighting_control_state;
> >   };
> > 
> > -static struct platform_device *platform_device;
> > +struct alienfx_platdata {
> > +	struct wmi_device *wdev;
> > +};
> > +
> >   static struct platform_profile_handler pp_handler;
> >   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> > 
> > @@ -1048,7 +1050,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
> >   	return wmax_thermal_control(supported_thermal_profiles[profile]);
> >   }
> > 
> > -static int create_thermal_profile(struct platform_device *platform_device)
> > +static int create_thermal_profile(struct wmi_device *wdev)
> >   {
> >   	enum platform_profile_option profile;
> >   	enum wmax_thermal_mode mode;
> > @@ -1097,7 +1099,7 @@ static int create_thermal_profile(struct platform_device *platform_device)
> >   	pp_handler.profile_get = thermal_profile_get;
> >   	pp_handler.profile_set = thermal_profile_set;
> >   	pp_handler.name = "alienware-wmi";
> > -	pp_handler.dev = &platform_device->dev;
> > +	pp_handler.dev = &wdev->dev;
> > 
> >   	return platform_profile_register(&pp_handler);
> >   }
> > @@ -1153,19 +1155,138 @@ static struct platform_driver platform_driver = {
> >   	.probe = alienfx_probe,
> >   };
> > 
> > -static int __init alienware_wmi_init(void)
> > +static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
> >   {
> > +	struct platform_device *pdev;
> >   	int ret;
> > 
> > -	if (wmi_has_guid(LEGACY_CONTROL_GUID))
> > -		interface = LEGACY;
> > -	else if (wmi_has_guid(WMAX_CONTROL_GUID))
> > -		interface = WMAX;
> > -	else {
> > -		pr_warn("alienware-wmi: No known WMI GUID found\n");
> > -		return -ENODEV;
> > +	ret = platform_driver_register(&platform_driver);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	pdev = platform_device_register_data(NULL, "alienware-wmi",
> > +					     PLATFORM_DEVID_NONE, pdata,
> > +					     sizeof(*pdata));
> > +
> > +	if (IS_ERR(pdev)) {
> > +		platform_driver_unregister(&platform_driver);
> > +		return PTR_ERR(pdev);
> >   	}
> > 
> > +	dev_set_drvdata(&pdata->wdev->dev, pdev);
> > +
> > +	return 0;
> > +}
> > +
> > +static void alienware_alienfx_exit(struct wmi_device *wdev)
> > +{
> > +	struct platform_device *pdev;
> > +
> > +	pdev = dev_get_drvdata(&wdev->dev);
> > +
> > +	platform_device_unregister(pdev);
> > +	platform_driver_unregister(&platform_driver);
> > +}
> > +
> > +/*
> > + * Legacy WMI driver
> > + */
> > +static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
> > +{
> > +	struct alienfx_platdata pdata = {
> > +		.wdev = wdev,
> > +	};
> > +
> > +	return alienware_alienfx_setup(&pdata);
> > +}
> > +
> > +static void legacy_wmi_remove(struct wmi_device *wdev)
> > +{
> > +	alienware_alienfx_exit(wdev);
> > +}
> > +
> > +static struct wmi_device_id alienware_legacy_device_id_table[] = {
> > +	{ LEGACY_CONTROL_GUID, NULL },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
> > +
> > +static struct wmi_driver alienware_legacy_wmi_driver = {
> > +	.driver = {
> > +		.name = "alienware-wmi-alienfx",
> > +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> > +	},
> > +	.id_table = alienware_legacy_device_id_table,
> > +	.probe = legacy_wmi_probe,
> > +	.remove = legacy_wmi_remove,
> > +};
> > +
> > +static int __init alienware_legacy_wmi_init(void)
> > +{
> > +	return wmi_driver_register(&alienware_legacy_wmi_driver);
> > +}
> > +
> > +static void __exit alienware_legacy_wmi_exit(void)
> > +{
> > +	wmi_driver_unregister(&alienware_legacy_wmi_driver);
> > +}
> > +
> > +/*
> > + * WMAX WMI driver
> > + */
> > +static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> > +{
> > +	struct alienfx_platdata pdata = {
> > +		.wdev = wdev,
> > +	};
> > +	int ret = 0;
> > +
> > +	if (quirks->thermal)
> > +		ret = create_thermal_profile(wdev);
> > +	else
> > +		ret = alienware_alienfx_setup(&pdata);
> > +
> > +	return ret;
> > +}
> > +
> > +static void wmax_wmi_remove(struct wmi_device *wdev)
> > +{
> > +	if (quirks->thermal)
> > +		remove_thermal_profile();
> > +	else
> > +		alienware_alienfx_exit(wdev);
> > +}
> > +
> > +static struct wmi_device_id alienware_wmax_device_id_table[] = {
> > +	{ WMAX_CONTROL_GUID, NULL },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
> > +
> > +static struct wmi_driver alienware_wmax_wmi_driver = {
> > +	.driver = {
> > +		.name = "alienware-wmi-wmax",
> > +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> > +	},
> > +	.id_table = alienware_wmax_device_id_table,
> > +	.probe = wmax_wmi_probe,
> > +	.remove = wmax_wmi_remove,
> > +};
> > +
> > +static int __init alienware_wmax_wmi_init(void)
> > +{
> > +	return wmi_driver_register(&alienware_wmax_wmi_driver);
> > +}
> > +
> > +static void __exit alienware_wmax_wmi_exit(void)
> > +{
> > +	wmi_driver_unregister(&alienware_wmax_wmi_driver);
> > +}
> > +
> > +static int __init alienware_wmi_init(void)
> > +{
> > +	int ret;
> > +
> >   	dmi_check_system(alienware_quirks);
> >   	if (quirks == NULL)
> >   		quirks = &quirk_unknown;
> > @@ -1180,43 +1301,28 @@ static int __init alienware_wmi_init(void)
> >   			pr_warn("force_gmode requires platform profile support\n");
> >   	}
> > 
> > -	ret = platform_driver_register(&platform_driver);
> > -	if (ret)
> > -		goto fail_platform_driver;
> > -	platform_device = platform_device_alloc("alienware-wmi", PLATFORM_DEVID_NONE);
> > -	if (!platform_device) {
> > -		ret = -ENOMEM;
> > -		goto fail_platform_device1;
> > +	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
> > +		interface = WMAX;
> > +		ret = alienware_wmax_wmi_init();
> > +	} else {
> > +		interface = LEGACY;
> > +		ret = alienware_legacy_wmi_init();
> >   	}
> > -	ret = platform_device_add(platform_device);
> > -	if (ret)
> > -		goto fail_platform_device2;
> > 
> > -	if (quirks->thermal) {
> > -		ret = create_thermal_profile(platform_device);
> > -		if (ret)
> > -			goto fail_prep_thermal_profile;
> > -	}
> > +	if (ret < 0)
> > +		return ret;
> > 
> >   	return 0;
> > -
> > -fail_prep_thermal_profile:
> > -	platform_device_del(platform_device);
> > -fail_platform_device2:
> > -	platform_device_put(platform_device);
> > -fail_platform_device1:
> > -	platform_driver_unregister(&platform_driver);
> > -fail_platform_driver:
> > -	return ret;
> >   }
> > 
> >   module_init(alienware_wmi_init);
> > 
> >   static void __exit alienware_wmi_exit(void)
> >   {
> > -	remove_thermal_profile();
> > -	platform_device_unregister(platform_device);
> > -	platform_driver_unregister(&platform_driver);
> > +	if (interface == WMAX)
> > +		alienware_wmax_wmi_exit();
> > +	else
> > +		alienware_legacy_wmi_exit();
> >   }
> > 
> >   module_exit(alienware_wmi_exit);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 08/20] alienware-wmi: Add WMI Drivers
  2024-12-27  4:44     ` Kurt Borja
@ 2024-12-27  4:48       ` Kurt Borja
  2024-12-29  0:26       ` Armin Wolf
  1 sibling, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:48 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Thu, Dec 26, 2024 at 11:44:52PM -0500, Kurt Borja wrote:
> On Fri, Dec 27, 2024 at 04:21:14AM +0100, Armin Wolf wrote:
> > Am 21.12.24 um 06:59 schrieb Kurt Borja:
> > 
> > > Add WMI drivers for LEGACY and WMAX devices.
> > > 
> > > This involves moving platform driver and device registration to a helper
> > > function, which is now called from the driver's preferred WMI device
> > > driver probe. However this is only done if !quirks->thermal because
> > > newer WMAX interface doesn't support any of the features exposed by this
> > > device.
> > > 
> > > Only one driver is registered on module initialization to prevent
> > > registering duplicate platform driver and device.
> > > 
> > > Aditionally, create_thermal_profile() now takes wmi_device * instead of
> > > platform_device *.
> > 
> > Since the HDMI, Amplifier and deepslp groups depend on the WMAX interface i would
> > register them inside wmax_wmi_probe() using device_add_groups() (you might need to
> > rework alienware_alienfx_setup() for that).
> > 
> > In the end the only code shared between both drivers should be related to the LED handling.
> > Everything else AFAIK depends on the WMAX interface and should therefore be inside the
> > WMAX driver.
> 
> Unfortunately this breaks old user-space interface, as the path to this
> attributes would change :(. This is why I can't even set a parent dev
> for the platform_device.
> 
> I only know of one project which interefaces with this driver [1], and
> it does use the /sys/devices/platform/alienware-wmi path. Maybe I could
> send a pull req, but it would still break old unknown projects and
> scripts.
> 
> [1] https://crates.io/crates/alienware

Nevermind this, I thought you said .dev_groups xd. I will do this on v2.

> 
> > 
> > Thanks,
> > Armin Wolf
> > 
> > > 
> > > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > > ---
> > >   drivers/platform/x86/dell/alienware-wmi.c | 186 +++++++++++++++++-----
> > >   1 file changed, 146 insertions(+), 40 deletions(-)
> > > 
> > > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > > index 4b68d64bd742..f2f6842e27e6 100644
> > > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > > @@ -15,6 +15,7 @@
> > >   #include <linux/platform_profile.h>
> > >   #include <linux/dmi.h>
> > >   #include <linux/leds.h>
> > > +#include <linux/wmi.h>
> > > 
> > >   #define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
> > >   #define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> > > @@ -39,8 +40,6 @@
> > >   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
> > >   MODULE_DESCRIPTION("Alienware special feature control");
> > >   MODULE_LICENSE("GPL");
> > > -MODULE_ALIAS("wmi:" LEGACY_CONTROL_GUID);
> > > -MODULE_ALIAS("wmi:" WMAX_CONTROL_GUID);
> > > 
> > >   static bool force_platform_profile;
> > >   module_param_unsafe(force_platform_profile, bool, 0);
> > > @@ -412,7 +411,10 @@ struct alienfx_priv {
> > >   	u8 lighting_control_state;
> > >   };
> > > 
> > > -static struct platform_device *platform_device;
> > > +struct alienfx_platdata {
> > > +	struct wmi_device *wdev;
> > > +};
> > > +
> > >   static struct platform_profile_handler pp_handler;
> > >   static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> > > 
> > > @@ -1048,7 +1050,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
> > >   	return wmax_thermal_control(supported_thermal_profiles[profile]);
> > >   }
> > > 
> > > -static int create_thermal_profile(struct platform_device *platform_device)
> > > +static int create_thermal_profile(struct wmi_device *wdev)
> > >   {
> > >   	enum platform_profile_option profile;
> > >   	enum wmax_thermal_mode mode;
> > > @@ -1097,7 +1099,7 @@ static int create_thermal_profile(struct platform_device *platform_device)
> > >   	pp_handler.profile_get = thermal_profile_get;
> > >   	pp_handler.profile_set = thermal_profile_set;
> > >   	pp_handler.name = "alienware-wmi";
> > > -	pp_handler.dev = &platform_device->dev;
> > > +	pp_handler.dev = &wdev->dev;
> > > 
> > >   	return platform_profile_register(&pp_handler);
> > >   }
> > > @@ -1153,19 +1155,138 @@ static struct platform_driver platform_driver = {
> > >   	.probe = alienfx_probe,
> > >   };
> > > 
> > > -static int __init alienware_wmi_init(void)
> > > +static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
> > >   {
> > > +	struct platform_device *pdev;
> > >   	int ret;
> > > 
> > > -	if (wmi_has_guid(LEGACY_CONTROL_GUID))
> > > -		interface = LEGACY;
> > > -	else if (wmi_has_guid(WMAX_CONTROL_GUID))
> > > -		interface = WMAX;
> > > -	else {
> > > -		pr_warn("alienware-wmi: No known WMI GUID found\n");
> > > -		return -ENODEV;
> > > +	ret = platform_driver_register(&platform_driver);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	pdev = platform_device_register_data(NULL, "alienware-wmi",
> > > +					     PLATFORM_DEVID_NONE, pdata,
> > > +					     sizeof(*pdata));
> > > +
> > > +	if (IS_ERR(pdev)) {
> > > +		platform_driver_unregister(&platform_driver);
> > > +		return PTR_ERR(pdev);
> > >   	}
> > > 
> > > +	dev_set_drvdata(&pdata->wdev->dev, pdev);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static void alienware_alienfx_exit(struct wmi_device *wdev)
> > > +{
> > > +	struct platform_device *pdev;
> > > +
> > > +	pdev = dev_get_drvdata(&wdev->dev);
> > > +
> > > +	platform_device_unregister(pdev);
> > > +	platform_driver_unregister(&platform_driver);
> > > +}
> > > +
> > > +/*
> > > + * Legacy WMI driver
> > > + */
> > > +static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
> > > +{
> > > +	struct alienfx_platdata pdata = {
> > > +		.wdev = wdev,
> > > +	};
> > > +
> > > +	return alienware_alienfx_setup(&pdata);
> > > +}
> > > +
> > > +static void legacy_wmi_remove(struct wmi_device *wdev)
> > > +{
> > > +	alienware_alienfx_exit(wdev);
> > > +}
> > > +
> > > +static struct wmi_device_id alienware_legacy_device_id_table[] = {
> > > +	{ LEGACY_CONTROL_GUID, NULL },
> > > +	{ },
> > > +};
> > > +MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
> > > +
> > > +static struct wmi_driver alienware_legacy_wmi_driver = {
> > > +	.driver = {
> > > +		.name = "alienware-wmi-alienfx",
> > > +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> > > +	},
> > > +	.id_table = alienware_legacy_device_id_table,
> > > +	.probe = legacy_wmi_probe,
> > > +	.remove = legacy_wmi_remove,
> > > +};
> > > +
> > > +static int __init alienware_legacy_wmi_init(void)
> > > +{
> > > +	return wmi_driver_register(&alienware_legacy_wmi_driver);
> > > +}
> > > +
> > > +static void __exit alienware_legacy_wmi_exit(void)
> > > +{
> > > +	wmi_driver_unregister(&alienware_legacy_wmi_driver);
> > > +}
> > > +
> > > +/*
> > > + * WMAX WMI driver
> > > + */
> > > +static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> > > +{
> > > +	struct alienfx_platdata pdata = {
> > > +		.wdev = wdev,
> > > +	};
> > > +	int ret = 0;
> > > +
> > > +	if (quirks->thermal)
> > > +		ret = create_thermal_profile(wdev);
> > > +	else
> > > +		ret = alienware_alienfx_setup(&pdata);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void wmax_wmi_remove(struct wmi_device *wdev)
> > > +{
> > > +	if (quirks->thermal)
> > > +		remove_thermal_profile();
> > > +	else
> > > +		alienware_alienfx_exit(wdev);
> > > +}
> > > +
> > > +static struct wmi_device_id alienware_wmax_device_id_table[] = {
> > > +	{ WMAX_CONTROL_GUID, NULL },
> > > +	{ },
> > > +};
> > > +MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
> > > +
> > > +static struct wmi_driver alienware_wmax_wmi_driver = {
> > > +	.driver = {
> > > +		.name = "alienware-wmi-wmax",
> > > +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
> > > +	},
> > > +	.id_table = alienware_wmax_device_id_table,
> > > +	.probe = wmax_wmi_probe,
> > > +	.remove = wmax_wmi_remove,
> > > +};
> > > +
> > > +static int __init alienware_wmax_wmi_init(void)
> > > +{
> > > +	return wmi_driver_register(&alienware_wmax_wmi_driver);
> > > +}
> > > +
> > > +static void __exit alienware_wmax_wmi_exit(void)
> > > +{
> > > +	wmi_driver_unregister(&alienware_wmax_wmi_driver);
> > > +}
> > > +
> > > +static int __init alienware_wmi_init(void)
> > > +{
> > > +	int ret;
> > > +
> > >   	dmi_check_system(alienware_quirks);
> > >   	if (quirks == NULL)
> > >   		quirks = &quirk_unknown;
> > > @@ -1180,43 +1301,28 @@ static int __init alienware_wmi_init(void)
> > >   			pr_warn("force_gmode requires platform profile support\n");
> > >   	}
> > > 
> > > -	ret = platform_driver_register(&platform_driver);
> > > -	if (ret)
> > > -		goto fail_platform_driver;
> > > -	platform_device = platform_device_alloc("alienware-wmi", PLATFORM_DEVID_NONE);
> > > -	if (!platform_device) {
> > > -		ret = -ENOMEM;
> > > -		goto fail_platform_device1;
> > > +	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
> > > +		interface = WMAX;
> > > +		ret = alienware_wmax_wmi_init();
> > > +	} else {
> > > +		interface = LEGACY;
> > > +		ret = alienware_legacy_wmi_init();
> > >   	}
> > > -	ret = platform_device_add(platform_device);
> > > -	if (ret)
> > > -		goto fail_platform_device2;
> > > 
> > > -	if (quirks->thermal) {
> > > -		ret = create_thermal_profile(platform_device);
> > > -		if (ret)
> > > -			goto fail_prep_thermal_profile;
> > > -	}
> > > +	if (ret < 0)
> > > +		return ret;
> > > 
> > >   	return 0;
> > > -
> > > -fail_prep_thermal_profile:
> > > -	platform_device_del(platform_device);
> > > -fail_platform_device2:
> > > -	platform_device_put(platform_device);
> > > -fail_platform_device1:
> > > -	platform_driver_unregister(&platform_driver);
> > > -fail_platform_driver:
> > > -	return ret;
> > >   }
> > > 
> > >   module_init(alienware_wmi_init);
> > > 
> > >   static void __exit alienware_wmi_exit(void)
> > >   {
> > > -	remove_thermal_profile();
> > > -	platform_device_unregister(platform_device);
> > > -	platform_driver_unregister(&platform_driver);
> > > +	if (interface == WMAX)
> > > +		alienware_wmax_wmi_exit();
> > > +	else
> > > +		alienware_legacy_wmi_exit();
> > >   }
> > > 
> > >   module_exit(alienware_wmi_exit);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods
  2024-12-27  3:26   ` Armin Wolf
@ 2024-12-27  4:50     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:50 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 04:26:05AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Refactor all thermal control methods to use the newly defined awcc_priv
> > state container instead of global variables.
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 71 +++++++++++++++++------
> >   1 file changed, 52 insertions(+), 19 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index f2f6842e27e6..c4ca141d628e 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -403,6 +403,12 @@ struct wmax_u32_args {
> >   	u8 arg3;
> >   };
> > 
> > +struct awcc_priv {
> > +	struct wmi_device *wdev;
> > +	struct platform_profile_handler pp_handler;
> > +	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> > +};
> > +
> >   struct alienfx_priv {
> >   	struct platform_device *pdev;
> >   	struct led_classdev global_led;
> > @@ -415,9 +421,6 @@ struct alienfx_platdata {
> >   	struct wmi_device *wdev;
> >   };
> > 
> > -static struct platform_profile_handler pp_handler;
> > -static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> > -
> >   static u8 interface;
> > 
> >   /*
> > @@ -1027,6 +1030,10 @@ static int thermal_profile_get(struct platform_profile_handler *pprof,
> >   static int thermal_profile_set(struct platform_profile_handler *pprof,
> >   			       enum platform_profile_option profile)
> >   {
> > +	struct awcc_priv *priv;
> > +
> > +	priv = container_of(pprof, struct awcc_priv, pp_handler);
> 
> Please merge those two statements.

Ack.

> 
> > +
> >   	if (quirks->gmode) {
> >   		u32 gmode_status;
> >   		int ret;
> > @@ -1047,18 +1054,21 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
> >   		}
> >   	}
> > 
> > -	return wmax_thermal_control(supported_thermal_profiles[profile]);
> > +	return wmax_thermal_control(priv->supported_thermal_profiles[profile]);
> >   }
> > 
> >   static int create_thermal_profile(struct wmi_device *wdev)
> >   {
> >   	enum platform_profile_option profile;
> >   	enum wmax_thermal_mode mode;
> > +	struct awcc_priv *priv;
> >   	u8 sys_desc[4];
> >   	u32 first_mode;
> >   	u32 out_data;
> >   	int ret;
> > 
> > +	priv = dev_get_drvdata(&wdev->dev);
> 
> Same as above.

Ack.

> 
> > +
> >   	ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
> >   				       0, (u32 *) &sys_desc);
> >   	if (ret < 0)
> > @@ -1081,33 +1091,56 @@ static int create_thermal_profile(struct wmi_device *wdev)
> > 
> >   		mode = out_data & WMAX_THERMAL_MODE_MASK;
> >   		profile = wmax_mode_to_platform_profile[mode];
> > -		supported_thermal_profiles[profile] = out_data;
> > +		priv->supported_thermal_profiles[profile] = out_data;
> > 
> > -		set_bit(profile, pp_handler.choices);
> > +		set_bit(profile, priv->pp_handler.choices);
> >   	}
> > 
> > -	if (bitmap_empty(pp_handler.choices, PLATFORM_PROFILE_LAST))
> > +	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
> >   		return -ENODEV;
> > 
> >   	if (quirks->gmode) {
> > -		supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
> > +		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
> >   			WMAX_THERMAL_MODE_GMODE;
> > 
> > -		set_bit(PLATFORM_PROFILE_PERFORMANCE, pp_handler.choices);
> > +		set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->pp_handler.choices);
> >   	}
> > 
> > -	pp_handler.profile_get = thermal_profile_get;
> > -	pp_handler.profile_set = thermal_profile_set;
> > -	pp_handler.name = "alienware-wmi";
> > -	pp_handler.dev = &wdev->dev;
> > +	priv->pp_handler.profile_get = thermal_profile_get;
> > +	priv->pp_handler.profile_set = thermal_profile_set;
> > +	priv->pp_handler.name = "alienware-wmi";
> > +	priv->pp_handler.dev = &wdev->dev;
> > 
> > -	return platform_profile_register(&pp_handler);
> > +	return platform_profile_register(&priv->pp_handler);
> >   }
> > 
> > -static void remove_thermal_profile(void)
> > +static int alienware_awcc_setup(struct wmi_device *wdev)
> >   {
> > -	if (quirks->thermal)
> > -		platform_profile_remove(&pp_handler);
> > +	struct awcc_priv *priv;
> > +	int ret;
> > +
> > +	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	dev_set_drvdata(&wdev->dev, priv);
> > +
> > +	priv->wdev = wdev;
> > +
> > +	ret = create_thermal_profile(wdev);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	return 0;
> 
> Just directly return the result of create_thermal_profile() here.

Ack.

> 
> With those minor issues being fixed:
> 
> Reviewed-by: Armin Wolf <W_Armin@gmx.de>

Thanks!

> 
> > +}
> > +
> > +static void alienware_awcc_exit(struct wmi_device *wdev)
> > +{
> > +	struct awcc_priv *priv;
> > +
> > +	priv = dev_get_drvdata(&wdev->dev);
> 
> Please merge both statements.
> 
> > +
> > +	platform_profile_remove(&priv->pp_handler);
> >   }
> > 
> >   /*
> > @@ -1242,7 +1275,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> >   	int ret = 0;
> > 
> >   	if (quirks->thermal)
> > -		ret = create_thermal_profile(wdev);
> > +		ret = alienware_awcc_setup(wdev);
> >   	else
> >   		ret = alienware_alienfx_setup(&pdata);
> > 
> > @@ -1252,7 +1285,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> >   static void wmax_wmi_remove(struct wmi_device *wdev)
> >   {
> >   	if (quirks->thermal)
> > -		remove_thermal_profile();
> > +		alienware_awcc_exit(wdev);
> >   	else
> >   		alienware_alienfx_exit(wdev);
> >   }

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] alienware-wmi: Refactor LED control methods
  2024-12-27  3:41   ` Armin Wolf
@ 2024-12-27  4:52     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:52 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 04:41:36AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Both WMI devices handled by this module specify a distinct interface for
> > LED control. Previously this module handled this by dynamically adapting
> > arguments passed to wmi_evaluate_method() based on the `interface`
> > global variable.
> > 
> > To avoid the use of global variables, and enable the migration to
> > non-deprecated WMI methods, let the WMI drivers define upd_led and
> > upd_brightness operations, which completely replace
> > alienware_update_led() and wmax_brightness().
> > 
> > Also define alienware_wmi_command(), which serves as a wrapper for
> > wmidev_evaluate_method(). This new method is very similar to
> > alienware_wmax_command() but is WMI device agnostic.
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 180 ++++++++++++++--------
> >   1 file changed, 118 insertions(+), 62 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index c4ca141d628e..bcf3b2f80dfd 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -417,12 +417,46 @@ struct alienfx_priv {
> >   	u8 lighting_control_state;
> >   };
> > 
> > +struct alienfx_ops {
> > +	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
> > +		       u8 location);
> > +	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
> > +			      u8 brightness);
> > +};
> > +
> >   struct alienfx_platdata {
> >   	struct wmi_device *wdev;
> > +	struct alienfx_ops ops;
> >   };
> > 
> >   static u8 interface;
> > 
> > +static acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> > +					 void *in_args, size_t in_size, u32 *out_data)
> 
> Please return a errno here instead of acpi_status.

Ack!

> 
> > +{
> > +	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
> > +	struct acpi_buffer in = {in_size, in_args};
> > +	union acpi_object *obj;
> > +	acpi_status ret;
> > +
> > +	if (out_data) {
> > +		ret = wmidev_evaluate_method(wdev, 0, method_id, &in, &out);
> > +		if (ACPI_FAILURE(ret))
> > +			goto out_free_ptr;
> 
> Just return -EIO here as out.pointer will contain no valid data in this case.

I wasn't sure of this. Thanks.

> 
> > +
> > +		obj = (union acpi_object *)out.pointer;
> 
> Unnecessary cast.

Ack.

> 
> > +
> > +		if (obj && obj->type == ACPI_TYPE_INTEGER)
> > +			*out_data = (u32)obj->integer.value;
> 
> Please move the code for freeing "obj" to this line.

Ack.

> 
> > +	} else {
> > +		ret = wmidev_evaluate_method(wdev, 0, method_id, &in, NULL);
> > +	}
> > +
> > +out_free_ptr:
> > +	kfree(out.pointer);
> > +	return ret;
> > +}
> > +
> >   /*
> >    * Helpers used for zone control
> >    */
> > @@ -453,46 +487,6 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
> >   /*
> >    * Individual RGB zone control
> >    */
> > -static int alienware_update_led(struct alienfx_priv *priv, u8 location)
> > -{
> > -	int method_id;
> > -	acpi_status status;
> > -	char *guid;
> > -	struct acpi_buffer input;
> > -	struct legacy_led_args legacy_args;
> > -	struct wmax_led_args wmax_basic_args;
> > -	if (interface == WMAX) {
> > -		wmax_basic_args.led_mask = 1 << location;
> > -		wmax_basic_args.colors = priv->colors[location];
> > -		wmax_basic_args.state = priv->lighting_control_state;
> > -		guid = WMAX_CONTROL_GUID;
> > -		method_id = WMAX_METHOD_ZONE_CONTROL;
> > -
> > -		input.length = sizeof(wmax_basic_args);
> > -		input.pointer = &wmax_basic_args;
> > -	} else {
> > -		legacy_args.colors = priv->colors[location];
> > -		legacy_args.brightness = priv->global_brightness;
> > -		legacy_args.state = 0;
> > -		if (priv->lighting_control_state == LEGACY_BOOTING ||
> > -		    priv->lighting_control_state == LEGACY_SUSPEND) {
> > -			guid = LEGACY_POWER_CONTROL_GUID;
> > -			legacy_args.state = priv->lighting_control_state;
> > -		} else
> > -			guid = LEGACY_CONTROL_GUID;
> > -		method_id = location + 1;
> > -
> > -		input.length = sizeof(legacy_args);
> > -		input.pointer = &legacy_args;
> > -	}
> > -	pr_debug("alienware-wmi: guid %s method %d\n", guid, method_id);
> > -
> > -	status = wmi_evaluate_method(guid, 0, method_id, &input, NULL);
> > -	if (ACPI_FAILURE(status))
> > -		pr_err("alienware-wmi: zone set failure: %u\n", status);
> > -	return ACPI_FAILURE(status);
> > -}
> > -
> >   static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
> >   			 char *buf, u8 location)
> >   {
> > @@ -510,18 +504,20 @@ static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
> >   static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
> >   			  const char *buf, size_t count, u8 location)
> >   {
> > +	struct alienfx_platdata *pdata;
> >   	struct color_platform *colors;
> >   	struct alienfx_priv *priv;
> >   	int ret;
> > 
> >   	priv = dev_get_drvdata(dev);
> > +	pdata = dev_get_platdata(dev);
> >   	colors = &priv->colors[location];
> > 
> >   	ret = parse_rgb(buf, colors);
> >   	if (ret)
> >   		return ret;
> > 
> > -	ret = alienware_update_led(priv, location);
> > +	ret = pdata->ops.upd_led(priv, pdata->wdev, location);
> > 
> >   	return ret ? ret : count;
> >   }
> > @@ -628,35 +624,19 @@ static struct attribute_group zone_attribute_group = {
> >   /*
> >    * LED Brightness (Global)
> >    */
> > -static int wmax_brightness(int brightness)
> > -{
> > -	acpi_status status;
> > -	struct acpi_buffer input;
> > -	struct wmax_brightness_args args = {
> > -		.led_mask = 0xFF,
> > -		.percentage = brightness,
> > -	};
> > -	input.length = sizeof(args);
> > -	input.pointer = &args;
> > -	status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
> > -				     WMAX_METHOD_BRIGHTNESS, &input, NULL);
> > -	if (ACPI_FAILURE(status))
> > -		pr_err("alienware-wmi: brightness set failure: %u\n", status);
> > -	return ACPI_FAILURE(status);
> > -}
> > -
> >   static void global_led_set(struct led_classdev *led_cdev,
> >   			   enum led_brightness brightness)
> >   {
> > +	struct alienfx_platdata *pdata;
> >   	struct alienfx_priv *priv;
> >   	int ret;
> > 
> >   	priv = container_of(led_cdev, struct alienfx_priv, global_led);
> > +	pdata = dev_get_platdata(&priv->pdev->dev);
> > +
> >   	priv->global_brightness = brightness;
> > -	if (interface == WMAX)
> > -		ret = wmax_brightness(brightness);
> > -	else
> > -		ret = alienware_update_led(priv, 0);
> > +
> > +	ret = pdata->ops.upd_brightness(priv, pdata->wdev, brightness);
> >   	if (ret)
> >   		pr_err("LED brightness update failed\n");
> >   }
> > @@ -1224,10 +1204,47 @@ static void alienware_alienfx_exit(struct wmi_device *wdev)
> >   /*
> >    * Legacy WMI driver
> >    */
> > +static int legacy_wmi_update_led(struct alienfx_priv *priv,
> > +				 struct wmi_device *wdev, u8 location)
> > +{
> > +	struct legacy_led_args legacy_args;
> > +	struct acpi_buffer input;
> > +	acpi_status status;
> > +
> > +	legacy_args.colors = priv->colors[location];
> > +	legacy_args.brightness = priv->global_brightness;
> > +	legacy_args.state = priv->lighting_control_state;
> 
> The original code set "legacy_args.state" to "0" if "priv->lighting_control_state" was "LEGACY_RUNNING".
> Please keep this behavior.

I missed this. Thanks.

> 
> Thanks,
> Armin Wolf
> 
> > +
> > +	input.length = sizeof(legacy_args);
> > +	input.pointer = &legacy_args;
> > +
> > +	if (legacy_args.state == LEGACY_RUNNING)
> > +		status = alienware_wmi_command(wdev, location + 1, &legacy_args,
> > +					       sizeof(legacy_args), NULL);
> > +	else
> > +		status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
> > +					     location + 1, &input, NULL);
> > +
> > +	if (ACPI_FAILURE(status))
> > +		return -EIO;
> > +
> > +	return 0;
> > +}
> > +
> > +static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
> > +					struct wmi_device *wdev, u8 brightness)
> > +{
> > +	return legacy_wmi_update_led(priv, wdev, 0);
> > +}
> > +
> >   static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
> >   {
> >   	struct alienfx_platdata pdata = {
> >   		.wdev = wdev,
> > +		.ops = {
> > +			.upd_led = legacy_wmi_update_led,
> > +			.upd_brightness = legacy_wmi_update_brightness,
> > +		},
> >   	};
> > 
> >   	return alienware_alienfx_setup(&pdata);
> > @@ -1267,10 +1284,49 @@ static void __exit alienware_legacy_wmi_exit(void)
> >   /*
> >    * WMAX WMI driver
> >    */
> > +static int wmax_wmi_update_led(struct alienfx_priv *priv,
> > +			       struct wmi_device *wdev, u8 location)
> > +{
> > +	struct wmax_led_args in_args = {
> > +		.led_mask = 1 << location,
> > +		.colors = priv->colors[location],
> > +		.state = priv->lighting_control_state,
> > +	};
> > +	acpi_status status;
> > +
> > +	status = alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL,
> > +				       &in_args, sizeof(in_args), NULL);
> > +	if (ACPI_FAILURE(status))
> > +		return -EIO;
> > +
> > +	return 0;
> > +}
> > +
> > +static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
> > +				      struct wmi_device *wdev, u8 brightness)
> > +{
> > +	struct wmax_brightness_args in_args = {
> > +		.led_mask = 0xFF,
> > +		.percentage = brightness,
> > +	};
> > +	acpi_status status;
> > +
> > +	status = alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
> > +				       sizeof(in_args), NULL);
> > +	if (ACPI_FAILURE(status))
> > +		return -EIO;
> > +
> > +	return 0;
> > +}
> > +
> >   static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> >   {
> >   	struct alienfx_platdata pdata = {
> >   		.wdev = wdev,
> > +		.ops = {
> > +			.upd_led = wmax_wmi_update_led,
> > +			.upd_brightness = wmax_wmi_update_brightness,
> > +		},
> >   	};
> >   	int ret = 0;
> > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] alienware-wmi: Split DMI table
  2024-12-27  3:55   ` Armin Wolf
@ 2024-12-27  4:55     ` Kurt Borja
  2024-12-29  0:30       ` Armin Wolf
  0 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:55 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 04:55:28AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Split thermal features into a new DMI table to support upcoming file
> > split.
> 
> Could it be that you also decided to reorder the quirk entries?

No. I'll make this split lower in the file, so it doesn't mess up the
diff.

If I did reorder it by accident I will fix it.

> 
> Thanks,
> Armin WOlf
> 
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi.c | 163 +++++++++-------------
> >   1 file changed, 69 insertions(+), 94 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
> > index 0a0b72dc61ea..8ea08f5f8810 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi.c
> > @@ -118,8 +118,6 @@ struct quirk_entry {
> >   	u8 hdmi_mux;
> >   	u8 amplifier;
> >   	u8 deepslp;
> > -	bool thermal;
> > -	bool gmode;
> >   };
> > 
> >   static struct quirk_entry *quirks;
> > @@ -130,8 +128,6 @@ static struct quirk_entry quirk_inspiron5675 = {
> >   	.hdmi_mux = 0,
> >   	.amplifier = 0,
> >   	.deepslp = 0,
> > -	.thermal = false,
> > -	.gmode = false,
> >   };
> > 
> >   static struct quirk_entry quirk_unknown = {
> > @@ -139,8 +135,6 @@ static struct quirk_entry quirk_unknown = {
> >   	.hdmi_mux = 0,
> >   	.amplifier = 0,
> >   	.deepslp = 0,
> > -	.thermal = false,
> > -	.gmode = false,
> >   };
> > 
> >   static struct quirk_entry quirk_x51_r1_r2 = {
> > @@ -148,8 +142,6 @@ static struct quirk_entry quirk_x51_r1_r2 = {
> >   	.hdmi_mux = 0,
> >   	.amplifier = 0,
> >   	.deepslp = 0,
> > -	.thermal = false,
> > -	.gmode = false,
> >   };
> > 
> >   static struct quirk_entry quirk_x51_r3 = {
> > @@ -157,8 +149,6 @@ static struct quirk_entry quirk_x51_r3 = {
> >   	.hdmi_mux = 0,
> >   	.amplifier = 1,
> >   	.deepslp = 0,
> > -	.thermal = false,
> > -	.gmode = false,
> >   };
> > 
> >   static struct quirk_entry quirk_asm100 = {
> > @@ -166,8 +156,6 @@ static struct quirk_entry quirk_asm100 = {
> >   	.hdmi_mux = 1,
> >   	.amplifier = 0,
> >   	.deepslp = 0,
> > -	.thermal = false,
> > -	.gmode = false,
> >   };
> > 
> >   static struct quirk_entry quirk_asm200 = {
> > @@ -175,8 +163,6 @@ static struct quirk_entry quirk_asm200 = {
> >   	.hdmi_mux = 1,
> >   	.amplifier = 0,
> >   	.deepslp = 1,
> > -	.thermal = false,
> > -	.gmode = false,
> >   };
> > 
> >   static struct quirk_entry quirk_asm201 = {
> > @@ -184,26 +170,6 @@ static struct quirk_entry quirk_asm201 = {
> >   	.hdmi_mux = 1,
> >   	.amplifier = 1,
> >   	.deepslp = 1,
> > -	.thermal = false,
> > -	.gmode = false,
> > -};
> > -
> > -static struct quirk_entry quirk_g_series = {
> > -	.num_zones = 2,
> > -	.hdmi_mux = 0,
> > -	.amplifier = 0,
> > -	.deepslp = 0,
> > -	.thermal = true,
> > -	.gmode = true,
> > -};
> > -
> > -static struct quirk_entry quirk_x_series = {
> > -	.num_zones = 2,
> > -	.hdmi_mux = 0,
> > -	.amplifier = 0,
> > -	.deepslp = 0,
> > -	.thermal = true,
> > -	.gmode = false,
> >   };
> > 
> >   static int __init dmi_matched(const struct dmi_system_id *dmi)
> > @@ -242,133 +208,140 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
> >   	},
> >   	{
> >   		.callback = dmi_matched,
> > -		.ident = "Alienware m17 R5",
> > +		.ident = "Alienware X51 R1",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
> >   		},
> > -		.driver_data = &quirk_x_series,
> > +		.driver_data = &quirk_x51_r1_r2,
> >   	},
> >   	{
> >   		.callback = dmi_matched,
> > -		.ident = "Alienware m18 R2",
> > +		.ident = "Alienware X51 R2",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
> >   		},
> > -		.driver_data = &quirk_x_series,
> > +		.driver_data = &quirk_x51_r1_r2,
> >   	},
> >   	{
> >   		.callback = dmi_matched,
> > -		.ident = "Alienware x15 R1",
> > +		.ident = "Alienware X51 R3",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
> >   		},
> > -		.driver_data = &quirk_x_series,
> > +		.driver_data = &quirk_x51_r3,
> >   	},
> >   	{
> >   		.callback = dmi_matched,
> > -		.ident = "Alienware x17 R2",
> > +		.ident = "Dell Inc. Inspiron 5675",
> > +		.matches = {
> > +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
> > +		},
> > +		.driver_data = &quirk_inspiron5675,
> > +	},
> > +	{}
> > +};
> > +
> > +struct awcc_features {
> > +	bool gmode;
> > +};
> > +
> > +static struct awcc_features g_series_features = {
> > +	.gmode = true,
> > +};
> > +
> > +static struct awcc_features x_series_features = {
> > +	.gmode = false,
> > +};
> > +
> > +static const struct dmi_system_id awcc_dmi_table[] __initconst = {
> > +	{
> > +		.ident = "Alienware m17 R5",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
> >   		},
> > -		.driver_data = &quirk_x_series,
> > +		.driver_data = &x_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> > -		.ident = "Alienware X51 R1",
> > +		.ident = "Alienware m18 R2",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
> >   		},
> > -		.driver_data = &quirk_x51_r1_r2,
> > +		.driver_data = &x_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> > -		.ident = "Alienware X51 R2",
> > +		.ident = "Alienware x15 R1",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
> >   		},
> > -		.driver_data = &quirk_x51_r1_r2,
> > +		.driver_data = &x_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> > -		.ident = "Alienware X51 R3",
> > +		.ident = "Alienware x17 R2",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
> >   		},
> > -		.driver_data = &quirk_x51_r3,
> > +		.driver_data = &x_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> >   		.ident = "Dell Inc. G15 5510",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> >   			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
> >   		},
> > -		.driver_data = &quirk_g_series,
> > +		.driver_data = &g_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> >   		.ident = "Dell Inc. G15 5511",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> >   			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
> >   		},
> > -		.driver_data = &quirk_g_series,
> > +		.driver_data = &g_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> >   		.ident = "Dell Inc. G15 5515",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> >   			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
> >   		},
> > -		.driver_data = &quirk_g_series,
> > +		.driver_data = &g_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> >   		.ident = "Dell Inc. G3 3500",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> >   			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
> >   		},
> > -		.driver_data = &quirk_g_series,
> > +		.driver_data = &g_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> >   		.ident = "Dell Inc. G3 3590",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> >   			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
> >   		},
> > -		.driver_data = &quirk_g_series,
> > +		.driver_data = &g_series_features,
> >   	},
> >   	{
> > -		.callback = dmi_matched,
> >   		.ident = "Dell Inc. G5 5500",
> >   		.matches = {
> >   			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> >   			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
> >   		},
> > -		.driver_data = &quirk_g_series,
> > -	},
> > -	{
> > -		.callback = dmi_matched,
> > -		.ident = "Dell Inc. Inspiron 5675",
> > -		.matches = {
> > -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> > -			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
> > -		},
> > -		.driver_data = &quirk_inspiron5675,
> > +		.driver_data = &g_series_features,
> >   	},
> > -	{}
> >   };
> > 
> > +struct awcc_features *awcc;
> > +
> >   struct color_platform {
> >   	u8 blue;
> >   	u8 green;
> > @@ -1009,7 +982,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
> > 
> >   	priv = container_of(pprof, struct awcc_priv, pp_handler);
> > 
> > -	if (quirks->gmode) {
> > +	if (awcc->gmode) {
> >   		u32 gmode_status;
> >   		int ret;
> > 
> > @@ -1077,7 +1050,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
> >   	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
> >   		return -ENODEV;
> > 
> > -	if (quirks->gmode) {
> > +	if (awcc->gmode) {
> >   		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
> >   			WMAX_THERMAL_MODE_GMODE;
> > 
> > @@ -1328,7 +1301,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> >   	};
> >   	int ret = 0;
> > 
> > -	if (quirks->thermal)
> > +	if (awcc)
> >   		ret = alienware_awcc_setup(wdev);
> >   	else
> >   		ret = alienware_alienfx_setup(&pdata);
> > @@ -1338,7 +1311,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
> > 
> >   static void wmax_wmi_remove(struct wmi_device *wdev)
> >   {
> > -	if (quirks->thermal)
> > +	if (awcc)
> >   		alienware_awcc_exit(wdev);
> >   	else
> >   		alienware_alienfx_exit(wdev);
> > @@ -1362,6 +1335,18 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
> > 
> >   static int __init alienware_wmax_wmi_init(void)
> >   {
> > +	const struct dmi_system_id *id;
> > +
> > +	id = dmi_first_match(awcc_dmi_table);
> > +	if (id)
> > +		awcc = id->driver_data;
> > +
> > +	if (force_platform_profile)
> > +		awcc = &x_series_features;
> > +
> > +	if (force_gmode)
> > +		awcc = &g_series_features;
> > +
> >   	return wmi_driver_register(&alienware_wmax_wmi_driver);
> >   }
> > 
> > @@ -1378,16 +1363,6 @@ static int __init alienware_wmi_init(void)
> >   	if (quirks == NULL)
> >   		quirks = &quirk_unknown;
> > 
> > -	if (force_platform_profile)
> > -		quirks->thermal = true;
> > -
> > -	if (force_gmode) {
> > -		if (quirks->thermal)
> > -			quirks->gmode = true;
> > -		else
> > -			pr_warn("force_gmode requires platform profile support\n");
> > -	}
> > -
> >   	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
> >   		interface = WMAX;
> >   		ret = alienware_wmax_wmi_init();

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 16/20] platform/x86: Add alienware-wmi.h
  2024-12-27  4:02   ` Armin Wolf
@ 2024-12-27  4:56     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:56 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 05:02:32AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Add a header file for alienware-wmi with shared resources to support the
> > upcoming file split.
> 
> I am OK with this, but only common definitions should be moved inside this header file.
> Definitions only used by a single driver should remain inside the driver file.

Ack.

> 
> Thanks,
> Armin Wolf
> 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   .../platform/x86/dell/alienware-wmi-base.c    |  93 ++--------------
> >   drivers/platform/x86/dell/alienware-wmi.h     | 103 ++++++++++++++++++
> >   2 files changed, 112 insertions(+), 84 deletions(-)
> >   create mode 100644 drivers/platform/x86/dell/alienware-wmi.h
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
> > index 8ea08f5f8810..e8d470bbb608 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi-base.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi-base.c
> > @@ -16,26 +16,7 @@
> >   #include <linux/dmi.h>
> >   #include <linux/leds.h>
> >   #include <linux/wmi.h>
> > -
> > -#define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
> > -#define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> > -#define WMAX_CONTROL_GUID		"A70591CE-A997-11DA-B012-B622A1EF5492"
> > -
> > -#define WMAX_METHOD_HDMI_SOURCE		0x1
> > -#define WMAX_METHOD_HDMI_STATUS		0x2
> > -#define WMAX_METHOD_BRIGHTNESS		0x3
> > -#define WMAX_METHOD_ZONE_CONTROL	0x4
> > -#define WMAX_METHOD_HDMI_CABLE		0x5
> > -#define WMAX_METHOD_AMPLIFIER_CABLE	0x6
> > -#define WMAX_METHOD_DEEP_SLEEP_CONTROL	0x0B
> > -#define WMAX_METHOD_DEEP_SLEEP_STATUS	0x0C
> > -#define WMAX_METHOD_THERMAL_INFORMATION	0x14
> > -#define WMAX_METHOD_THERMAL_CONTROL	0x15
> > -#define WMAX_METHOD_GAME_SHIFT_STATUS	0x25
> > -
> > -#define WMAX_THERMAL_MODE_GMODE		0xAB
> > -
> > -#define WMAX_FAILURE_CODE		0xFFFFFFFF
> > +#include "alienware-wmi.h"
> > 
> >   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
> >   MODULE_DESCRIPTION("Alienware special feature control");
> > @@ -54,18 +35,6 @@ enum INTERFACE_FLAGS {
> >   	WMAX,
> >   };
> > 
> > -enum LEGACY_CONTROL_STATES {
> > -	LEGACY_RUNNING = 1,
> > -	LEGACY_BOOTING = 0,
> > -	LEGACY_SUSPEND = 3,
> > -};
> > -
> > -enum WMAX_CONTROL_STATES {
> > -	WMAX_RUNNING = 0xFF,
> > -	WMAX_BOOTING = 0,
> > -	WMAX_SUSPEND = 3,
> > -};
> > -
> >   enum WMAX_THERMAL_INFORMATION_OPERATIONS {
> >   	WMAX_OPERATION_SYS_DESCRIPTION		= 0x02,
> >   	WMAX_OPERATION_LIST_IDS			= 0x03,
> > @@ -122,7 +91,6 @@ struct quirk_entry {
> > 
> >   static struct quirk_entry *quirks;
> > 
> > -
> >   static struct quirk_entry quirk_inspiron5675 = {
> >   	.num_zones = 2,
> >   	.hdmi_mux = 0,
> > @@ -342,33 +310,10 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {
> > 
> >   struct awcc_features *awcc;
> > 
> > -struct color_platform {
> > -	u8 blue;
> > -	u8 green;
> > -	u8 red;
> > -} __packed;
> > -
> > -struct wmax_brightness_args {
> > -	u32 led_mask;
> > -	u32 percentage;
> > -};
> > -
> >   struct wmax_basic_args {
> >   	u8 arg;
> >   };
> > 
> > -struct legacy_led_args {
> > -	struct color_platform colors;
> > -	u8 brightness;
> > -	u8 state;
> > -} __packed;
> > -
> > -struct wmax_led_args {
> > -	u32 led_mask;
> > -	struct color_platform colors;
> > -	u8 state;
> > -} __packed;
> > -
> >   struct wmax_u32_args {
> >   	u8 operation;
> >   	u8 arg1;
> > @@ -382,30 +327,10 @@ struct awcc_priv {
> >   	enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
> >   };
> > 
> > -struct alienfx_priv {
> > -	struct platform_device *pdev;
> > -	struct led_classdev global_led;
> > -	struct color_platform colors[4];
> > -	u8 global_brightness;
> > -	u8 lighting_control_state;
> > -};
> > -
> > -struct alienfx_ops {
> > -	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
> > -		       u8 location);
> > -	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
> > -			      u8 brightness);
> > -};
> > -
> > -struct alienfx_platdata {
> > -	struct wmi_device *wdev;
> > -	struct alienfx_ops ops;
> > -};
> > -
> >   static u8 interface;
> > 
> > -static acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> > -					 void *in_args, size_t in_size, u32 *out_data)
> > +acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> > +				  void *in_args, size_t in_size, u32 *out_data)
> >   {
> >   	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
> >   	struct acpi_buffer in = {in_size, in_args};
> > @@ -1139,7 +1064,7 @@ static struct platform_driver platform_driver = {
> >   	.probe = alienfx_probe,
> >   };
> > 
> > -static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
> > +int alienware_alienfx_setup(struct alienfx_platdata *pdata)
> >   {
> >   	struct platform_device *pdev;
> >   	int ret;
> > @@ -1162,7 +1087,7 @@ static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
> >   	return 0;
> >   }
> > 
> > -static void alienware_alienfx_exit(struct wmi_device *wdev)
> > +void alienware_alienfx_exit(struct wmi_device *wdev)
> >   {
> >   	struct platform_device *pdev;
> > 
> > @@ -1242,12 +1167,12 @@ static struct wmi_driver alienware_legacy_wmi_driver = {
> >   	.remove = legacy_wmi_remove,
> >   };
> > 
> > -static int __init alienware_legacy_wmi_init(void)
> > +int __init alienware_legacy_wmi_init(void)
> >   {
> >   	return wmi_driver_register(&alienware_legacy_wmi_driver);
> >   }
> > 
> > -static void __exit alienware_legacy_wmi_exit(void)
> > +void __exit alienware_legacy_wmi_exit(void)
> >   {
> >   	wmi_driver_unregister(&alienware_legacy_wmi_driver);
> >   }
> > @@ -1333,7 +1258,7 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
> >   	.remove = wmax_wmi_remove,
> >   };
> > 
> > -static int __init alienware_wmax_wmi_init(void)
> > +int __init alienware_wmax_wmi_init(void)
> >   {
> >   	const struct dmi_system_id *id;
> > 
> > @@ -1350,7 +1275,7 @@ static int __init alienware_wmax_wmi_init(void)
> >   	return wmi_driver_register(&alienware_wmax_wmi_driver);
> >   }
> > 
> > -static void __exit alienware_wmax_wmi_exit(void)
> > +void __exit alienware_wmax_wmi_exit(void)
> >   {
> >   	wmi_driver_unregister(&alienware_wmax_wmi_driver);
> >   }
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
> > new file mode 100644
> > index 000000000000..78ac10122155
> > --- /dev/null
> > +++ b/drivers/platform/x86/dell/alienware-wmi.h
> > @@ -0,0 +1,103 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Alienware WMI special features driver
> > + *
> > + * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
> > + * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
> > + */
> > +
> > +#ifndef _ALIENWARE_WMI_H_
> > +#define _ALIENWARE_WMI_H_
> > +
> > +#include <linux/leds.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/wmi.h>
> > +
> > +#define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
> > +#define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
> > +#define WMAX_CONTROL_GUID		"A70591CE-A997-11DA-B012-B622A1EF5492"
> > +
> > +#define WMAX_METHOD_HDMI_SOURCE			0x1
> > +#define WMAX_METHOD_HDMI_STATUS			0x2
> > +#define WMAX_METHOD_BRIGHTNESS			0x3
> > +#define WMAX_METHOD_ZONE_CONTROL		0x4
> > +#define WMAX_METHOD_HDMI_CABLE			0x5
> > +#define WMAX_METHOD_AMPLIFIER_CABLE		0x6
> > +#define WMAX_METHOD_DEEP_SLEEP_CONTROL		0x0B
> > +#define WMAX_METHOD_DEEP_SLEEP_STATUS		0x0C
> > +#define WMAX_METHOD_THERMAL_INFORMATION		0x14
> > +#define WMAX_METHOD_THERMAL_CONTROL		0x15
> > +#define WMAX_METHOD_GAME_SHIFT_STATUS		0x25
> > +
> > +#define WMAX_THERMAL_MODE_GMODE			0xAB
> > +
> > +#define WMAX_FAILURE_CODE			0xFFFFFFFF
> > +
> > +enum LEGACY_CONTROL_STATES {
> > +	LEGACY_RUNNING = 1,
> > +	LEGACY_BOOTING = 0,
> > +	LEGACY_SUSPEND = 3,
> > +};
> > +
> > +enum WMAX_CONTROL_STATES {
> > +	WMAX_RUNNING = 0xFF,
> > +	WMAX_BOOTING = 0,
> > +	WMAX_SUSPEND = 3,
> > +};
> > +
> > +struct color_platform {
> > +	u8 blue;
> > +	u8 green;
> > +	u8 red;
> > +} __packed;
> > +
> > +struct wmax_brightness_args {
> > +	u32 led_mask;
> > +	u32 percentage;
> > +};
> > +
> > +struct legacy_led_args {
> > +	struct color_platform colors;
> > +	u8 brightness;
> > +	u8 state;
> > +} __packed;
> > +
> > +struct wmax_led_args {
> > +	u32 led_mask;
> > +	struct color_platform colors;
> > +	u8 state;
> > +} __packed;
> > +
> > +struct alienfx_priv {
> > +	struct platform_device *pdev;
> > +	struct led_classdev global_led;
> > +	struct color_platform colors[4];
> > +	u8 global_brightness;
> > +	u8 lighting_control_state;
> > +};
> > +
> > +struct alienfx_ops {
> > +	int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
> > +		       u8 location);
> > +	int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
> > +			      u8 brightness);
> > +};
> > +
> > +struct alienfx_platdata {
> > +	struct wmi_device *wdev;
> > +	struct alienfx_ops ops;
> > +};
> > +
> > +acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> > +				  void *in_args, size_t in_size, u32 *out_data);
> > +
> > +int alienware_alienfx_setup(struct alienfx_platdata *pdata);
> > +void alienware_alienfx_exit(struct wmi_device *wdev);
> > +
> > +int __init alienware_legacy_wmi_init(void);
> > +void __exit alienware_legacy_wmi_exit(void);
> > +
> > +int __init alienware_wmax_wmi_init(void);
> > +void __exit alienware_wmax_wmi_exit(void);
> > +
> > +#endif

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 18/20] platform/x86: dell: Modify Makefile alignment
  2024-12-27  4:05   ` Armin Wolf
@ 2024-12-27  4:57     ` Kurt Borja
  2024-12-29  0:31       ` Armin Wolf
  0 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:57 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 05:05:30AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Add one more TAB to each line to support upcoming changes.
> 
> Please merge this with patch 19.

I'm almost certain I read an email in the lists, in which a maintainer
asked these to be separate changes.

I have no problem with stashing them tho.

> 
> Thanks,
> Armin Wolf
> 
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/Makefile | 48 +++++++++++++++---------------
> >   1 file changed, 24 insertions(+), 24 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> > index 03ba459f3d31..d5718ef34c48 100644
> > --- a/drivers/platform/x86/dell/Makefile
> > +++ b/drivers/platform/x86/dell/Makefile
> > @@ -4,27 +4,27 @@
> >   # Dell x86 Platform-Specific Drivers
> >   #
> > 
> > -obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
> > -alienware-wmi-objs			:= alienware-wmi-base.o
> > -alienware-wmi-y				+= alienware-wmi-legacy.o
> > -alienware-wmi-y				+= alienware-wmi-wmax.o
> > -obj-$(CONFIG_DCDBAS)			+= dcdbas.o
> > -obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
> > -obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
> > -obj-$(CONFIG_DELL_RBU)			+= dell_rbu.o
> > -obj-$(CONFIG_DELL_PC)			+= dell-pc.o
> > -obj-$(CONFIG_DELL_SMBIOS)		+= dell-smbios.o
> > -dell-smbios-objs			:= dell-smbios-base.o
> > -dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)	+= dell-smbios-wmi.o
> > -dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)	+= dell-smbios-smm.o
> > -obj-$(CONFIG_DELL_SMO8800)		+= dell-smo8800.o
> > -obj-$(CONFIG_DELL_SMO8800)		+= dell-lis3lv02d.o
> > -obj-$(CONFIG_DELL_UART_BACKLIGHT)	+= dell-uart-backlight.o
> > -obj-$(CONFIG_DELL_WMI)			+= dell-wmi.o
> > -dell-wmi-objs				:= dell-wmi-base.o
> > -dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)	+= dell-wmi-privacy.o
> > -obj-$(CONFIG_DELL_WMI_AIO)		+= dell-wmi-aio.o
> > -obj-$(CONFIG_DELL_WMI_DESCRIPTOR)	+= dell-wmi-descriptor.o
> > -obj-$(CONFIG_DELL_WMI_DDV)		+= dell-wmi-ddv.o
> > -obj-$(CONFIG_DELL_WMI_LED)		+= dell-wmi-led.o
> > -obj-$(CONFIG_DELL_WMI_SYSMAN)		+= dell-wmi-sysman/
> > +obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
> > +alienware-wmi-objs				:= alienware-wmi-base.o
> > +alienware-wmi-y					+= alienware-wmi-legacy.o
> > +alienware-wmi-y					+= alienware-wmi-wmax.o
> > +obj-$(CONFIG_DCDBAS)				+= dcdbas.o
> > +obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
> > +obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
> > +obj-$(CONFIG_DELL_RBU)				+= dell_rbu.o
> > +obj-$(CONFIG_DELL_PC)				+= dell-pc.o
> > +obj-$(CONFIG_DELL_SMBIOS)			+= dell-smbios.o
> > +dell-smbios-objs				:= dell-smbios-base.o
> > +dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)		+= dell-smbios-wmi.o
> > +dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)		+= dell-smbios-smm.o
> > +obj-$(CONFIG_DELL_SMO8800)			+= dell-smo8800.o
> > +obj-$(CONFIG_DELL_SMO8800)			+= dell-lis3lv02d.o
> > +obj-$(CONFIG_DELL_UART_BACKLIGHT)		+= dell-uart-backlight.o
> > +obj-$(CONFIG_DELL_WMI)				+= dell-wmi.o
> > +dell-wmi-objs					:= dell-wmi-base.o
> > +dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)		+= dell-wmi-privacy.o
> > +obj-$(CONFIG_DELL_WMI_AIO)			+= dell-wmi-aio.o
> > +obj-$(CONFIG_DELL_WMI_DESCRIPTOR)		+= dell-wmi-descriptor.o
> > +obj-$(CONFIG_DELL_WMI_DDV)			+= dell-wmi-ddv.o
> > +obj-$(CONFIG_DELL_WMI_LED)			+= dell-wmi-led.o
> > +obj-$(CONFIG_DELL_WMI_SYSMAN)			+= dell-wmi-sysman/

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 19/20] platform/x86: Update alienware-wmi config entries
  2024-12-27  4:08   ` Armin Wolf
@ 2024-12-27  4:59     ` Kurt Borja
  2024-12-29  0:32       ` Armin Wolf
  0 siblings, 1 reply; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  4:59 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 05:08:03AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Add config entries for each WMI driver managed by the alienware-wmi
> > module to be able to conditionally compile them.
> > 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/Kconfig         | 30 +++++++++++++++++++----
> >   drivers/platform/x86/dell/Makefile        |  4 +--
> >   drivers/platform/x86/dell/alienware-wmi.h | 23 +++++++++++++++++
> >   3 files changed, 50 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
> > index d09060aedd3f..f8a0dffcaab7 100644
> > --- a/drivers/platform/x86/dell/Kconfig
> > +++ b/drivers/platform/x86/dell/Kconfig
> > @@ -18,15 +18,35 @@ config ALIENWARE_WMI
> >   	tristate "Alienware Special feature control"
> >   	default m
> >   	depends on ACPI
> > +	depends on ACPI_WMI
> > +	depends on DMI
> >   	depends on LEDS_CLASS
> >   	depends on NEW_LEDS
> > -	depends on ACPI_WMI
> > +	help
> > +	 This is a driver for controlling Alienware WMI driven features.
> > +
> > +	 On legacy devices, it exposes an interface for controlling the AlienFX
> > +	 zones on Alienware machines that don't contain a dedicated
> > +	 AlienFX USB MCU such as the X51 and X51-R2.
> > +
> > +	 On newer devices, it exposes the AWCC thermal control interface through
> > +	 known Kernel APIs.
> > +
> > +config ALIENWARE_WMI_LEGACY
> > +	bool "Alienware Legacy WMI device driver"
> > +	default y
> > +	depends on ALIENWARE_WMI
> > +	help
> > +	 Legacy Alienware WMI driver with AlienFX LED control capabilities.
> > +
> > +config ALIENWARE_WMI_WMAX
> > +	bool "Alienware WMAX WMI device driver"
> > +	default y
> > +	depends on ALIENWARE_WMI
> >   	select ACPI_PLATFORM_PROFILE
> >   	help
> > -	 This is a driver for controlling Alienware BIOS driven
> > -	 features.  It exposes an interface for controlling the AlienFX
> > -	 zones on Alienware machines that don't contain a dedicated AlienFX
> > -	 USB MCU such as the X51 and X51-R2.
> > +	 Alienware WMI driver with AlienFX LED, HDMI, amplifier, deep sleep and
> > +	 AWCC thermal control capabilities.
> > 
> >   config DCDBAS
> >   	tristate "Dell Systems Management Base Driver"
> > diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> > index d5718ef34c48..8ac9a933c770 100644
> > --- a/drivers/platform/x86/dell/Makefile
> > +++ b/drivers/platform/x86/dell/Makefile
> > @@ -6,8 +6,8 @@
> > 
> >   obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
> >   alienware-wmi-objs				:= alienware-wmi-base.o
> > -alienware-wmi-y					+= alienware-wmi-legacy.o
> > -alienware-wmi-y					+= alienware-wmi-wmax.o
> > +alienware-wmi-$(CONFIG_ALIENWARE_WMI_LEGACY)	+= alienware-wmi-legacy.o
> > +alienware-wmi-$(CONFIG_ALIENWARE_WMI_WMAX)	+= alienware-wmi-wmax.o
> >   obj-$(CONFIG_DCDBAS)				+= dcdbas.o
> >   obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
> >   obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
> > diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
> > index 78ac10122155..97b52e51cd7d 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi.h
> > +++ b/drivers/platform/x86/dell/alienware-wmi.h
> > @@ -94,10 +94,33 @@ acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
> >   int alienware_alienfx_setup(struct alienfx_platdata *pdata);
> >   void alienware_alienfx_exit(struct wmi_device *wdev);
> > 
> > +#if IS_ENABLED(CONFIG_ALIENWARE_WMI_LEGACY)
> >   int __init alienware_legacy_wmi_init(void);
> >   void __exit alienware_legacy_wmi_exit(void);
> > +#else
> > +int __init alienware_legacy_wmi_init(void)
> > +{
> > +	return 0;
> 
> Please return -EOPNOTSUPP here.

Maybe -ENODEV is better in this case?

Also this should be static inline, I'll fix it.

> 
> > +}
> > +
> > +void __exit alienware_legacy_wmi_exit(void)
> > +{
> > +}
> > +#endif
> > 
> > +#if IS_ENABLED(CONFIG_ALIENWARE_WMI_WMAX)
> >   int __init alienware_wmax_wmi_init(void);
> >   void __exit alienware_wmax_wmi_exit(void);
> > +#else
> > +int __init alienware_wmax_wmi_init(void)
> > +{
> > +	return 0;
> 
> Same as above.
> 
> Thanks,
> Armin Wolf
> 
> > +}
> > +
> > +
> > +void __exit alienware_wmax_wmi_exit(void)
> > +{
> > +}
> > +#endif
> > 
> >   #endif

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 20/20] alienware-wmi: Update header and module information
  2024-12-27  4:08   ` Armin Wolf
@ 2024-12-27  5:01     ` Kurt Borja
  0 siblings, 0 replies; 61+ messages in thread
From: Kurt Borja @ 2024-12-27  5:01 UTC (permalink / raw)
  To: Armin Wolf
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

On Fri, Dec 27, 2024 at 05:08:58AM +0100, Armin Wolf wrote:
> Am 21.12.24 um 06:59 schrieb Kurt Borja:
> 
> > Update module description and add myself as a module author.
> 
> Reviewed-by: Armin Wolf <W_Armin@gmx.de>

Thank you so much for your detailed review Armin! :) I'll submit v2 in a
couple of days.

~ Kurt

> 
> > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > ---
> >   drivers/platform/x86/dell/alienware-wmi-base.c | 4 +++-
> >   1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
> > index 450ba0a48004..e8ccf9b277fa 100644
> > --- a/drivers/platform/x86/dell/alienware-wmi-base.c
> > +++ b/drivers/platform/x86/dell/alienware-wmi-base.c
> > @@ -1,8 +1,9 @@
> >   // SPDX-License-Identifier: GPL-2.0-or-later
> >   /*
> > - * Alienware AlienFX control
> > + * Alienware special feature control
> >    *
> >    * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
> > + * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
> >    */
> > 
> >   #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > @@ -15,6 +16,7 @@
> >   #include "alienware-wmi.h"
> > 
> >   MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
> > +MODULE_AUTHOR("Kurt Borja <kuurtb@gmail.com>");
> >   MODULE_DESCRIPTION("Alienware special feature control");
> >   MODULE_LICENSE("GPL");
> > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 05/20] alienware-wmi: Improve rgb-zones group creation
  2024-12-27  4:37     ` Kurt Borja
@ 2024-12-29  0:17       ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-29  0:17 UTC (permalink / raw)
  To: Kurt Borja
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

Am 27.12.24 um 05:37 schrieb Kurt Borja:

> On Fri, Dec 27, 2024 at 02:04:51AM +0100, Armin Wolf wrote:
>> Am 21.12.24 um 06:59 schrieb Kurt Borja:
>>
>>> Define zone_attrs statically with the use of helper macros and
>>> initialize the zone_attribute_group with driver's .dev_groups.
>>>
>>> Drop match_zone() and instead pass a `location` argument to previous
>>> show/store methods to access the correct `zone` LED state. On top of
>>> that rename zone_set() -> zone_store() to be more consistent with sysfs
>>> conventions.
>>>
>>> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
>>> ---
>>>    drivers/platform/x86/dell/alienware-wmi.c | 179 +++++++++-------------
>>>    1 file changed, 72 insertions(+), 107 deletions(-)
>>>
>>> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
>>> index e010c94555e8..a431b1fec9fb 100644
>>> --- a/drivers/platform/x86/dell/alienware-wmi.c
>>> +++ b/drivers/platform/x86/dell/alienware-wmi.c
>>> @@ -376,12 +376,6 @@ struct color_platform {
>>>    	u8 red;
>>>    } __packed;
>>>
>>> -struct platform_zone {
>>> -	u8 location;
>>> -	struct device_attribute *attr;
>>> -	struct color_platform colors;
>>> -};
>>> -
>>>    struct wmax_brightness_args {
>>>    	u32 led_mask;
>>>    	u32 percentage;
>>> @@ -411,16 +405,10 @@ struct wmax_u32_args {
>>>    };
>>>
>>>    static struct platform_device *platform_device;
>>> -static struct device_attribute *zone_dev_attrs;
>>> -static struct attribute **zone_attrs;
>>> -static struct platform_zone *zone_data;
>>> +static struct color_platform colors[4];
>>>    static struct platform_profile_handler pp_handler;
>>>    static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>>>
>>> -static struct attribute_group zone_attribute_group = {
>>> -	.name = "rgb_zones",
>>> -};
>>> -
>>>    static u8 interface;
>>>    static u8 lighting_control_state;
>>>    static u8 global_brightness;
>>> @@ -452,24 +440,10 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
>>>    	return 0;
>>>    }
>>>
>>> -static struct platform_zone *match_zone(struct device_attribute *attr)
>>> -{
>>> -	u8 zone;
>>> -
>>> -	for (zone = 0; zone < quirks->num_zones; zone++) {
>>> -		if ((struct device_attribute *)zone_data[zone].attr == attr) {
>>> -			pr_debug("alienware-wmi: matched zone location: %d\n",
>>> -				 zone_data[zone].location);
>>> -			return &zone_data[zone];
>>> -		}
>>> -	}
>>> -	return NULL;
>>> -}
>>> -
>>>    /*
>>>     * Individual RGB zone control
>>>     */
>>> -static int alienware_update_led(struct platform_zone *zone)
>>> +static int alienware_update_led(u8 location)
>>>    {
>>>    	int method_id;
>>>    	acpi_status status;
>>> @@ -478,8 +452,8 @@ static int alienware_update_led(struct platform_zone *zone)
>>>    	struct legacy_led_args legacy_args;
>>>    	struct wmax_led_args wmax_basic_args;
>>>    	if (interface == WMAX) {
>>> -		wmax_basic_args.led_mask = 1 << zone->location;
>>> -		wmax_basic_args.colors = zone->colors;
>>> +		wmax_basic_args.led_mask = 1 << location;
>>> +		wmax_basic_args.colors = colors[location];
>>>    		wmax_basic_args.state = lighting_control_state;
>>>    		guid = WMAX_CONTROL_GUID;
>>>    		method_id = WMAX_METHOD_ZONE_CONTROL;
>>> @@ -487,7 +461,7 @@ static int alienware_update_led(struct platform_zone *zone)
>>>    		input.length = sizeof(wmax_basic_args);
>>>    		input.pointer = &wmax_basic_args;
>>>    	} else {
>>> -		legacy_args.colors = zone->colors;
>>> +		legacy_args.colors = colors[location];
>>>    		legacy_args.brightness = global_brightness;
>>>    		legacy_args.state = 0;
>>>    		if (lighting_control_state == LEGACY_BOOTING ||
>>> @@ -496,7 +470,7 @@ static int alienware_update_led(struct platform_zone *zone)
>>>    			legacy_args.state = lighting_control_state;
>>>    		} else
>>>    			guid = LEGACY_CONTROL_GUID;
>>> -		method_id = zone->location + 1;
>>> +		method_id = location + 1;
>>>
>>>    		input.length = sizeof(legacy_args);
>>>    		input.pointer = &legacy_args;
>>> @@ -510,35 +484,54 @@ static int alienware_update_led(struct platform_zone *zone)
>>>    }
>>>
>>>    static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
>>> -			 char *buf)
>>> +			 char *buf, u8 location)
>>>    {
>>> -	struct platform_zone *target_zone;
>>> -	target_zone = match_zone(attr);
>>> -	if (target_zone == NULL)
>>> -		return sprintf(buf, "red: -1, green: -1, blue: -1\n");
>>>    	return sprintf(buf, "red: %d, green: %d, blue: %d\n",
>>> -		       target_zone->colors.red,
>>> -		       target_zone->colors.green, target_zone->colors.blue);
>>> +		       colors[location].red, colors[location].green,
>>> +		       colors[location].blue);
>>>
>>>    }
>>>
>>> -static ssize_t zone_set(struct device *dev, struct device_attribute *attr,
>>> -			const char *buf, size_t count)
>>> +static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
>>> +			  const char *buf, size_t count, u8 location)
>>>    {
>>> -	struct platform_zone *target_zone;
>>>    	int ret;
>>> -	target_zone = match_zone(attr);
>>> -	if (target_zone == NULL) {
>>> -		pr_err("alienware-wmi: invalid target zone\n");
>>> -		return 1;
>>> -	}
>>> -	ret = parse_rgb(buf, &target_zone->colors);
>>> +
>>> +	ret = parse_rgb(buf, &colors[location]);
>>>    	if (ret)
>>>    		return ret;
>>> -	ret = alienware_update_led(target_zone);
>>> +
>>> +	ret = alienware_update_led(location);
>>> +
>>>    	return ret ? ret : count;
>>>    }
>>>
>>> +#define ALIENWARE_ZONE_SHOW_FUNC(_num)					\
>>> +	static ssize_t zone0##_num##_show(struct device *dev,		\
>>> +					struct device_attribute *attr,	\
>>> +					char *buf)			\
>>> +	{								\
>>> +		return zone_show(dev, attr, buf, _num);			\
>>> +	}
>>> +
>>> +#define ALIENWARE_ZONE_STORE_FUNC(_num)					\
>>> +	static ssize_t zone0##_num##_store(struct device *dev,		\
>>> +					struct device_attribute *attr,	\
>>> +					const char *buf, size_t count)	\
>>> +	{								\
>>> +		return zone_store(dev, attr, buf, count, _num);		\
>>> +	}
>>> +
>>> +#define ALIENWARE_ZONE_ATTR(_num)					\
>>> +	ALIENWARE_ZONE_SHOW_FUNC(_num)					\
>>> +	ALIENWARE_ZONE_STORE_FUNC(_num)					\
>>> +	static DEVICE_ATTR_RW(zone0##_num)
>>> +
>>> +ALIENWARE_ZONE_ATTR(0);
>>> +ALIENWARE_ZONE_ATTR(1);
>>> +ALIENWARE_ZONE_ATTR(2);
>>> +ALIENWARE_ZONE_ATTR(3);
>> I know that this will result in a bit of boilerplate code, but please do not use such macros.
>> They have a habit of confusing static code analysis tools.
> Ack.
>
> I'll drop this macros, checkpatch also hates the last one.
>
>>> +
>>>    /*
>>>     * Lighting control state device attribute (Global)
>>>     */
>>> @@ -578,6 +571,33 @@ static ssize_t lighting_control_state_store(struct device *dev,
>>>
>>>    static DEVICE_ATTR_RW(lighting_control_state);
>>>
>>> +static umode_t zone_attr_visible(struct kobject *kobj,
>>> +				 struct attribute *attr, int n)
>>> +{
>>> +	return n < quirks->num_zones + 1 ? 0644 : 0;
>> Where is this function used?
> It gets picked up by DEFINE_SYSFS_GROUP_VISIBLE to manage individual
> attributes permissions.

I see, nice.

Thanks,
Armin Wolf

>> Thanks,
>> Armin Wolf
>>
>>> +}
>>> +
>>> +static bool zone_group_visible(struct kobject *kobj)
>>> +{
>>> +	return quirks->num_zones > 0;
>>> +}
>>> +DEFINE_SYSFS_GROUP_VISIBLE(zone);
>>> +
>>> +static struct attribute *zone_attrs[] = {
>>> +	&dev_attr_lighting_control_state.attr,
>>> +	&dev_attr_zone00.attr,
>>> +	&dev_attr_zone01.attr,
>>> +	&dev_attr_zone02.attr,
>>> +	&dev_attr_zone03.attr,
>>> +	NULL
>>> +};
>>> +
>>> +static struct attribute_group zone_attribute_group = {
>>> +	.name = "rgb_zones",
>>> +	.is_visible = SYSFS_GROUP_VISIBLE(zone),
>>> +	.attrs = zone_attrs,
>>> +};
>>> +
>>>    /*
>>>     * LED Brightness (Global)
>>>     */
>>> @@ -606,7 +626,7 @@ static void global_led_set(struct led_classdev *led_cdev,
>>>    	if (interface == WMAX)
>>>    		ret = wmax_brightness(brightness);
>>>    	else
>>> -		ret = alienware_update_led(&zone_data[0]);
>>> +		ret = alienware_update_led(0);
>>>    	if (ret)
>>>    		pr_err("LED brightness update failed\n");
>>>    }
>>> @@ -624,9 +644,6 @@ static struct led_classdev global_led = {
>>>
>>>    static int alienware_zone_init(struct platform_device *dev)
>>>    {
>>> -	u8 zone;
>>> -	char *name;
>>> -
>>>    	if (interface == WMAX) {
>>>    		lighting_control_state = WMAX_RUNNING;
>>>    	} else if (interface == LEGACY) {
>>> @@ -635,65 +652,12 @@ static int alienware_zone_init(struct platform_device *dev)
>>>    	global_led.max_brightness = 0x0F;
>>>    	global_brightness = global_led.max_brightness;
>>>
>>> -	/*
>>> -	 *      - zone_dev_attrs num_zones + 1 is for individual zones and then
>>> -	 *        null terminated
>>> -	 *      - zone_attrs num_zones + 2 is for all attrs in zone_dev_attrs +
>>> -	 *        the lighting control + null terminated
>>> -	 *      - zone_data num_zones is for the distinct zones
>>> -	 */
>>> -	zone_dev_attrs =
>>> -	    kcalloc(quirks->num_zones + 1, sizeof(struct device_attribute),
>>> -		    GFP_KERNEL);
>>> -	if (!zone_dev_attrs)
>>> -		return -ENOMEM;
>>> -
>>> -	zone_attrs =
>>> -	    kcalloc(quirks->num_zones + 2, sizeof(struct attribute *),
>>> -		    GFP_KERNEL);
>>> -	if (!zone_attrs)
>>> -		return -ENOMEM;
>>> -
>>> -	zone_data =
>>> -	    kcalloc(quirks->num_zones, sizeof(struct platform_zone),
>>> -		    GFP_KERNEL);
>>> -	if (!zone_data)
>>> -		return -ENOMEM;
>>> -
>>> -	for (zone = 0; zone < quirks->num_zones; zone++) {
>>> -		name = kasprintf(GFP_KERNEL, "zone%02hhX", zone);
>>> -		if (name == NULL)
>>> -			return 1;
>>> -		sysfs_attr_init(&zone_dev_attrs[zone].attr);
>>> -		zone_dev_attrs[zone].attr.name = name;
>>> -		zone_dev_attrs[zone].attr.mode = 0644;
>>> -		zone_dev_attrs[zone].show = zone_show;
>>> -		zone_dev_attrs[zone].store = zone_set;
>>> -		zone_data[zone].location = zone;
>>> -		zone_attrs[zone] = &zone_dev_attrs[zone].attr;
>>> -		zone_data[zone].attr = &zone_dev_attrs[zone];
>>> -	}
>>> -	zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
>>> -	zone_attribute_group.attrs = zone_attrs;
>>> -
>>> -	led_classdev_register(&dev->dev, &global_led);
>>> -
>>> -	return sysfs_create_group(&dev->dev.kobj, &zone_attribute_group);
>>> +	return led_classdev_register(&dev->dev, &global_led);
>>>    }
>>>
>>>    static void alienware_zone_exit(struct platform_device *dev)
>>>    {
>>> -	u8 zone;
>>> -
>>> -	sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
>>>    	led_classdev_unregister(&global_led);
>>> -	if (zone_dev_attrs) {
>>> -		for (zone = 0; zone < quirks->num_zones; zone++)
>>> -			kfree(zone_dev_attrs[zone].attr.name);
>>> -	}
>>> -	kfree(zone_dev_attrs);
>>> -	kfree(zone_data);
>>> -	kfree(zone_attrs);
>>>    }
>>>
>>>    static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
>>> @@ -1143,6 +1107,7 @@ static void remove_thermal_profile(void)
>>>     * Platform Driver
>>>     */
>>>    static const struct attribute_group *alienfx_groups[] = {
>>> +	&zone_attribute_group,
>>>    	&hdmi_attribute_group,
>>>    	&amplifier_attribute_group,
>>>    	&deepsleep_attribute_group,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 08/20] alienware-wmi: Add WMI Drivers
  2024-12-27  4:44     ` Kurt Borja
  2024-12-27  4:48       ` Kurt Borja
@ 2024-12-29  0:26       ` Armin Wolf
  1 sibling, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-29  0:26 UTC (permalink / raw)
  To: Kurt Borja
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

Am 27.12.24 um 05:44 schrieb Kurt Borja:

> On Fri, Dec 27, 2024 at 04:21:14AM +0100, Armin Wolf wrote:
>> Am 21.12.24 um 06:59 schrieb Kurt Borja:
>>
>>> Add WMI drivers for LEGACY and WMAX devices.
>>>
>>> This involves moving platform driver and device registration to a helper
>>> function, which is now called from the driver's preferred WMI device
>>> driver probe. However this is only done if !quirks->thermal because
>>> newer WMAX interface doesn't support any of the features exposed by this
>>> device.
>>>
>>> Only one driver is registered on module initialization to prevent
>>> registering duplicate platform driver and device.
>>>
>>> Aditionally, create_thermal_profile() now takes wmi_device * instead of
>>> platform_device *.
>> Since the HDMI, Amplifier and deepslp groups depend on the WMAX interface i would
>> register them inside wmax_wmi_probe() using device_add_groups() (you might need to
>> rework alienware_alienfx_setup() for that).
>>
>> In the end the only code shared between both drivers should be related to the LED handling.
>> Everything else AFAIK depends on the WMAX interface and should therefore be inside the
>> WMAX driver.
> Unfortunately this breaks old user-space interface, as the path to this
> attributes would change :(. This is why I can't even set a parent dev
> for the platform_device.
>
> I only know of one project which interefaces with this driver [1], and
> it does use the /sys/devices/platform/alienware-wmi path. Maybe I could
> send a pull req, but it would still break old unknown projects and
> scripts.
>
> [1] https://crates.io/crates/alienware

I meant that you use device_add_groups() on the platform device, not on the WMI device itself.
Since alienware_alienfx_setup() stores a pointer to the platform device using dev_set_drvdata() the WMI driver
can use dev_get_drvdata() to access the platform device.

Thanks,
Armin Wolf

>> Thanks,
>> Armin Wolf
>>
>>> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
>>> ---
>>>    drivers/platform/x86/dell/alienware-wmi.c | 186 +++++++++++++++++-----
>>>    1 file changed, 146 insertions(+), 40 deletions(-)
>>>
>>> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
>>> index 4b68d64bd742..f2f6842e27e6 100644
>>> --- a/drivers/platform/x86/dell/alienware-wmi.c
>>> +++ b/drivers/platform/x86/dell/alienware-wmi.c
>>> @@ -15,6 +15,7 @@
>>>    #include <linux/platform_profile.h>
>>>    #include <linux/dmi.h>
>>>    #include <linux/leds.h>
>>> +#include <linux/wmi.h>
>>>
>>>    #define LEGACY_CONTROL_GUID		"A90597CE-A997-11DA-B012-B622A1EF5492"
>>>    #define LEGACY_POWER_CONTROL_GUID	"A80593CE-A997-11DA-B012-B622A1EF5492"
>>> @@ -39,8 +40,6 @@
>>>    MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
>>>    MODULE_DESCRIPTION("Alienware special feature control");
>>>    MODULE_LICENSE("GPL");
>>> -MODULE_ALIAS("wmi:" LEGACY_CONTROL_GUID);
>>> -MODULE_ALIAS("wmi:" WMAX_CONTROL_GUID);
>>>
>>>    static bool force_platform_profile;
>>>    module_param_unsafe(force_platform_profile, bool, 0);
>>> @@ -412,7 +411,10 @@ struct alienfx_priv {
>>>    	u8 lighting_control_state;
>>>    };
>>>
>>> -static struct platform_device *platform_device;
>>> +struct alienfx_platdata {
>>> +	struct wmi_device *wdev;
>>> +};
>>> +
>>>    static struct platform_profile_handler pp_handler;
>>>    static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
>>>
>>> @@ -1048,7 +1050,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>>>    	return wmax_thermal_control(supported_thermal_profiles[profile]);
>>>    }
>>>
>>> -static int create_thermal_profile(struct platform_device *platform_device)
>>> +static int create_thermal_profile(struct wmi_device *wdev)
>>>    {
>>>    	enum platform_profile_option profile;
>>>    	enum wmax_thermal_mode mode;
>>> @@ -1097,7 +1099,7 @@ static int create_thermal_profile(struct platform_device *platform_device)
>>>    	pp_handler.profile_get = thermal_profile_get;
>>>    	pp_handler.profile_set = thermal_profile_set;
>>>    	pp_handler.name = "alienware-wmi";
>>> -	pp_handler.dev = &platform_device->dev;
>>> +	pp_handler.dev = &wdev->dev;
>>>
>>>    	return platform_profile_register(&pp_handler);
>>>    }
>>> @@ -1153,19 +1155,138 @@ static struct platform_driver platform_driver = {
>>>    	.probe = alienfx_probe,
>>>    };
>>>
>>> -static int __init alienware_wmi_init(void)
>>> +static int alienware_alienfx_setup(struct alienfx_platdata *pdata)
>>>    {
>>> +	struct platform_device *pdev;
>>>    	int ret;
>>>
>>> -	if (wmi_has_guid(LEGACY_CONTROL_GUID))
>>> -		interface = LEGACY;
>>> -	else if (wmi_has_guid(WMAX_CONTROL_GUID))
>>> -		interface = WMAX;
>>> -	else {
>>> -		pr_warn("alienware-wmi: No known WMI GUID found\n");
>>> -		return -ENODEV;
>>> +	ret = platform_driver_register(&platform_driver);
>>> +	if (ret < 0)
>>> +		return ret;
>>> +
>>> +	pdev = platform_device_register_data(NULL, "alienware-wmi",
>>> +					     PLATFORM_DEVID_NONE, pdata,
>>> +					     sizeof(*pdata));
>>> +
>>> +	if (IS_ERR(pdev)) {
>>> +		platform_driver_unregister(&platform_driver);
>>> +		return PTR_ERR(pdev);
>>>    	}
>>>
>>> +	dev_set_drvdata(&pdata->wdev->dev, pdev);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static void alienware_alienfx_exit(struct wmi_device *wdev)
>>> +{
>>> +	struct platform_device *pdev;
>>> +
>>> +	pdev = dev_get_drvdata(&wdev->dev);
>>> +
>>> +	platform_device_unregister(pdev);
>>> +	platform_driver_unregister(&platform_driver);
>>> +}
>>> +
>>> +/*
>>> + * Legacy WMI driver
>>> + */
>>> +static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
>>> +{
>>> +	struct alienfx_platdata pdata = {
>>> +		.wdev = wdev,
>>> +	};
>>> +
>>> +	return alienware_alienfx_setup(&pdata);
>>> +}
>>> +
>>> +static void legacy_wmi_remove(struct wmi_device *wdev)
>>> +{
>>> +	alienware_alienfx_exit(wdev);
>>> +}
>>> +
>>> +static struct wmi_device_id alienware_legacy_device_id_table[] = {
>>> +	{ LEGACY_CONTROL_GUID, NULL },
>>> +	{ },
>>> +};
>>> +MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
>>> +
>>> +static struct wmi_driver alienware_legacy_wmi_driver = {
>>> +	.driver = {
>>> +		.name = "alienware-wmi-alienfx",
>>> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
>>> +	},
>>> +	.id_table = alienware_legacy_device_id_table,
>>> +	.probe = legacy_wmi_probe,
>>> +	.remove = legacy_wmi_remove,
>>> +};
>>> +
>>> +static int __init alienware_legacy_wmi_init(void)
>>> +{
>>> +	return wmi_driver_register(&alienware_legacy_wmi_driver);
>>> +}
>>> +
>>> +static void __exit alienware_legacy_wmi_exit(void)
>>> +{
>>> +	wmi_driver_unregister(&alienware_legacy_wmi_driver);
>>> +}
>>> +
>>> +/*
>>> + * WMAX WMI driver
>>> + */
>>> +static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>>> +{
>>> +	struct alienfx_platdata pdata = {
>>> +		.wdev = wdev,
>>> +	};
>>> +	int ret = 0;
>>> +
>>> +	if (quirks->thermal)
>>> +		ret = create_thermal_profile(wdev);
>>> +	else
>>> +		ret = alienware_alienfx_setup(&pdata);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static void wmax_wmi_remove(struct wmi_device *wdev)
>>> +{
>>> +	if (quirks->thermal)
>>> +		remove_thermal_profile();
>>> +	else
>>> +		alienware_alienfx_exit(wdev);
>>> +}
>>> +
>>> +static struct wmi_device_id alienware_wmax_device_id_table[] = {
>>> +	{ WMAX_CONTROL_GUID, NULL },
>>> +	{ },
>>> +};
>>> +MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
>>> +
>>> +static struct wmi_driver alienware_wmax_wmi_driver = {
>>> +	.driver = {
>>> +		.name = "alienware-wmi-wmax",
>>> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
>>> +	},
>>> +	.id_table = alienware_wmax_device_id_table,
>>> +	.probe = wmax_wmi_probe,
>>> +	.remove = wmax_wmi_remove,
>>> +};
>>> +
>>> +static int __init alienware_wmax_wmi_init(void)
>>> +{
>>> +	return wmi_driver_register(&alienware_wmax_wmi_driver);
>>> +}
>>> +
>>> +static void __exit alienware_wmax_wmi_exit(void)
>>> +{
>>> +	wmi_driver_unregister(&alienware_wmax_wmi_driver);
>>> +}
>>> +
>>> +static int __init alienware_wmi_init(void)
>>> +{
>>> +	int ret;
>>> +
>>>    	dmi_check_system(alienware_quirks);
>>>    	if (quirks == NULL)
>>>    		quirks = &quirk_unknown;
>>> @@ -1180,43 +1301,28 @@ static int __init alienware_wmi_init(void)
>>>    			pr_warn("force_gmode requires platform profile support\n");
>>>    	}
>>>
>>> -	ret = platform_driver_register(&platform_driver);
>>> -	if (ret)
>>> -		goto fail_platform_driver;
>>> -	platform_device = platform_device_alloc("alienware-wmi", PLATFORM_DEVID_NONE);
>>> -	if (!platform_device) {
>>> -		ret = -ENOMEM;
>>> -		goto fail_platform_device1;
>>> +	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
>>> +		interface = WMAX;
>>> +		ret = alienware_wmax_wmi_init();
>>> +	} else {
>>> +		interface = LEGACY;
>>> +		ret = alienware_legacy_wmi_init();
>>>    	}
>>> -	ret = platform_device_add(platform_device);
>>> -	if (ret)
>>> -		goto fail_platform_device2;
>>>
>>> -	if (quirks->thermal) {
>>> -		ret = create_thermal_profile(platform_device);
>>> -		if (ret)
>>> -			goto fail_prep_thermal_profile;
>>> -	}
>>> +	if (ret < 0)
>>> +		return ret;
>>>
>>>    	return 0;
>>> -
>>> -fail_prep_thermal_profile:
>>> -	platform_device_del(platform_device);
>>> -fail_platform_device2:
>>> -	platform_device_put(platform_device);
>>> -fail_platform_device1:
>>> -	platform_driver_unregister(&platform_driver);
>>> -fail_platform_driver:
>>> -	return ret;
>>>    }
>>>
>>>    module_init(alienware_wmi_init);
>>>
>>>    static void __exit alienware_wmi_exit(void)
>>>    {
>>> -	remove_thermal_profile();
>>> -	platform_device_unregister(platform_device);
>>> -	platform_driver_unregister(&platform_driver);
>>> +	if (interface == WMAX)
>>> +		alienware_wmax_wmi_exit();
>>> +	else
>>> +		alienware_legacy_wmi_exit();
>>>    }
>>>
>>>    module_exit(alienware_wmi_exit);

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] alienware-wmi: Split DMI table
  2024-12-27  4:55     ` Kurt Borja
@ 2024-12-29  0:30       ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-29  0:30 UTC (permalink / raw)
  To: Kurt Borja
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

Am 27.12.24 um 05:55 schrieb Kurt Borja:

> On Fri, Dec 27, 2024 at 04:55:28AM +0100, Armin Wolf wrote:
>> Am 21.12.24 um 06:59 schrieb Kurt Borja:
>>
>>> Split thermal features into a new DMI table to support upcoming file
>>> split.
>> Could it be that you also decided to reorder the quirk entries?
> No. I'll make this split lower in the file, so it doesn't mess up the
> diff.
>
> If I did reorder it by accident I will fix it.

OK, having a clear diff would make it easier to verify that no quirk entries have been changed.

Thanks,
Armin Wolf

>
>> Thanks,
>> Armin WOlf
>>
>>> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
>>> ---
>>>    drivers/platform/x86/dell/alienware-wmi.c | 163 +++++++++-------------
>>>    1 file changed, 69 insertions(+), 94 deletions(-)
>>>
>>> diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
>>> index 0a0b72dc61ea..8ea08f5f8810 100644
>>> --- a/drivers/platform/x86/dell/alienware-wmi.c
>>> +++ b/drivers/platform/x86/dell/alienware-wmi.c
>>> @@ -118,8 +118,6 @@ struct quirk_entry {
>>>    	u8 hdmi_mux;
>>>    	u8 amplifier;
>>>    	u8 deepslp;
>>> -	bool thermal;
>>> -	bool gmode;
>>>    };
>>>
>>>    static struct quirk_entry *quirks;
>>> @@ -130,8 +128,6 @@ static struct quirk_entry quirk_inspiron5675 = {
>>>    	.hdmi_mux = 0,
>>>    	.amplifier = 0,
>>>    	.deepslp = 0,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static struct quirk_entry quirk_unknown = {
>>> @@ -139,8 +135,6 @@ static struct quirk_entry quirk_unknown = {
>>>    	.hdmi_mux = 0,
>>>    	.amplifier = 0,
>>>    	.deepslp = 0,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static struct quirk_entry quirk_x51_r1_r2 = {
>>> @@ -148,8 +142,6 @@ static struct quirk_entry quirk_x51_r1_r2 = {
>>>    	.hdmi_mux = 0,
>>>    	.amplifier = 0,
>>>    	.deepslp = 0,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static struct quirk_entry quirk_x51_r3 = {
>>> @@ -157,8 +149,6 @@ static struct quirk_entry quirk_x51_r3 = {
>>>    	.hdmi_mux = 0,
>>>    	.amplifier = 1,
>>>    	.deepslp = 0,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static struct quirk_entry quirk_asm100 = {
>>> @@ -166,8 +156,6 @@ static struct quirk_entry quirk_asm100 = {
>>>    	.hdmi_mux = 1,
>>>    	.amplifier = 0,
>>>    	.deepslp = 0,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static struct quirk_entry quirk_asm200 = {
>>> @@ -175,8 +163,6 @@ static struct quirk_entry quirk_asm200 = {
>>>    	.hdmi_mux = 1,
>>>    	.amplifier = 0,
>>>    	.deepslp = 1,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static struct quirk_entry quirk_asm201 = {
>>> @@ -184,26 +170,6 @@ static struct quirk_entry quirk_asm201 = {
>>>    	.hdmi_mux = 1,
>>>    	.amplifier = 1,
>>>    	.deepslp = 1,
>>> -	.thermal = false,
>>> -	.gmode = false,
>>> -};
>>> -
>>> -static struct quirk_entry quirk_g_series = {
>>> -	.num_zones = 2,
>>> -	.hdmi_mux = 0,
>>> -	.amplifier = 0,
>>> -	.deepslp = 0,
>>> -	.thermal = true,
>>> -	.gmode = true,
>>> -};
>>> -
>>> -static struct quirk_entry quirk_x_series = {
>>> -	.num_zones = 2,
>>> -	.hdmi_mux = 0,
>>> -	.amplifier = 0,
>>> -	.deepslp = 0,
>>> -	.thermal = true,
>>> -	.gmode = false,
>>>    };
>>>
>>>    static int __init dmi_matched(const struct dmi_system_id *dmi)
>>> @@ -242,133 +208,140 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
>>>    	},
>>>    	{
>>>    		.callback = dmi_matched,
>>> -		.ident = "Alienware m17 R5",
>>> +		.ident = "Alienware X51 R1",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
>>>    		},
>>> -		.driver_data = &quirk_x_series,
>>> +		.driver_data = &quirk_x51_r1_r2,
>>>    	},
>>>    	{
>>>    		.callback = dmi_matched,
>>> -		.ident = "Alienware m18 R2",
>>> +		.ident = "Alienware X51 R2",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
>>>    		},
>>> -		.driver_data = &quirk_x_series,
>>> +		.driver_data = &quirk_x51_r1_r2,
>>>    	},
>>>    	{
>>>    		.callback = dmi_matched,
>>> -		.ident = "Alienware x15 R1",
>>> +		.ident = "Alienware X51 R3",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
>>>    		},
>>> -		.driver_data = &quirk_x_series,
>>> +		.driver_data = &quirk_x51_r3,
>>>    	},
>>>    	{
>>>    		.callback = dmi_matched,
>>> -		.ident = "Alienware x17 R2",
>>> +		.ident = "Dell Inc. Inspiron 5675",
>>> +		.matches = {
>>> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
>>> +		},
>>> +		.driver_data = &quirk_inspiron5675,
>>> +	},
>>> +	{}
>>> +};
>>> +
>>> +struct awcc_features {
>>> +	bool gmode;
>>> +};
>>> +
>>> +static struct awcc_features g_series_features = {
>>> +	.gmode = true,
>>> +};
>>> +
>>> +static struct awcc_features x_series_features = {
>>> +	.gmode = false,
>>> +};
>>> +
>>> +static const struct dmi_system_id awcc_dmi_table[] __initconst = {
>>> +	{
>>> +		.ident = "Alienware m17 R5",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
>>>    		},
>>> -		.driver_data = &quirk_x_series,
>>> +		.driver_data = &x_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>> -		.ident = "Alienware X51 R1",
>>> +		.ident = "Alienware m18 R2",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
>>>    		},
>>> -		.driver_data = &quirk_x51_r1_r2,
>>> +		.driver_data = &x_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>> -		.ident = "Alienware X51 R2",
>>> +		.ident = "Alienware x15 R1",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
>>>    		},
>>> -		.driver_data = &quirk_x51_r1_r2,
>>> +		.driver_data = &x_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>> -		.ident = "Alienware X51 R3",
>>> +		.ident = "Alienware x17 R2",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
>>> +			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
>>>    		},
>>> -		.driver_data = &quirk_x51_r3,
>>> +		.driver_data = &x_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>>    		.ident = "Dell Inc. G15 5510",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>>    			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
>>>    		},
>>> -		.driver_data = &quirk_g_series,
>>> +		.driver_data = &g_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>>    		.ident = "Dell Inc. G15 5511",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>>    			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
>>>    		},
>>> -		.driver_data = &quirk_g_series,
>>> +		.driver_data = &g_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>>    		.ident = "Dell Inc. G15 5515",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>>    			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
>>>    		},
>>> -		.driver_data = &quirk_g_series,
>>> +		.driver_data = &g_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>>    		.ident = "Dell Inc. G3 3500",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>>    			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
>>>    		},
>>> -		.driver_data = &quirk_g_series,
>>> +		.driver_data = &g_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>>    		.ident = "Dell Inc. G3 3590",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>>    			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
>>>    		},
>>> -		.driver_data = &quirk_g_series,
>>> +		.driver_data = &g_series_features,
>>>    	},
>>>    	{
>>> -		.callback = dmi_matched,
>>>    		.ident = "Dell Inc. G5 5500",
>>>    		.matches = {
>>>    			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>>    			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
>>>    		},
>>> -		.driver_data = &quirk_g_series,
>>> -	},
>>> -	{
>>> -		.callback = dmi_matched,
>>> -		.ident = "Dell Inc. Inspiron 5675",
>>> -		.matches = {
>>> -			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
>>> -			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
>>> -		},
>>> -		.driver_data = &quirk_inspiron5675,
>>> +		.driver_data = &g_series_features,
>>>    	},
>>> -	{}
>>>    };
>>>
>>> +struct awcc_features *awcc;
>>> +
>>>    struct color_platform {
>>>    	u8 blue;
>>>    	u8 green;
>>> @@ -1009,7 +982,7 @@ static int thermal_profile_set(struct platform_profile_handler *pprof,
>>>
>>>    	priv = container_of(pprof, struct awcc_priv, pp_handler);
>>>
>>> -	if (quirks->gmode) {
>>> +	if (awcc->gmode) {
>>>    		u32 gmode_status;
>>>    		int ret;
>>>
>>> @@ -1077,7 +1050,7 @@ static int create_thermal_profile(struct wmi_device *wdev)
>>>    	if (bitmap_empty(priv->pp_handler.choices, PLATFORM_PROFILE_LAST))
>>>    		return -ENODEV;
>>>
>>> -	if (quirks->gmode) {
>>> +	if (awcc->gmode) {
>>>    		priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
>>>    			WMAX_THERMAL_MODE_GMODE;
>>>
>>> @@ -1328,7 +1301,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>>>    	};
>>>    	int ret = 0;
>>>
>>> -	if (quirks->thermal)
>>> +	if (awcc)
>>>    		ret = alienware_awcc_setup(wdev);
>>>    	else
>>>    		ret = alienware_alienfx_setup(&pdata);
>>> @@ -1338,7 +1311,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
>>>
>>>    static void wmax_wmi_remove(struct wmi_device *wdev)
>>>    {
>>> -	if (quirks->thermal)
>>> +	if (awcc)
>>>    		alienware_awcc_exit(wdev);
>>>    	else
>>>    		alienware_alienfx_exit(wdev);
>>> @@ -1362,6 +1335,18 @@ static struct wmi_driver alienware_wmax_wmi_driver = {
>>>
>>>    static int __init alienware_wmax_wmi_init(void)
>>>    {
>>> +	const struct dmi_system_id *id;
>>> +
>>> +	id = dmi_first_match(awcc_dmi_table);
>>> +	if (id)
>>> +		awcc = id->driver_data;
>>> +
>>> +	if (force_platform_profile)
>>> +		awcc = &x_series_features;
>>> +
>>> +	if (force_gmode)
>>> +		awcc = &g_series_features;
>>> +
>>>    	return wmi_driver_register(&alienware_wmax_wmi_driver);
>>>    }
>>>
>>> @@ -1378,16 +1363,6 @@ static int __init alienware_wmi_init(void)
>>>    	if (quirks == NULL)
>>>    		quirks = &quirk_unknown;
>>>
>>> -	if (force_platform_profile)
>>> -		quirks->thermal = true;
>>> -
>>> -	if (force_gmode) {
>>> -		if (quirks->thermal)
>>> -			quirks->gmode = true;
>>> -		else
>>> -			pr_warn("force_gmode requires platform profile support\n");
>>> -	}
>>> -
>>>    	if (wmi_has_guid(WMAX_CONTROL_GUID)) {
>>>    		interface = WMAX;
>>>    		ret = alienware_wmax_wmi_init();

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 18/20] platform/x86: dell: Modify Makefile alignment
  2024-12-27  4:57     ` Kurt Borja
@ 2024-12-29  0:31       ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-29  0:31 UTC (permalink / raw)
  To: Kurt Borja
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

Am 27.12.24 um 05:57 schrieb Kurt Borja:

> On Fri, Dec 27, 2024 at 05:05:30AM +0100, Armin Wolf wrote:
>> Am 21.12.24 um 06:59 schrieb Kurt Borja:
>>
>>> Add one more TAB to each line to support upcoming changes.
>> Please merge this with patch 19.
> I'm almost certain I read an email in the lists, in which a maintainer
> asked these to be separate changes.
>
> I have no problem with stashing them tho.

I was not aware of that email.

In this case:

Reviewed-by: Armin Wolf <W_Armin@gmx.de>

>> Thanks,
>> Armin Wolf
>>
>>> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
>>> ---
>>>    drivers/platform/x86/dell/Makefile | 48 +++++++++++++++---------------
>>>    1 file changed, 24 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
>>> index 03ba459f3d31..d5718ef34c48 100644
>>> --- a/drivers/platform/x86/dell/Makefile
>>> +++ b/drivers/platform/x86/dell/Makefile
>>> @@ -4,27 +4,27 @@
>>>    # Dell x86 Platform-Specific Drivers
>>>    #
>>>
>>> -obj-$(CONFIG_ALIENWARE_WMI)		+= alienware-wmi.o
>>> -alienware-wmi-objs			:= alienware-wmi-base.o
>>> -alienware-wmi-y				+= alienware-wmi-legacy.o
>>> -alienware-wmi-y				+= alienware-wmi-wmax.o
>>> -obj-$(CONFIG_DCDBAS)			+= dcdbas.o
>>> -obj-$(CONFIG_DELL_LAPTOP)		+= dell-laptop.o
>>> -obj-$(CONFIG_DELL_RBTN)			+= dell-rbtn.o
>>> -obj-$(CONFIG_DELL_RBU)			+= dell_rbu.o
>>> -obj-$(CONFIG_DELL_PC)			+= dell-pc.o
>>> -obj-$(CONFIG_DELL_SMBIOS)		+= dell-smbios.o
>>> -dell-smbios-objs			:= dell-smbios-base.o
>>> -dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)	+= dell-smbios-wmi.o
>>> -dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)	+= dell-smbios-smm.o
>>> -obj-$(CONFIG_DELL_SMO8800)		+= dell-smo8800.o
>>> -obj-$(CONFIG_DELL_SMO8800)		+= dell-lis3lv02d.o
>>> -obj-$(CONFIG_DELL_UART_BACKLIGHT)	+= dell-uart-backlight.o
>>> -obj-$(CONFIG_DELL_WMI)			+= dell-wmi.o
>>> -dell-wmi-objs				:= dell-wmi-base.o
>>> -dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)	+= dell-wmi-privacy.o
>>> -obj-$(CONFIG_DELL_WMI_AIO)		+= dell-wmi-aio.o
>>> -obj-$(CONFIG_DELL_WMI_DESCRIPTOR)	+= dell-wmi-descriptor.o
>>> -obj-$(CONFIG_DELL_WMI_DDV)		+= dell-wmi-ddv.o
>>> -obj-$(CONFIG_DELL_WMI_LED)		+= dell-wmi-led.o
>>> -obj-$(CONFIG_DELL_WMI_SYSMAN)		+= dell-wmi-sysman/
>>> +obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
>>> +alienware-wmi-objs				:= alienware-wmi-base.o
>>> +alienware-wmi-y					+= alienware-wmi-legacy.o
>>> +alienware-wmi-y					+= alienware-wmi-wmax.o
>>> +obj-$(CONFIG_DCDBAS)				+= dcdbas.o
>>> +obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
>>> +obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
>>> +obj-$(CONFIG_DELL_RBU)				+= dell_rbu.o
>>> +obj-$(CONFIG_DELL_PC)				+= dell-pc.o
>>> +obj-$(CONFIG_DELL_SMBIOS)			+= dell-smbios.o
>>> +dell-smbios-objs				:= dell-smbios-base.o
>>> +dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)		+= dell-smbios-wmi.o
>>> +dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)		+= dell-smbios-smm.o
>>> +obj-$(CONFIG_DELL_SMO8800)			+= dell-smo8800.o
>>> +obj-$(CONFIG_DELL_SMO8800)			+= dell-lis3lv02d.o
>>> +obj-$(CONFIG_DELL_UART_BACKLIGHT)		+= dell-uart-backlight.o
>>> +obj-$(CONFIG_DELL_WMI)				+= dell-wmi.o
>>> +dell-wmi-objs					:= dell-wmi-base.o
>>> +dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)		+= dell-wmi-privacy.o
>>> +obj-$(CONFIG_DELL_WMI_AIO)			+= dell-wmi-aio.o
>>> +obj-$(CONFIG_DELL_WMI_DESCRIPTOR)		+= dell-wmi-descriptor.o
>>> +obj-$(CONFIG_DELL_WMI_DDV)			+= dell-wmi-ddv.o
>>> +obj-$(CONFIG_DELL_WMI_LED)			+= dell-wmi-led.o
>>> +obj-$(CONFIG_DELL_WMI_SYSMAN)			+= dell-wmi-sysman/

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 19/20] platform/x86: Update alienware-wmi config entries
  2024-12-27  4:59     ` Kurt Borja
@ 2024-12-29  0:32       ` Armin Wolf
  0 siblings, 0 replies; 61+ messages in thread
From: Armin Wolf @ 2024-12-29  0:32 UTC (permalink / raw)
  To: Kurt Borja
  Cc: platform-driver-x86, ilpo.jarvinen, mario.limonciello, hdegoede,
	linux-kernel, Dell.Client.Kernel

Am 27.12.24 um 05:59 schrieb Kurt Borja:

> On Fri, Dec 27, 2024 at 05:08:03AM +0100, Armin Wolf wrote:
>> Am 21.12.24 um 06:59 schrieb Kurt Borja:
>>
>>> Add config entries for each WMI driver managed by the alienware-wmi
>>> module to be able to conditionally compile them.
>>>
>>> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
>>> ---
>>>    drivers/platform/x86/dell/Kconfig         | 30 +++++++++++++++++++----
>>>    drivers/platform/x86/dell/Makefile        |  4 +--
>>>    drivers/platform/x86/dell/alienware-wmi.h | 23 +++++++++++++++++
>>>    3 files changed, 50 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
>>> index d09060aedd3f..f8a0dffcaab7 100644
>>> --- a/drivers/platform/x86/dell/Kconfig
>>> +++ b/drivers/platform/x86/dell/Kconfig
>>> @@ -18,15 +18,35 @@ config ALIENWARE_WMI
>>>    	tristate "Alienware Special feature control"
>>>    	default m
>>>    	depends on ACPI
>>> +	depends on ACPI_WMI
>>> +	depends on DMI
>>>    	depends on LEDS_CLASS
>>>    	depends on NEW_LEDS
>>> -	depends on ACPI_WMI
>>> +	help
>>> +	 This is a driver for controlling Alienware WMI driven features.
>>> +
>>> +	 On legacy devices, it exposes an interface for controlling the AlienFX
>>> +	 zones on Alienware machines that don't contain a dedicated
>>> +	 AlienFX USB MCU such as the X51 and X51-R2.
>>> +
>>> +	 On newer devices, it exposes the AWCC thermal control interface through
>>> +	 known Kernel APIs.
>>> +
>>> +config ALIENWARE_WMI_LEGACY
>>> +	bool "Alienware Legacy WMI device driver"
>>> +	default y
>>> +	depends on ALIENWARE_WMI
>>> +	help
>>> +	 Legacy Alienware WMI driver with AlienFX LED control capabilities.
>>> +
>>> +config ALIENWARE_WMI_WMAX
>>> +	bool "Alienware WMAX WMI device driver"
>>> +	default y
>>> +	depends on ALIENWARE_WMI
>>>    	select ACPI_PLATFORM_PROFILE
>>>    	help
>>> -	 This is a driver for controlling Alienware BIOS driven
>>> -	 features.  It exposes an interface for controlling the AlienFX
>>> -	 zones on Alienware machines that don't contain a dedicated AlienFX
>>> -	 USB MCU such as the X51 and X51-R2.
>>> +	 Alienware WMI driver with AlienFX LED, HDMI, amplifier, deep sleep and
>>> +	 AWCC thermal control capabilities.
>>>
>>>    config DCDBAS
>>>    	tristate "Dell Systems Management Base Driver"
>>> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
>>> index d5718ef34c48..8ac9a933c770 100644
>>> --- a/drivers/platform/x86/dell/Makefile
>>> +++ b/drivers/platform/x86/dell/Makefile
>>> @@ -6,8 +6,8 @@
>>>
>>>    obj-$(CONFIG_ALIENWARE_WMI)			+= alienware-wmi.o
>>>    alienware-wmi-objs				:= alienware-wmi-base.o
>>> -alienware-wmi-y					+= alienware-wmi-legacy.o
>>> -alienware-wmi-y					+= alienware-wmi-wmax.o
>>> +alienware-wmi-$(CONFIG_ALIENWARE_WMI_LEGACY)	+= alienware-wmi-legacy.o
>>> +alienware-wmi-$(CONFIG_ALIENWARE_WMI_WMAX)	+= alienware-wmi-wmax.o
>>>    obj-$(CONFIG_DCDBAS)				+= dcdbas.o
>>>    obj-$(CONFIG_DELL_LAPTOP)			+= dell-laptop.o
>>>    obj-$(CONFIG_DELL_RBTN)				+= dell-rbtn.o
>>> diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
>>> index 78ac10122155..97b52e51cd7d 100644
>>> --- a/drivers/platform/x86/dell/alienware-wmi.h
>>> +++ b/drivers/platform/x86/dell/alienware-wmi.h
>>> @@ -94,10 +94,33 @@ acpi_status alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
>>>    int alienware_alienfx_setup(struct alienfx_platdata *pdata);
>>>    void alienware_alienfx_exit(struct wmi_device *wdev);
>>>
>>> +#if IS_ENABLED(CONFIG_ALIENWARE_WMI_LEGACY)
>>>    int __init alienware_legacy_wmi_init(void);
>>>    void __exit alienware_legacy_wmi_exit(void);
>>> +#else
>>> +int __init alienware_legacy_wmi_init(void)
>>> +{
>>> +	return 0;
>> Please return -EOPNOTSUPP here.
> Maybe -ENODEV is better in this case?
>
> Also this should be static inline, I'll fix it.

-ENODEV is also OK.

Thanks,
Armin Wolf

>
>>> +}
>>> +
>>> +void __exit alienware_legacy_wmi_exit(void)
>>> +{
>>> +}
>>> +#endif
>>>
>>> +#if IS_ENABLED(CONFIG_ALIENWARE_WMI_WMAX)
>>>    int __init alienware_wmax_wmi_init(void);
>>>    void __exit alienware_wmax_wmi_exit(void);
>>> +#else
>>> +int __init alienware_wmax_wmi_init(void)
>>> +{
>>> +	return 0;
>> Same as above.
>>
>> Thanks,
>> Armin Wolf
>>
>>> +}
>>> +
>>> +
>>> +void __exit alienware_wmax_wmi_exit(void)
>>> +{
>>> +}
>>> +#endif
>>>
>>>    #endif

^ permalink raw reply	[flat|nested] 61+ messages in thread

end of thread, other threads:[~2024-12-29  0:33 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-21  5:58 [PATCH 00/20] alienware-wmi driver rework Kurt Borja
2024-12-21  5:58 ` [PATCH 01/20] alienware-wmi: Remove unnecessary check at module exit Kurt Borja
2024-12-27  0:32   ` Armin Wolf
2024-12-21  5:58 ` [PATCH 02/20] alienware-wmi: Move Lighting Control State Kurt Borja
2024-12-27  0:35   ` Armin Wolf
2024-12-27  4:32     ` Kurt Borja
2024-12-21  5:59 ` [PATCH 03/20] alienware-wmi: Modify parse_rgb() signature Kurt Borja
2024-12-27  0:36   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 04/20] alienware-wmi: Improve hdmi_mux, amplifier and deepslp group creation Kurt Borja
2024-12-27  0:44   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 05/20] alienware-wmi: Improve rgb-zones " Kurt Borja
2024-12-27  1:04   ` Armin Wolf
2024-12-27  4:37     ` Kurt Borja
2024-12-29  0:17       ` Armin Wolf
2024-12-21  5:59 ` [PATCH 06/20] alienware_wmi: Clean variable declaration in thermal methods Kurt Borja
2024-12-27  1:06   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 07/20] alienware-wmi: Add a state container for LED control feature Kurt Borja
2024-12-27  1:32   ` Armin Wolf
2024-12-27  4:39     ` Kurt Borja
2024-12-21  5:59 ` [PATCH 08/20] alienware-wmi: Add WMI Drivers Kurt Borja
2024-12-27  3:21   ` Armin Wolf
2024-12-27  4:44     ` Kurt Borja
2024-12-27  4:48       ` Kurt Borja
2024-12-29  0:26       ` Armin Wolf
2024-12-21  5:59 ` [PATCH 09/20] alienware-wmi: Add a state container for thermal control methods Kurt Borja
2024-12-27  3:26   ` Armin Wolf
2024-12-27  4:50     ` Kurt Borja
2024-12-21  5:59 ` [PATCH 10/20] alienware-wmi: Refactor LED " Kurt Borja
2024-12-27  3:41   ` Armin Wolf
2024-12-27  4:52     ` Kurt Borja
2024-12-21  5:59 ` [PATCH 11/20] alienware-wmi: Refactor hdmi, amplifier, deepslp methods Kurt Borja
2024-12-27  3:43   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 12/20] alienware-wmi: Refactor thermal control methods Kurt Borja
2024-12-27  3:45   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 13/20] alienware-wmi: Split DMI table Kurt Borja
2024-12-27  3:55   ` Armin Wolf
2024-12-27  4:55     ` Kurt Borja
2024-12-29  0:30       ` Armin Wolf
2024-12-21  5:59 ` [PATCH 14/20] MAINTAINERS: Update ALIENWARE WMI DRIVER entry Kurt Borja
2024-12-27  3:56   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 15/20] platform/x86: Rename alienware-wmi.c Kurt Borja
2024-12-27  3:57   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 16/20] platform/x86: Add alienware-wmi.h Kurt Borja
2024-12-27  4:02   ` Armin Wolf
2024-12-27  4:56     ` Kurt Borja
2024-12-21  5:59 ` [PATCH 17/20] platform-x86: Split the alienware-wmi driver Kurt Borja
2024-12-27  4:04   ` Armin Wolf
2024-12-21  5:59 ` [PATCH 18/20] platform/x86: dell: Modify Makefile alignment Kurt Borja
2024-12-27  4:05   ` Armin Wolf
2024-12-27  4:57     ` Kurt Borja
2024-12-29  0:31       ` Armin Wolf
2024-12-21  5:59 ` [PATCH 19/20] platform/x86: Update alienware-wmi config entries Kurt Borja
2024-12-27  4:08   ` Armin Wolf
2024-12-27  4:59     ` Kurt Borja
2024-12-29  0:32       ` Armin Wolf
2024-12-21  5:59 ` [PATCH 20/20] alienware-wmi: Update header and module information Kurt Borja
2024-12-27  4:08   ` Armin Wolf
2024-12-27  5:01     ` Kurt Borja
2024-12-22 23:06 ` [PATCH 00/20] alienware-wmi driver rework Armin Wolf
2024-12-25 20:25   ` Armin Wolf
2024-12-25 20:36     ` Kurt Borja

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).