platform-driver-x86.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] platform/x86: dell-laptop: Implement platform_profile
@ 2024-04-25 17:27 Lyndon Sanche
  2024-04-25 20:07 ` Mario Limonciello
                   ` (11 more replies)
  0 siblings, 12 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-25 17:27 UTC (permalink / raw)
  To: lsanche
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Some Dell laptops support configuration of preset
fan modes through smbios tables.

If the platform supports these fan modes, set up
platform_profile to change these modes. If not
supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 drivers/platform/x86/dell/dell-laptop.c | 220 ++++++++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios.h |   1 +
 2 files changed, 221 insertions(+)

diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..7f9c4e0e5ef5 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -27,6 +27,7 @@
 #include <linux/i8042.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/platform_profile.h>
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
@@ -95,10 +96,18 @@ static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct platform_profile_handler *thermal_handler;
 static bool force_rfkill;
 static bool micmute_led_registered;
 static bool mute_led_registered;
 
+enum thermal_mode_bits {
+	DELL_BALANCED = 0,
+	DELL_COOL_BOTTOM = 1,
+	DELL_QUIET = 2,
+	DELL_PERFORMANCE = 3,
+};
+
 module_param(force_rfkill, bool, 0444);
 MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
 
@@ -2199,6 +2208,211 @@ static int mute_led_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
+// Derived from smbios-thermal-ctl
+//
+// cbClass 17
+// cbSelect 19
+// User Selectable Thermal Tables(USTT)
+// cbArg1 determines the function to be performed
+// cbArg1 0x0 = Get Thermal Information
+//  cbRES1         Standard return codes (0, -1, -2)
+//  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if its bit is set to 1
+//     Bit 0 Balanced
+//     Bit 1 Cool Bottom
+//     Bit 2 Quiet
+//     Bit 3 Performance
+//  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes. Each mode
+//                 corresponds to the supported thermal modes in byte 0. A mode is supported if
+//                 its bit is set to 1.
+//     Bit 0 AAC (Balanced)
+//     Bit 1 AAC (Cool Bottom
+//     Bit 2 AAC (Quiet)
+//     Bit 3 AAC (Performance)
+//  cbRes3, byte 0 Current Thermal Mode
+//     Bit 0 Balanced
+//     Bit 1 Cool Bottom
+//     Bit 2 Quiet
+//     Bit 3 Performanc
+//  cbRes3, byte 1  AAC Configuration type
+//          0       Global (AAC enable/disable applies to all supported USTT modes)
+//          1       USTT mode specific
+//  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+//     If AAC Configuration Type is Global,
+//          0       AAC mode disabled
+//          1       AAC mode enabled
+//     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+//          Bit 0 AAC (Balanced)
+//          Bit 1 AAC (Cool Bottom
+//          Bit 2 AAC (Quiet)
+//          Bit 3 AAC (Performance)
+//  cbRes3, byte 3  Current Fan Failure Mode
+//     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+//     Bit 1 Catastrophic Fan Failure (all fans have failed)
+//  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+//               desired AAC mode shall be applied
+//  cbArg2, byte 0  Desired Thermal Mode to set (only one bit may be set for this parameter)
+//     Bit 0 Balanced
+//     Bit 1 Cool Bottom
+//     Bit 2 Quiet
+//     Bit 3 Performance
+//  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+//     If AAC Configuration Type is Global,
+//         0  AAC mode disabled
+//         1  AAC mode enabled
+//
+//     If AAC Configuration Type is USTT mode specific (multiple bits may be set for this parameter),
+//         Bit 0 AAC (Balanced)
+//         Bit 1 AAC (Cool Bottom
+//         Bit 2 AAC (Quiet)
+//         Bit 3 AAC (Performance)
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if ((state >> DELL_BALANCED) & 1)
+		return DELL_BALANCED;
+	else if ((state >> DELL_COOL_BOTTOM) & 1)
+		return DELL_COOL_BOTTOM;
+	else if ((state >> DELL_QUIET) & 1)
+		return DELL_QUIET;
+	else if ((state >> DELL_PERFORMANCE) & 1)
+		return DELL_PERFORMANCE;
+	else
+		return 0;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*supported_bits = buffer.output[1] & 0xF;
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = ((buffer.output[3] >> 8) & 0xFF);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, (acc_mode << 8) | BIT(state), 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	int ret;
+
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		ret = thermal_set_mode(DELL_BALANCED);
+		break;
+	case PLATFORM_PROFILE_PERFORMANCE:
+		ret = thermal_set_mode(DELL_PERFORMANCE);
+		break;
+	case PLATFORM_PROFILE_QUIET:
+		ret = thermal_set_mode(DELL_QUIET);
+		break;
+	case PLATFORM_PROFILE_COOL:
+		ret = thermal_set_mode(DELL_COOL_BOTTOM);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	switch (thermal_get_mode()) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	ret = thermal_get_supported_modes(&supported_modes);
+
+	if (ret != 0 || supported_modes == 0)
+		return -ENXIO;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if ((supported_modes >> DELL_QUIET) & 1)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if ((supported_modes >> DELL_BALANCED) & 1)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if ((supported_modes >> DELL_PERFORMANCE) & 1)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	platform_profile_register(thermal_handler);
+
+	return 0;
+}
+
+void thermal_cleanup(void)
+{
+	platform_profile_remove();
+	kfree(thermal_handler);
+}
+
 static struct led_classdev mute_led_cdev = {
 	.name = "platform::mute",
 	.max_brightness = 1,
@@ -2266,6 +2480,11 @@ static int __init dell_init(void)
 		mute_led_registered = true;
 	}
 
+	// Do not fail module if thermal modes not supported,
+	// just skip
+	if (thermal_init() != 0)
+		pr_warn("Unable to setup platform_profile, skipping");
+
 	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
 		return 0;
 
@@ -2344,6 +2563,7 @@ static void __exit dell_exit(void)
 		platform_device_unregister(platform_device);
 		platform_driver_unregister(&platform_driver);
 	}
+	thermal_cleanup();
 }
 
 /* dell-rbtn.c driver export functions which will not work correctly (and could
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..585d042f1779 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
@ 2024-04-25 20:07 ` Mario Limonciello
  2024-04-25 20:24   ` Lyndon Sanche
  2024-04-25 20:12 ` Pali Rohár
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 72+ messages in thread
From: Mario Limonciello @ 2024-04-25 20:07 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel, 'Srinivas Pandruvada'

+ Srinivas

On 4/25/2024 12:27, Lyndon Sanche wrote:
> Some Dell laptops support configuration of preset
> fan modes through smbios tables.
> 
> If the platform supports these fan modes, set up
> platform_profile to change these modes. If not
> supported, skip enabling platform_profile.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---

When you developed this was it using a Dell Intel or Dell AMD system?

If it was an Intel system, did you test it with thermald installed and 
active?

I'm wondering how all this stuff jives with the stuff that thermald 
does.  I don't know if they fight for any of the same "resources".

>   drivers/platform/x86/dell/dell-laptop.c | 220 ++++++++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios.h |   1 +
>   2 files changed, 221 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..7f9c4e0e5ef5 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,7 @@
>   #include <linux/i8042.h>
>   #include <linux/debugfs.h>
>   #include <linux/seq_file.h>
> +#include <linux/platform_profile.h>
>   #include <acpi/video.h>
>   #include "dell-rbtn.h"
>   #include "dell-smbios.h"
> @@ -95,10 +96,18 @@ static struct backlight_device *dell_backlight_device;
>   static struct rfkill *wifi_rfkill;
>   static struct rfkill *bluetooth_rfkill;
>   static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>   static bool force_rfkill;
>   static bool micmute_led_registered;
>   static bool mute_led_registered;
>   
> +enum thermal_mode_bits {
> +	DELL_BALANCED = 0,
> +	DELL_COOL_BOTTOM = 1,
> +	DELL_QUIET = 2,
> +	DELL_PERFORMANCE = 3,
> +};
> +
>   module_param(force_rfkill, bool, 0444);
>   MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
>   
> @@ -2199,6 +2208,211 @@ static int mute_led_set(struct led_classdev *led_cdev,
>   	return 0;
>   }
>   
> +// Derived from smbios-thermal-ctl
> +//
> +// cbClass 17
> +// cbSelect 19
> +// User Selectable Thermal Tables(USTT)
> +// cbArg1 determines the function to be performed
> +// cbArg1 0x0 = Get Thermal Information
> +//  cbRES1         Standard return codes (0, -1, -2)
> +//  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if its bit is set to 1
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performance
> +//  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes. Each mode
> +//                 corresponds to the supported thermal modes in byte 0. A mode is supported if
> +//                 its bit is set to 1.
> +//     Bit 0 AAC (Balanced)
> +//     Bit 1 AAC (Cool Bottom
> +//     Bit 2 AAC (Quiet)
> +//     Bit 3 AAC (Performance)
> +//  cbRes3, byte 0 Current Thermal Mode
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performanc
> +//  cbRes3, byte 1  AAC Configuration type
> +//          0       Global (AAC enable/disable applies to all supported USTT modes)
> +//          1       USTT mode specific
> +//  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> +//     If AAC Configuration Type is Global,
> +//          0       AAC mode disabled
> +//          1       AAC mode enabled
> +//     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> +//          Bit 0 AAC (Balanced)
> +//          Bit 1 AAC (Cool Bottom
> +//          Bit 2 AAC (Quiet)
> +//          Bit 3 AAC (Performance)
> +//  cbRes3, byte 3  Current Fan Failure Mode
> +//     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> +//     Bit 1 Catastrophic Fan Failure (all fans have failed)
> +//  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> +//               desired AAC mode shall be applied
> +//  cbArg2, byte 0  Desired Thermal Mode to set (only one bit may be set for this parameter)
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performance
> +//  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> +//     If AAC Configuration Type is Global,
> +//         0  AAC mode disabled
> +//         1  AAC mode enabled
> +//
> +//     If AAC Configuration Type is USTT mode specific (multiple bits may be set for this parameter),
> +//         Bit 0 AAC (Balanced)
> +//         Bit 1 AAC (Cool Bottom
> +//         Bit 2 AAC (Quiet)
> +//         Bit 3 AAC (Performance)
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if ((state >> DELL_BALANCED) & 1)
> +		return DELL_BALANCED;
> +	else if ((state >> DELL_COOL_BOTTOM) & 1)
> +		return DELL_COOL_BOTTOM;
> +	else if ((state >> DELL_QUIET) & 1)
> +		return DELL_QUIET;
> +	else if ((state >> DELL_PERFORMANCE) & 1)
> +		return DELL_PERFORMANCE;
> +	else
> +		return 0;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = buffer.output[1] & 0xF;
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = ((buffer.output[3] >> 8) & 0xFF);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, (acc_mode << 8) | BIT(state), 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	int ret;
> +
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		ret = thermal_set_mode(DELL_BALANCED);
> +		break;
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		ret = thermal_set_mode(DELL_PERFORMANCE);
> +		break;
> +	case PLATFORM_PROFILE_QUIET:
> +		ret = thermal_set_mode(DELL_QUIET);
> +		break;
> +	case PLATFORM_PROFILE_COOL:
> +		ret = thermal_set_mode(DELL_COOL_BOTTOM);
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	switch (thermal_get_mode()) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	ret = thermal_get_supported_modes(&supported_modes);
> +
> +	if (ret != 0 || supported_modes == 0)
> +		return -ENXIO;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if ((supported_modes >> DELL_QUIET) & 1)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if ((supported_modes >> DELL_BALANCED) & 1)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if ((supported_modes >> DELL_PERFORMANCE) & 1)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	platform_profile_register(thermal_handler);
> +
> +	return 0;
> +}
> +
> +void thermal_cleanup(void)
> +{
> +	platform_profile_remove();
> +	kfree(thermal_handler);
> +}
> +
>   static struct led_classdev mute_led_cdev = {
>   	.name = "platform::mute",
>   	.max_brightness = 1,
> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
>   		mute_led_registered = true;
>   	}
>   
> +	// Do not fail module if thermal modes not supported,
> +	// just skip
> +	if (thermal_init() != 0)
> +		pr_warn("Unable to setup platform_profile, skipping");
> +
>   	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
>   		return 0;
>   
> @@ -2344,6 +2563,7 @@ static void __exit dell_exit(void)
>   		platform_device_unregister(platform_device);
>   		platform_driver_unregister(&platform_driver);
>   	}
> +	thermal_cleanup();
>   }
>   
>   /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>   /* Classes and selects used only in kernel drivers */
>   #define CLASS_KBD_BACKLIGHT 4
>   #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>   
>   /* Tokens used in kernel drivers, any of these
>    * should be filtered from userspace access


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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
  2024-04-25 20:07 ` Mario Limonciello
@ 2024-04-25 20:12 ` Pali Rohár
  2024-04-25 20:27   ` Lyndon Sanche
  2024-04-25 21:07 ` Armin Wolf
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 72+ messages in thread
From: Pali Rohár @ 2024-04-25 20:12 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Matthew Garrett, Hans de Goede, Ilpo Järvinen,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

On Thursday 25 April 2024 11:27:57 Lyndon Sanche wrote:
> +int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	ret = thermal_get_supported_modes(&supported_modes);
> +
> +	if (ret != 0 || supported_modes == 0)
> +		return -ENXIO;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if ((supported_modes >> DELL_QUIET) & 1)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if ((supported_modes >> DELL_BALANCED) & 1)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if ((supported_modes >> DELL_PERFORMANCE) & 1)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	platform_profile_register(thermal_handler);
> +
> +	return 0;
> +}
> +
> +void thermal_cleanup(void)
> +{
> +	platform_profile_remove();
> +	kfree(thermal_handler);
> +}
> +
>  static struct led_classdev mute_led_cdev = {
>  	.name = "platform::mute",
>  	.max_brightness = 1,
> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
>  		mute_led_registered = true;
>  	}
>  
> +	// Do not fail module if thermal modes not supported,
> +	// just skip
> +	if (thermal_init() != 0)
> +		pr_warn("Unable to setup platform_profile, skipping");

I think that -ENOMEM error should be failure of the loading the driver.
It does not make sense to continue of memory allocation failed.

On the other hand when the thermal modes are not support (e.g. old
Latitude models) then there should not be a warning message. It is
expected that on systems without thermal modes the setup fails.

> +
>  	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
>  		return 0;

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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 20:07 ` Mario Limonciello
@ 2024-04-25 20:24   ` Lyndon Sanche
  2024-04-25 20:28     ` Mario Limonciello
  2024-04-26 16:14     ` srinivas pandruvada
  0 siblings, 2 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-25 20:24 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel, 'Srinivas Pandruvada'

On Thu, Apr 25, 2024, at 2:07 PM, Mario Limonciello wrote:
> + Srinivas
>
> On 4/25/2024 12:27, Lyndon Sanche wrote:
>> Some Dell laptops support configuration of preset
>> fan modes through smbios tables.
>> 
>> If the platform supports these fan modes, set up
>> platform_profile to change these modes. If not
>> supported, skip enabling platform_profile.
>> 
>> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>> ---
>
> When you developed this was it using a Dell Intel or Dell AMD system?
>
> If it was an Intel system, did you test it with thermald installed and 
> active?
>
> I'm wondering how all this stuff jives with the stuff that thermald 
> does.  I don't know if they fight for any of the same "resources".

Thank you for your response.

I did my development and testing on a Dell Intel system. Specifically the XPS 15 9560 with i7-7700HQ.

I do have thermald running, though I admit I am not really aware of what exactly it does, besides being related to thermals in some way.

I normally set the thermal mode with Dell's smbios-thermal-ctl program. I am not too sure all the values that the bios configures on it's own depending on the provided mode, so I am not sure if thermald conflicts. But my understanding is that would be out of scope of this driver, since we are only telling the bios what we want at a high level.

Lyndon

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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 20:12 ` Pali Rohár
@ 2024-04-25 20:27   ` Lyndon Sanche
  2024-04-25 20:31     ` Pali Rohár
  0 siblings, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-25 20:27 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Matthew Garrett, Hans de Goede, Ilpo Järvinen,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

On Thu, Apr 25, 2024, at 2:12 PM, Pali Rohár wrote:
> On Thursday 25 April 2024 11:27:57 Lyndon Sanche wrote:
>> +int thermal_init(void)
>> +{
>> +	int ret;
>> +	int supported_modes;
>> +
>> +	ret = thermal_get_supported_modes(&supported_modes);
>> +
>> +	if (ret != 0 || supported_modes == 0)
>> +		return -ENXIO;
>> +
>> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
>> +	if (!thermal_handler)
>> +		return -ENOMEM;
>> +	thermal_handler->profile_get = thermal_platform_profile_get;
>> +	thermal_handler->profile_set = thermal_platform_profile_set;
>> +
>> +	if ((supported_modes >> DELL_QUIET) & 1)
>> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
>> +	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
>> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
>> +	if ((supported_modes >> DELL_BALANCED) & 1)
>> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
>> +	if ((supported_modes >> DELL_PERFORMANCE) & 1)
>> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
>> +
>> +	platform_profile_register(thermal_handler);
>> +
>> +	return 0;
>> +}
>> +
>> +void thermal_cleanup(void)
>> +{
>> +	platform_profile_remove();
>> +	kfree(thermal_handler);
>> +}
>> +
>>  static struct led_classdev mute_led_cdev = {
>>  	.name = "platform::mute",
>>  	.max_brightness = 1,
>> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
>>  		mute_led_registered = true;
>>  	}
>>  
>> +	// Do not fail module if thermal modes not supported,
>> +	// just skip
>> +	if (thermal_init() != 0)
>> +		pr_warn("Unable to setup platform_profile, skipping");
>
> I think that -ENOMEM error should be failure of the loading the driver.
> It does not make sense to continue of memory allocation failed.
>
> On the other hand when the thermal modes are not support (e.g. old
> Latitude models) then there should not be a warning message. It is
> expected that on systems without thermal modes the setup fails.

Thank you for your feedback.

I agree with your suggestion. -ENOMEM would indicate something bigger is amiss. I can add a check:

If -ENOMEM, fail driver.
If anything other error, skip, but do not show a message.

Lyndon

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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 20:24   ` Lyndon Sanche
@ 2024-04-25 20:28     ` Mario Limonciello
  2024-04-25 21:51       ` Srinivas Pandruvada
  2024-04-26 16:14     ` srinivas pandruvada
  1 sibling, 1 reply; 72+ messages in thread
From: Mario Limonciello @ 2024-04-25 20:28 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel, 'Srinivas Pandruvada'

On 4/25/2024 15:24, Lyndon Sanche wrote:
> On Thu, Apr 25, 2024, at 2:07 PM, Mario Limonciello wrote:
>> + Srinivas
>>
>> On 4/25/2024 12:27, Lyndon Sanche wrote:
>>> Some Dell laptops support configuration of preset
>>> fan modes through smbios tables.
>>>
>>> If the platform supports these fan modes, set up
>>> platform_profile to change these modes. If not
>>> supported, skip enabling platform_profile.
>>>
>>> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>>> ---
>>
>> When you developed this was it using a Dell Intel or Dell AMD system?
>>
>> If it was an Intel system, did you test it with thermald installed and
>> active?
>>
>> I'm wondering how all this stuff jives with the stuff that thermald
>> does.  I don't know if they fight for any of the same "resources".
> 
> Thank you for your response.
> 
> I did my development and testing on a Dell Intel system. Specifically the XPS 15 9560 with i7-7700HQ.
> 
> I do have thermald running, though I admit I am not really aware of what exactly it does, besides being related to thermals in some way.
> 
> I normally set the thermal mode with Dell's smbios-thermal-ctl program. I am not too sure all the values that the bios configures on it's own depending on the provided mode, so I am not sure if thermald conflicts. But my understanding is that would be out of scope of this driver, since we are only telling the bios what we want at a high level.
> 
> Lyndon

Yeah it's not say it's a "new" conflict, it would just become a lot more 
prevalent since software like GNOME and KDE use power-profiles-daemon to 
manipulate the new power profile you're exporting from the driver.

If there really is no conflict, then great!
If there is a conflict then I was just wondering if there needs to be an 
easy way to turn on/off the profile support when thermald is in use.

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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 20:27   ` Lyndon Sanche
@ 2024-04-25 20:31     ` Pali Rohár
  0 siblings, 0 replies; 72+ messages in thread
From: Pali Rohár @ 2024-04-25 20:31 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Matthew Garrett, Hans de Goede, Ilpo Järvinen,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

On Thursday 25 April 2024 14:27:32 Lyndon Sanche wrote:
> On Thu, Apr 25, 2024, at 2:12 PM, Pali Rohár wrote:
> > On Thursday 25 April 2024 11:27:57 Lyndon Sanche wrote:
> >> +int thermal_init(void)
> >> +{
> >> +	int ret;
> >> +	int supported_modes;
> >> +
> >> +	ret = thermal_get_supported_modes(&supported_modes);
> >> +
> >> +	if (ret != 0 || supported_modes == 0)
> >> +		return -ENXIO;
> >> +
> >> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> >> +	if (!thermal_handler)
> >> +		return -ENOMEM;
> >> +	thermal_handler->profile_get = thermal_platform_profile_get;
> >> +	thermal_handler->profile_set = thermal_platform_profile_set;
> >> +
> >> +	if ((supported_modes >> DELL_QUIET) & 1)
> >> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> >> +	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
> >> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> >> +	if ((supported_modes >> DELL_BALANCED) & 1)
> >> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> >> +	if ((supported_modes >> DELL_PERFORMANCE) & 1)
> >> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> >> +
> >> +	platform_profile_register(thermal_handler);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +void thermal_cleanup(void)
> >> +{
> >> +	platform_profile_remove();
> >> +	kfree(thermal_handler);
> >> +}
> >> +
> >>  static struct led_classdev mute_led_cdev = {
> >>  	.name = "platform::mute",
> >>  	.max_brightness = 1,
> >> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
> >>  		mute_led_registered = true;
> >>  	}
> >>  
> >> +	// Do not fail module if thermal modes not supported,
> >> +	// just skip
> >> +	if (thermal_init() != 0)
> >> +		pr_warn("Unable to setup platform_profile, skipping");
> >
> > I think that -ENOMEM error should be failure of the loading the driver.
> > It does not make sense to continue of memory allocation failed.
> >
> > On the other hand when the thermal modes are not support (e.g. old
> > Latitude models) then there should not be a warning message. It is
> > expected that on systems without thermal modes the setup fails.
> 
> Thank you for your feedback.
> 
> I agree with your suggestion. -ENOMEM would indicate something bigger is amiss. I can add a check:
> 
> If -ENOMEM, fail driver.
> If anything other error, skip, but do not show a message.
> 
> Lyndon

Maybe you can simplify it more. thermal_init() could return 0 also for
the case when thermal modes are not supported. And dell_init() then can
unconditionally fail when thermal_init() returns non-zero value. It has
benefit that in case thermal_init() is extended in future for some other
fatal error, it would not be required to update also caller to handle
another error (and not just ENOMEM).

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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
  2024-04-25 20:07 ` Mario Limonciello
  2024-04-25 20:12 ` Pali Rohár
@ 2024-04-25 21:07 ` Armin Wolf
  2024-04-26  0:54   ` Lyndon Sanche
  2024-04-26  2:04 ` [PATCH v2] " Lyndon Sanche
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 72+ messages in thread
From: Armin Wolf @ 2024-04-25 21:07 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Am 25.04.24 um 19:27 schrieb Lyndon Sanche:

> Some Dell laptops support configuration of preset
> fan modes through smbios tables.
>
> If the platform supports these fan modes, set up
> platform_profile to change these modes. If not
> supported, skip enabling platform_profile.
>
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
>   drivers/platform/x86/dell/dell-laptop.c | 220 ++++++++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios.h |   1 +
>   2 files changed, 221 insertions(+)
>
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..7f9c4e0e5ef5 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,7 @@
>   #include <linux/i8042.h>
>   #include <linux/debugfs.h>
>   #include <linux/seq_file.h>
> +#include <linux/platform_profile.h>
>   #include <acpi/video.h>
>   #include "dell-rbtn.h"
>   #include "dell-smbios.h"
> @@ -95,10 +96,18 @@ static struct backlight_device *dell_backlight_device;
>   static struct rfkill *wifi_rfkill;
>   static struct rfkill *bluetooth_rfkill;
>   static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>   static bool force_rfkill;
>   static bool micmute_led_registered;
>   static bool mute_led_registered;
>
> +enum thermal_mode_bits {
> +	DELL_BALANCED = 0,
> +	DELL_COOL_BOTTOM = 1,
> +	DELL_QUIET = 2,
> +	DELL_PERFORMANCE = 3,
> +};
> +
>   module_param(force_rfkill, bool, 0444);
>   MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
>
> @@ -2199,6 +2208,211 @@ static int mute_led_set(struct led_classdev *led_cdev,
>   	return 0;
>   }
>
> +// Derived from smbios-thermal-ctl
> +//
> +// cbClass 17
> +// cbSelect 19
> +// User Selectable Thermal Tables(USTT)
> +// cbArg1 determines the function to be performed
> +// cbArg1 0x0 = Get Thermal Information
> +//  cbRES1         Standard return codes (0, -1, -2)
> +//  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if its bit is set to 1
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performance
> +//  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes. Each mode
> +//                 corresponds to the supported thermal modes in byte 0. A mode is supported if
> +//                 its bit is set to 1.
> +//     Bit 0 AAC (Balanced)
> +//     Bit 1 AAC (Cool Bottom
> +//     Bit 2 AAC (Quiet)
> +//     Bit 3 AAC (Performance)
> +//  cbRes3, byte 0 Current Thermal Mode
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performanc
> +//  cbRes3, byte 1  AAC Configuration type
> +//          0       Global (AAC enable/disable applies to all supported USTT modes)
> +//          1       USTT mode specific
> +//  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> +//     If AAC Configuration Type is Global,
> +//          0       AAC mode disabled
> +//          1       AAC mode enabled
> +//     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> +//          Bit 0 AAC (Balanced)
> +//          Bit 1 AAC (Cool Bottom
> +//          Bit 2 AAC (Quiet)
> +//          Bit 3 AAC (Performance)
> +//  cbRes3, byte 3  Current Fan Failure Mode
> +//     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> +//     Bit 1 Catastrophic Fan Failure (all fans have failed)
> +//  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> +//               desired AAC mode shall be applied
> +//  cbArg2, byte 0  Desired Thermal Mode to set (only one bit may be set for this parameter)
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performance
> +//  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> +//     If AAC Configuration Type is Global,
> +//         0  AAC mode disabled
> +//         1  AAC mode enabled
> +//
> +//     If AAC Configuration Type is USTT mode specific (multiple bits may be set for this parameter),

Hi,

checkpatch reports: WARNING: line length of 101 exceeds 100 columns

> +//         Bit 0 AAC (Balanced)
> +//         Bit 1 AAC (Cool Bottom
> +//         Bit 2 AAC (Quiet)
> +//         Bit 3 AAC (Performance)
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if ((state >> DELL_BALANCED) & 1)
> +		return DELL_BALANCED;
> +	else if ((state >> DELL_COOL_BOTTOM) & 1)
> +		return DELL_COOL_BOTTOM;
> +	else if ((state >> DELL_QUIET) & 1)
> +		return DELL_QUIET;
> +	else if ((state >> DELL_PERFORMANCE) & 1)
> +		return DELL_PERFORMANCE;
> +	else
> +		return 0;

This would return DELL_BALANCED if no option is set. Please return an appropriate error code.

> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = buffer.output[1] & 0xF;
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = ((buffer.output[3] >> 8) & 0xFF);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, (acc_mode << 8) | BIT(state), 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	int ret;
> +
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		ret = thermal_set_mode(DELL_BALANCED);
> +		break;

Maybe using "return thermal_set_mode()" would be better in this cases.

> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		ret = thermal_set_mode(DELL_PERFORMANCE);
> +		break;
> +	case PLATFORM_PROFILE_QUIET:
> +		ret = thermal_set_mode(DELL_QUIET);
> +		break;
> +	case PLATFORM_PROFILE_COOL:
> +		ret = thermal_set_mode(DELL_COOL_BOTTOM);
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	switch (thermal_get_mode()) {

Please check if thermal_get_mode() returned an error code and return it in this case.

> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	ret = thermal_get_supported_modes(&supported_modes);
> +
> +	if (ret != 0 || supported_modes == 0)
> +		return -ENXIO;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if ((supported_modes >> DELL_QUIET) & 1)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if ((supported_modes >> DELL_BALANCED) & 1)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if ((supported_modes >> DELL_PERFORMANCE) & 1)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	platform_profile_register(thermal_handler);
> +
> +	return 0;

Please check the return value of platform_profile_register() and return the error if this function fails,
see commit fe0e04cf66a1 ("platform/surface: platform_profile: Propagate error if profile registration fails")
for an explanation.

> +}
> +
> +void thermal_cleanup(void)
> +{
> +	platform_profile_remove();
> +	kfree(thermal_handler);
> +}
> +
>   static struct led_classdev mute_led_cdev = {
>   	.name = "platform::mute",
>   	.max_brightness = 1,
> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
>   		mute_led_registered = true;
>   	}
>
> +	// Do not fail module if thermal modes not supported,
> +	// just skip
> +	if (thermal_init() != 0)
> +		pr_warn("Unable to setup platform_profile, skipping");
> +
>   	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
>   		return 0;
>
> @@ -2344,6 +2563,7 @@ static void __exit dell_exit(void)
>   		platform_device_unregister(platform_device);
>   		platform_driver_unregister(&platform_driver);
>   	}
> +	thermal_cleanup();

Should only be called when thermal_init() was successful.

Thanks,
Armin Wolf

>   }
>
>   /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>   /* Classes and selects used only in kernel drivers */
>   #define CLASS_KBD_BACKLIGHT 4
>   #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>
>   /* Tokens used in kernel drivers, any of these
>    * should be filtered from userspace access

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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 20:28     ` Mario Limonciello
@ 2024-04-25 21:51       ` Srinivas Pandruvada
  2024-04-26  0:38         ` Lyndon Sanche
  0 siblings, 1 reply; 72+ messages in thread
From: Srinivas Pandruvada @ 2024-04-25 21:51 UTC (permalink / raw)
  To: Mario Limonciello, Lyndon Sanche
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel


On 4/25/24 13:28, Mario Limonciello wrote:
> On 4/25/2024 15:24, Lyndon Sanche wrote:
>> On Thu, Apr 25, 2024, at 2:07 PM, Mario Limonciello wrote:
>>> + Srinivas
>>>
>>> On 4/25/2024 12:27, Lyndon Sanche wrote:
>>>> Some Dell laptops support configuration of preset
>>>> fan modes through smbios tables.
>>>>
>>>> If the platform supports these fan modes, set up
>>>> platform_profile to change these modes. If not
>>>> supported, skip enabling platform_profile.
>>>>
>>>> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>>>> ---
>>>
>>> When you developed this was it using a Dell Intel or Dell AMD system?
>>>
>>> If it was an Intel system, did you test it with thermald installed and
>>> active?
>>>
>>> I'm wondering how all this stuff jives with the stuff that thermald
>>> does.  I don't know if they fight for any of the same "resources".
>>
>> Thank you for your response.
>>
>> I did my development and testing on a Dell Intel system. Specifically 
>> the XPS 15 9560 with i7-7700HQ.
>>
>> I do have thermald running, though I admit I am not really aware of 
>> what exactly it does, besides being related to thermals in some way.
>>
>> I normally set the thermal mode with Dell's smbios-thermal-ctl 
>> program. I am not too sure all the values that the bios configures on 
>> it's own depending on the provided mode, so I am not sure if thermald 
>> conflicts. But my understanding is that would be out of scope of this 
>> driver, since we are only telling the bios what we want at a high level.
>>
>> Lyndon
>
> Yeah it's not say it's a "new" conflict, it would just become a lot 
> more prevalent since software like GNOME and KDE use 
> power-profiles-daemon to manipulate the new power profile you're 
> exporting from the driver.
>
> If there really is no conflict, then great!
> If there is a conflict then I was just wondering if there needs to be 
> an easy way to turn on/off the profile support when thermald is in use.

This shouldn't be in conflict as this should be directly changing some 
settings in BIOS. BIOS should send some notification, if it wants some 
changes in thermal tables used by thermald.


Thanks,

Srinivas



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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 21:51       ` Srinivas Pandruvada
@ 2024-04-26  0:38         ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-26  0:38 UTC (permalink / raw)
  To: Srinivas Pandruvada
  Cc: Mario Limonciello, Matthew Garrett, Pali Rohár,
	Hans de Goede, Ilpo Järvinen, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On Thu, Apr 25 2024 at 02:51:42 PM -07:00:00, Srinivas Pandruvada 
<srinivas.pandruvada@linux.intel.com> wrote:
> 
> On 4/25/24 13:28, Mario Limonciello wrote:
>> Yeah it's not say it's a "new" conflict, it would just become a lot 
>> \x7fmore prevalent since software like GNOME and KDE use 
>> \x7fpower-profiles-daemon to manipulate the new power profile you're 
>> \x7fexporting from the driver.
>> 
>> If there really is no conflict, then great!
>> If there is a conflict then I was just wondering if there needs to 
>> be \x7fan easy way to turn on/off the profile support when thermald is 
>> in use.
> 
> This shouldn't be in conflict as this should be directly changing 
> some settings in BIOS. BIOS should send some notification, if it 
> wants some changes in thermal tables used by thermald.
> 
> 
> Thanks,
> 
> Srinivas
> 

If we do not think there is a conflict I can leave it without a toggle.

Lyndon




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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 21:07 ` Armin Wolf
@ 2024-04-26  0:54   ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-26  0:54 UTC (permalink / raw)
  To: Armin Wolf
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel



On Thu, Apr 25 2024 at 11:07:22 PM +02:00:00, Armin Wolf 
<W_Armin@gmx.de> wrote:
> Am 25.04.24 um 19:27 schrieb Lyndon Sanche:
>> 
>> +//         1  AAC mode enabled
>> +//
>> +//     If AAC Configuration Type is USTT mode specific (multiple 
>> bits may be set for this parameter),
> 
> Hi,
> 
> checkpatch reports: WARNING: line length of 101 exceeds 100 columns

I can wrap this last line.

> 
>> +//         Bit 0 AAC (Balanced)
>> +//         Bit 1 AAC (Cool Bottom
>> +//         Bit 2 AAC (Quiet)
>> +//         Bit 3 AAC (Performance)
>> +static int thermal_get_mode(void)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int state;
>> +	int ret;
>> +
>> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +	if (ret)
>> +		return ret;
>> +	state = buffer.output[2];
>> +	if ((state >> DELL_BALANCED) & 1)
>> +		return DELL_BALANCED;
>> +	else if ((state >> DELL_COOL_BOTTOM) & 1)
>> +		return DELL_COOL_BOTTOM;
>> +	else if ((state >> DELL_QUIET) & 1)
>> +		return DELL_QUIET;
>> +	else if ((state >> DELL_PERFORMANCE) & 1)
>> +		return DELL_PERFORMANCE;
>> +	else
>> +		return 0;
> 
> This would return DELL_BALANCED if no option is set. Please return an 
> appropriate error code.

Thanks for catching this, I will return a proper error code.

> 
>> +}
>> +
>> +static int thermal_get_supported_modes(int *supported_bits)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int ret;
>> +
>> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +	if (ret)
>> +		return ret;
>> +	*supported_bits = buffer.output[1] & 0xF;
>> +	return 0;
>> +}
>> +
>> +static int thermal_get_acc_mode(int *acc_mode)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int ret;
>> +
>> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +	if (ret)
>> +		return ret;
>> +	*acc_mode = ((buffer.output[3] >> 8) & 0xFF);
>> +	return 0;
>> +}
>> +
>> +static int thermal_set_mode(enum thermal_mode_bits state)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int ret;
>> +	int acc_mode;
>> +
>> +	ret = thermal_get_acc_mode(&acc_mode);
>> +	if (ret)
>> +		return ret;
>> +
>> +	dell_fill_request(&buffer, 0x1, (acc_mode << 8) | BIT(state), 0, 
>> 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +	return ret;
>> +}
>> +
>> +static int thermal_platform_profile_set(struct 
>> platform_profile_handler *pprof,
>> +					enum platform_profile_option profile)
>> +{
>> +	int ret;
>> +
>> +	switch (profile) {
>> +	case PLATFORM_PROFILE_BALANCED:
>> +		ret = thermal_set_mode(DELL_BALANCED);
>> +		break;
> 
> Maybe using "return thermal_set_mode()" would be better in this cases.

Good idea, I can clean up the code with this suggestion.

> 
>> +	case PLATFORM_PROFILE_PERFORMANCE:
>> +		ret = thermal_set_mode(DELL_PERFORMANCE);
>> +		break;
>> +	case PLATFORM_PROFILE_QUIET:
>> +		ret = thermal_set_mode(DELL_QUIET);
>> +		break;
>> +	case PLATFORM_PROFILE_COOL:
>> +		ret = thermal_set_mode(DELL_COOL_BOTTOM);
>> +		break;
>> +	default:
>> +		return -EOPNOTSUPP;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int thermal_platform_profile_get(struct 
>> platform_profile_handler *pprof,
>> +					enum platform_profile_option *profile)
>> +{
>> +	switch (thermal_get_mode()) {
> 
> Please check if thermal_get_mode() returned an error code and return 
> it in this case.

Will add error checking.

>> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
>> +
>> +	platform_profile_register(thermal_handler);
>> +
>> +	return 0;
> 
> Please check the return value of platform_profile_register() and 
> return the error if this function fails,
> see commit fe0e04cf66a1 ("platform/surface: platform_profile: 
> Propagate error if profile registration fails")
> for an explanation.

Thank you for catching this. I forgot to handle the return value.

> 
>> +}
>> +
>> +void thermal_cleanup(void)
>> +{
>> +	platform_profile_remove();
>> +	kfree(thermal_handler);
>> +}
>> +
>>   static struct led_classdev mute_led_cdev = {
>>   	.name = "platform::mute",
>>   	.max_brightness = 1,
>> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
>>   		mute_led_registered = true;
>>   	}
>> 
>> +	// Do not fail module if thermal modes not supported,
>> +	// just skip
>> +	if (thermal_init() != 0)
>> +		pr_warn("Unable to setup platform_profile, skipping");
>> +
>>   	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
>>   		return 0;
>> 
>> @@ -2344,6 +2563,7 @@ static void __exit dell_exit(void)
>>   		platform_device_unregister(platform_device);
>>   		platform_driver_unregister(&platform_driver);
>>   	}
>> +	thermal_cleanup();
> 
> Should only be called when thermal_init() was successful.

I do not believe it is incorrect to skip checking for this.

platform_profile_remove() does not return anything and does not panic 
when a profile is not currently registered. My understanding from 
reading the source is it handles the case of no profile gracefully. 
Please let me know if my understanding is incorrect however.

kfree does not care of the thermal handler is allocated or not. Please 
let me know if calling kfree on NULL pointers is poor form for this 
application.

Thank you for your feedback, I do appreciate it.

Lyndon



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

* [PATCH v2] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (2 preceding siblings ...)
  2024-04-25 21:07 ` Armin Wolf
@ 2024-04-26  2:04 ` Lyndon Sanche
  2024-04-26  9:23   ` Ilpo Järvinen
  2024-05-13 20:09   ` kernel test robot
  2024-04-26  6:57 ` [PATCH] " Ilpo Järvinen
                   ` (7 subsequent siblings)
  11 siblings, 2 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-26  2:04 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	Matthew Garrett, Hans de Goede, Ilpo Järvinen,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Some Dell laptops support configuration of preset
fan modes through smbios tables.

If the platform supports these fan modes, set up
platform_profile to change these modes. If not
supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 drivers/platform/x86/dell/dell-laptop.c | 223 ++++++++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios.h |   1 +
 2 files changed, 224 insertions(+)

diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..ff67bc7697b1 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -27,6 +27,7 @@
 #include <linux/i8042.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/platform_profile.h>
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
@@ -95,10 +96,18 @@ static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct platform_profile_handler *thermal_handler;
 static bool force_rfkill;
 static bool micmute_led_registered;
 static bool mute_led_registered;
 
+enum thermal_mode_bits {
+	DELL_BALANCED = 0,
+	DELL_COOL_BOTTOM = 1,
+	DELL_QUIET = 2,
+	DELL_PERFORMANCE = 3,
+};
+
 module_param(force_rfkill, bool, 0444);
 MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
 
@@ -2199,6 +2208,211 @@ static int mute_led_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
+// Derived from smbios-thermal-ctl
+//
+// cbClass 17
+// cbSelect 19
+// User Selectable Thermal Tables(USTT)
+// cbArg1 determines the function to be performed
+// cbArg1 0x0 = Get Thermal Information
+//  cbRES1         Standard return codes (0, -1, -2)
+//  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if its bit is set to 1
+//     Bit 0 Balanced
+//     Bit 1 Cool Bottom
+//     Bit 2 Quiet
+//     Bit 3 Performance
+//  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes. Each mode
+//                 corresponds to the supported thermal modes in byte 0. A mode is supported if
+//                 its bit is set to 1.
+//     Bit 0 AAC (Balanced)
+//     Bit 1 AAC (Cool Bottom
+//     Bit 2 AAC (Quiet)
+//     Bit 3 AAC (Performance)
+//  cbRes3, byte 0 Current Thermal Mode
+//     Bit 0 Balanced
+//     Bit 1 Cool Bottom
+//     Bit 2 Quiet
+//     Bit 3 Performanc
+//  cbRes3, byte 1  AAC Configuration type
+//          0       Global (AAC enable/disable applies to all supported USTT modes)
+//          1       USTT mode specific
+//  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+//     If AAC Configuration Type is Global,
+//          0       AAC mode disabled
+//          1       AAC mode enabled
+//     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+//          Bit 0 AAC (Balanced)
+//          Bit 1 AAC (Cool Bottom
+//          Bit 2 AAC (Quiet)
+//          Bit 3 AAC (Performance)
+//  cbRes3, byte 3  Current Fan Failure Mode
+//     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+//     Bit 1 Catastrophic Fan Failure (all fans have failed)
+//  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+//               desired AAC mode shall be applied
+//  cbArg2, byte 0  Desired Thermal Mode to set (only one bit may be set for this parameter)
+//     Bit 0 Balanced
+//     Bit 1 Cool Bottom
+//     Bit 2 Quiet
+//     Bit 3 Performance
+//  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+//     If AAC Configuration Type is Global,
+//         0  AAC mode disabled
+//         1  AAC mode enabled
+//
+//     If AAC Configuration Type is USTT mode specific
+//     (multiple bits may be set for this parameter),
+//         Bit 0 AAC (Balanced)
+//         Bit 1 AAC (Cool Bottom
+//         Bit 2 AAC (Quiet)
+//         Bit 3 AAC (Performance)
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if ((state >> DELL_BALANCED) & 1)
+		return DELL_BALANCED;
+	else if ((state >> DELL_COOL_BOTTOM) & 1)
+		return DELL_COOL_BOTTOM;
+	else if ((state >> DELL_QUIET) & 1)
+		return DELL_QUIET;
+	else if ((state >> DELL_PERFORMANCE) & 1)
+		return DELL_PERFORMANCE;
+	else
+		return -ENXIO;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*supported_bits = buffer.output[1] & 0xF;
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = ((buffer.output[3] >> 8) & 0xFF);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, (acc_mode << 8) | BIT(state), 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		return thermal_set_mode(DELL_BALANCED);
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return thermal_set_mode(DELL_PERFORMANCE);
+	case PLATFORM_PROFILE_QUIET:
+		return thermal_set_mode(DELL_QUIET);
+	case PLATFORM_PROFILE_COOL:
+		return thermal_set_mode(DELL_COOL_BOTTOM);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	int ret = thermal_get_mode();
+
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	ret = thermal_get_supported_modes(&supported_modes);
+
+	if (ret || !supported_modes)
+		return 0;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if ((supported_modes >> DELL_QUIET) & 1)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if ((supported_modes >> DELL_BALANCED) & 1)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if ((supported_modes >> DELL_PERFORMANCE) & 1)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	// Clean up but do not fail
+	if (platform_profile_register(thermal_handler))
+		kfree(thermal_handler);
+
+	return 0;
+}
+
+void thermal_cleanup(void)
+{
+	platform_profile_remove();
+	kfree(thermal_handler);
+}
+
 static struct led_classdev mute_led_cdev = {
 	.name = "platform::mute",
 	.max_brightness = 1,
@@ -2238,6 +2452,12 @@ static int __init dell_init(void)
 		goto fail_rfkill;
 	}
 
+	// Do not fail module if thermal modes not supported,
+	// just skip
+	ret = thermal_init();
+	if (ret)
+		goto fail_thermal;
+
 	if (quirks && quirks->touchpad_led)
 		touchpad_led_init(&platform_device->dev);
 
@@ -2317,6 +2537,8 @@ static int __init dell_init(void)
 		led_classdev_unregister(&mute_led_cdev);
 fail_led:
 	dell_cleanup_rfkill();
+fail_thermal:
+	thermal_cleanup();
 fail_rfkill:
 	platform_device_del(platform_device);
 fail_platform_device2:
@@ -2344,6 +2566,7 @@ static void __exit dell_exit(void)
 		platform_device_unregister(platform_device);
 		platform_driver_unregister(&platform_driver);
 	}
+	thermal_cleanup();
 }
 
 /* dell-rbtn.c driver export functions which will not work correctly (and could
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..585d042f1779 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (3 preceding siblings ...)
  2024-04-26  2:04 ` [PATCH v2] " Lyndon Sanche
@ 2024-04-26  6:57 ` Ilpo Järvinen
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 72+ messages in thread
From: Ilpo Järvinen @ 2024-04-26  6:57 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	platform-driver-x86, LKML, Dell.Client.Kernel

On Thu, 25 Apr 2024, Lyndon Sanche wrote:

> Some Dell laptops support configuration of preset
> fan modes through smbios tables.
> 
> If the platform supports these fan modes, set up
> platform_profile to change these modes. If not
> supported, skip enabling platform_profile.

These are too short lines, wrap at 72 (or 75) characters.

> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
>  drivers/platform/x86/dell/dell-laptop.c | 220 ++++++++++++++++++++++++
>  drivers/platform/x86/dell/dell-smbios.h |   1 +
>  2 files changed, 221 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..7f9c4e0e5ef5 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,7 @@
>  #include <linux/i8042.h>
>  #include <linux/debugfs.h>
>  #include <linux/seq_file.h>
> +#include <linux/platform_profile.h>
>  #include <acpi/video.h>
>  #include "dell-rbtn.h"
>  #include "dell-smbios.h"
> @@ -95,10 +96,18 @@ static struct backlight_device *dell_backlight_device;
>  static struct rfkill *wifi_rfkill;
>  static struct rfkill *bluetooth_rfkill;
>  static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>  static bool force_rfkill;
>  static bool micmute_led_registered;
>  static bool mute_led_registered;
>  
> +enum thermal_mode_bits {
> +	DELL_BALANCED = 0,
> +	DELL_COOL_BOTTOM = 1,
> +	DELL_QUIET = 2,
> +	DELL_PERFORMANCE = 3,
> +};

It would seem more more natural to define these with BIT(x) as that's how 
they're used in the code below?

>  module_param(force_rfkill, bool, 0444);
>  MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
>  
> @@ -2199,6 +2208,211 @@ static int mute_led_set(struct led_classdev *led_cdev,
>  	return 0;
>  }
>  
> +// Derived from smbios-thermal-ctl
> +//
> +// cbClass 17
> +// cbSelect 19
> +// User Selectable Thermal Tables(USTT)
> +// cbArg1 determines the function to be performed
> +// cbArg1 0x0 = Get Thermal Information
> +//  cbRES1         Standard return codes (0, -1, -2)
> +//  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if its bit is set to 1
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performance
> +//  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes. Each mode
> +//                 corresponds to the supported thermal modes in byte 0. A mode is supported if
> +//                 its bit is set to 1.
> +//     Bit 0 AAC (Balanced)
> +//     Bit 1 AAC (Cool Bottom
> +//     Bit 2 AAC (Quiet)
> +//     Bit 3 AAC (Performance)
> +//  cbRes3, byte 0 Current Thermal Mode
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performanc
> +//  cbRes3, byte 1  AAC Configuration type
> +//          0       Global (AAC enable/disable applies to all supported USTT modes)
> +//          1       USTT mode specific
> +//  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> +//     If AAC Configuration Type is Global,
> +//          0       AAC mode disabled
> +//          1       AAC mode enabled
> +//     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> +//          Bit 0 AAC (Balanced)
> +//          Bit 1 AAC (Cool Bottom
> +//          Bit 2 AAC (Quiet)
> +//          Bit 3 AAC (Performance)
> +//  cbRes3, byte 3  Current Fan Failure Mode
> +//     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> +//     Bit 1 Catastrophic Fan Failure (all fans have failed)
> +//  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> +//               desired AAC mode shall be applied
> +//  cbArg2, byte 0  Desired Thermal Mode to set (only one bit may be set for this parameter)
> +//     Bit 0 Balanced
> +//     Bit 1 Cool Bottom
> +//     Bit 2 Quiet
> +//     Bit 3 Performance
> +//  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> +//     If AAC Configuration Type is Global,
> +//         0  AAC mode disabled
> +//         1  AAC mode enabled
> +//
> +//     If AAC Configuration Type is USTT mode specific (multiple bits may be set for this parameter),
> +//         Bit 0 AAC (Balanced)
> +//         Bit 1 AAC (Cool Bottom
> +//         Bit 2 AAC (Quiet)
> +//         Bit 3 AAC (Performance)

Please use

/*
 *
 */

format for multiline comments.

Don't exceed 80 characters with comments.

> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if ((state >> DELL_BALANCED) & 1)
> +		return DELL_BALANCED;
> +	else if ((state >> DELL_COOL_BOTTOM) & 1)
> +		return DELL_COOL_BOTTOM;
> +	else if ((state >> DELL_QUIET) & 1)
> +		return DELL_QUIET;
> +	else if ((state >> DELL_PERFORMANCE) & 1)
> +		return DELL_PERFORMANCE;

When you convert defines to use BIT(), these become simpler.

> +	else
> +		return 0;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = buffer.output[1] & 0xF;

Add named define + use FIELD_GET() + add #include <linux/bitfield.h> if 
not there already.

> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = ((buffer.output[3] >> 8) & 0xFF);

Use named define + FIELD_GET()

> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, (acc_mode << 8) | BIT(state), 0, 0);

Named define + FIELD_PREP(XX, acc_mode)

After converting the enum values to use BIT(), you can remove BIT() from 
here.

> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	int ret;
> +
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		ret = thermal_set_mode(DELL_BALANCED);
> +		break;
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		ret = thermal_set_mode(DELL_PERFORMANCE);
> +		break;
> +	case PLATFORM_PROFILE_QUIET:
> +		ret = thermal_set_mode(DELL_QUIET);
> +		break;
> +	case PLATFORM_PROFILE_COOL:
> +		ret = thermal_set_mode(DELL_COOL_BOTTOM);
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	switch (thermal_get_mode()) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	ret = thermal_get_supported_modes(&supported_modes);
> +
> +	if (ret != 0 || supported_modes == 0)

Don't leave empty lines between call and its error handling.

> +		return -ENXIO;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if ((supported_modes >> DELL_QUIET) & 1)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if ((supported_modes >> DELL_BALANCED) & 1)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if ((supported_modes >> DELL_PERFORMANCE) & 1)

These too will get simpler when the values are using BIT().

> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	platform_profile_register(thermal_handler);
> +
> +	return 0;
> +}
> +
> +void thermal_cleanup(void)
> +{
> +	platform_profile_remove();

This should be called if thermal_init() failed, sysfs_remove_group() will 
be called for a group that was never created and I don't think that's 
okay.

> +	kfree(thermal_handler);
> +}
> +
>  static struct led_classdev mute_led_cdev = {
>  	.name = "platform::mute",
>  	.max_brightness = 1,
> @@ -2266,6 +2480,11 @@ static int __init dell_init(void)
>  		mute_led_registered = true;
>  	}
>  
> +	// Do not fail module if thermal modes not supported,
> +	// just skip

Fits to one line.

> +	if (thermal_init() != 0)
> +		pr_warn("Unable to setup platform_profile, skipping");
> +
>  	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
>  		return 0;
>  
> @@ -2344,6 +2563,7 @@ static void __exit dell_exit(void)
>  		platform_device_unregister(platform_device);
>  		platform_driver_unregister(&platform_driver);
>  	}
> +	thermal_cleanup();
>  }
>  
>  /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>  /* Classes and selects used only in kernel drivers */
>  #define CLASS_KBD_BACKLIGHT 4
>  #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>  
>  /* Tokens used in kernel drivers, any of these
>   * should be filtered from userspace access
> 

-- 
 i.


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

* Re: [PATCH v2] platform/x86: dell-laptop: Implement platform_profile
  2024-04-26  2:04 ` [PATCH v2] " Lyndon Sanche
@ 2024-04-26  9:23   ` Ilpo Järvinen
  2024-04-26 18:05     ` Lyndon Sanche
  2024-05-13 20:09   ` kernel test robot
  1 sibling, 1 reply; 72+ messages in thread
From: Ilpo Järvinen @ 2024-04-26  9:23 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	Matthew Garrett, Hans de Goede, platform-driver-x86, LKML,
	Dell.Client.Kernel

On Thu, 25 Apr 2024, Lyndon Sanche wrote:

> Some Dell laptops support configuration of preset
> fan modes through smbios tables.
> 
> If the platform supports these fan modes, set up
> platform_profile to change these modes. If not
> supported, skip enabling platform_profile.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---

Two things:
- You're missing patch version history (put it below the --- line)
- Don't send updates so soon, give people time to comment. When I saw v1 
  for the first time, you had already posted the next version.

> +void thermal_cleanup(void)
> +{
> +	platform_profile_remove();
> +	kfree(thermal_handler);
> +}
> +
>  static struct led_classdev mute_led_cdev = {
>  	.name = "platform::mute",
>  	.max_brightness = 1,
> @@ -2238,6 +2452,12 @@ static int __init dell_init(void)
>  		goto fail_rfkill;
>  	}
>  
> +	// Do not fail module if thermal modes not supported,
> +	// just skip
> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>  	if (quirks && quirks->touchpad_led)
>  		touchpad_led_init(&platform_device->dev);
>  
> @@ -2317,6 +2537,8 @@ static int __init dell_init(void)
>  		led_classdev_unregister(&mute_led_cdev);
>  fail_led:
>  	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>  fail_rfkill:
>  	platform_device_del(platform_device);
>  fail_platform_device2:
> @@ -2344,6 +2566,7 @@ static void __exit dell_exit(void)
>  		platform_device_unregister(platform_device);
>  		platform_driver_unregister(&platform_driver);
>  	}
> +	thermal_cleanup();

This is still not right, you'll still platform_profile_remove() even if 
the init side call failed.

-- 
 i.


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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 20:24   ` Lyndon Sanche
  2024-04-25 20:28     ` Mario Limonciello
@ 2024-04-26 16:14     ` srinivas pandruvada
  2024-04-26 18:23       ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: srinivas pandruvada @ 2024-04-26 16:14 UTC (permalink / raw)
  To: Lyndon Sanche, Mario Limonciello
  Cc: Matthew Garrett, Pali Rohár, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

On Thu, 2024-04-25 at 14:24 -0600, Lyndon Sanche wrote:
> On Thu, Apr 25, 2024, at 2:07 PM, Mario Limonciello wrote:
> > + Srinivas
> > 
> > On 4/25/2024 12:27, Lyndon Sanche wrote:
> > > Some Dell laptops support configuration of preset
> > > fan modes through smbios tables.
> > > 
> > > If the platform supports these fan modes, set up
> > > platform_profile to change these modes. If not
> > > supported, skip enabling platform_profile.
> > > 
> > > Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> > > ---
> > 
> > When you developed this was it using a Dell Intel or Dell AMD
> > system?
> > 
> > If it was an Intel system, did you test it with thermald installed
> > and 
> > active?
> > 
> > I'm wondering how all this stuff jives with the stuff that thermald
> > does.  I don't know if they fight for any of the same "resources".
> 
> Thank you for your response.
> 
> I did my development and testing on a Dell Intel system. Specifically
> the XPS 15 9560 with i7-7700HQ.
> 
> I do have thermald running, though I admit I am not really aware of
> what exactly it does, besides being related to thermals in some way.
> 
> I normally set the thermal mode with Dell's smbios-thermal-ctl
> program. I am not too sure all the values that the bios configures on
> it's own depending on the provided mode, so I am not sure if thermald
> conflicts. But my understanding is that would be out of scope of this
> driver, since we are only telling the bios what we want at a high
> level.
> 
> Lyndon
Can you share output of acpidump tool to me? I want to make sure if
there is some way the platform will bypass thermal table if you changed
to some profile.

Thanks,
Srinivas

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

* Re: [PATCH v2] platform/x86: dell-laptop: Implement platform_profile
  2024-04-26  9:23   ` Ilpo Järvinen
@ 2024-04-26 18:05     ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-26 18:05 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	Matthew Garrett, Hans de Goede, platform-driver-x86, LKML,
	Dell.Client.Kernel



On Fri, Apr 26 2024 at 12:23:00 PM +03:00:00, Ilpo Järvinen 
<ilpo.jarvinen@linux.intel.com> wrote:
> On Thu, 25 Apr 2024, Lyndon Sanche wrote:
> 
>>  Some Dell laptops support configuration of preset
>>  fan modes through smbios tables.
>> 
>>  If the platform supports these fan modes, set up
>>  platform_profile to change these modes. If not
>>  supported, skip enabling platform_profile.
>> 
>>  Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>>  ---
> 
> Two things:
> - You're missing patch version history (put it below the --- line)
> - Don't send updates so soon, give people time to comment. When I saw 
> v1
>   for the first time, you had already posted the next version.
> 
>>  +void thermal_cleanup(void)
>>  +{
>>  +	platform_profile_remove();
>>  +	kfree(thermal_handler);
>>  +}
>>  +
>>   static struct led_classdev mute_led_cdev = {
>>   	.name = "platform::mute",
>>   	.max_brightness = 1,
>>  @@ -2238,6 +2452,12 @@ static int __init dell_init(void)
>>   		goto fail_rfkill;
>>   	}
>> 
>>  +	// Do not fail module if thermal modes not supported,
>>  +	// just skip
>>  +	ret = thermal_init();
>>  +	if (ret)
>>  +		goto fail_thermal;
>>  +
>>   	if (quirks && quirks->touchpad_led)
>>   		touchpad_led_init(&platform_device->dev);
>> 
>>  @@ -2317,6 +2537,8 @@ static int __init dell_init(void)
>>   		led_classdev_unregister(&mute_led_cdev);
>>   fail_led:
>>   	dell_cleanup_rfkill();
>>  +fail_thermal:
>>  +	thermal_cleanup();
>>   fail_rfkill:
>>   	platform_device_del(platform_device);
>>   fail_platform_device2:
>>  @@ -2344,6 +2566,7 @@ static void __exit dell_exit(void)
>>   		platform_device_unregister(platform_device);
>>   		platform_driver_unregister(&platform_driver);
>>   	}
>>  +	thermal_cleanup();
> 
> This is still not right, you'll still platform_profile_remove() even 
> if
> the init side call failed.
> 
> --
>  i.
> 

Thank you for your feedback. I agree with your comments and will add 
more checking on whether certain cleanup actions are necessary.

Lyndon



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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-26 16:14     ` srinivas pandruvada
@ 2024-04-26 18:23       ` Lyndon Sanche
  2024-04-26 18:24         ` srinivas pandruvada
  0 siblings, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-26 18:23 UTC (permalink / raw)
  To: srinivas pandruvada
  Cc: Mario Limonciello, Matthew Garrett, Pali Rohár,
	Hans de Goede, Ilpo Järvinen, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On Fri, Apr 26 2024 at 09:14:07 AM -07:00:00, srinivas pandruvada 
<srinivas.pandruvada@linux.intel.com> wrote:
>> Can you share output of acpidump tool to me? I want to make sure if
> there is some way the platform will bypass thermal table if you 
> changed
> to some profile.
> 
> Thanks,
> Srinivas

Hello Srinivas:

I used acpidump. For sake of completeness I ran acpidump with each of 
the thermal modes enabled. The files are too large to provide here so I 
uploaded them to a public gist:
https://gist.github.com/Lyndeno/65ade5a15f1f2cd07175256dc021f551

Please let me know if there is a more appropriate medium for sharing 
files like this, and I will remember for next time.

Thank you,

Lyndon



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

* Re: [PATCH] platform/x86: dell-laptop: Implement platform_profile
  2024-04-26 18:23       ` Lyndon Sanche
@ 2024-04-26 18:24         ` srinivas pandruvada
  0 siblings, 0 replies; 72+ messages in thread
From: srinivas pandruvada @ 2024-04-26 18:24 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Mario Limonciello, Matthew Garrett, Pali Rohár,
	Hans de Goede, Ilpo Järvinen, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel

On Fri, 2024-04-26 at 12:23 -0600, Lyndon Sanche wrote:
> 
> 
> On Fri, Apr 26 2024 at 09:14:07 AM -07:00:00, srinivas pandruvada 
> <srinivas.pandruvada@linux.intel.com> wrote:
> > > Can you share output of acpidump tool to me? I want to make sure
> > > if
> > there is some way the platform will bypass thermal table if you 
> > changed
> > to some profile.
> > 
> > Thanks,
> > Srinivas
> 
> Hello Srinivas:
> 
> I used acpidump. For sake of completeness I ran acpidump with each of
> the thermal modes enabled. The files are too large to provide here so
> I 
> uploaded them to a public gist:
> https://gist.github.com/Lyndeno/65ade5a15f1f2cd07175256dc021f551
> 
> Please let me know if there is a more appropriate medium for sharing 
> files like this, and I will remember for next time.

This is fine. Thanks for uploading.

-Srinivas

> 
> Thank you,
> 
> Lyndon
> 
> 


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

* [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (4 preceding siblings ...)
  2024-04-26  6:57 ` [PATCH] " Ilpo Järvinen
@ 2024-04-29 16:48 ` Lyndon Sanche
  2024-04-29 17:45   ` Mario Limonciello
                     ` (5 more replies)
  2024-05-01  1:14 ` [PATCH v4] " Lyndon Sanche
                   ` (5 subsequent siblings)
  11 siblings, 6 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-29 16:48 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, Matthew Garrett, Hans de Goede,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Some Dell laptops support configuration of preset fan modes through
smbios tables.

If the platform supports these fan modes, set up platform_profile to
change these modes. If not supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
v3:
 - Convert smbios-thermal-ctl docs to multiline comment and wrap
 - Change thermal_mode_bits enum to directly be BIT() values
  - Convert related code to use this
 - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
  - Correct offset for getting current ACC mode, setting offset
		unchanged
 - Check if thermal_handler is allocated before freeing and
	 unregistering platform_profile
v2:
 - Wrap smbios-thermal-ctl comment
 - Return proper error code when invalid state returned
 - Simplify platform_profile_get returns
 - Propogate ENOMEM error
---
 drivers/platform/x86/dell/dell-laptop.c | 232 ++++++++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios.h |   1 +
 2 files changed, 233 insertions(+)

diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..fa58e7751d06 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -27,6 +27,8 @@
 #include <linux/i8042.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/platform_profile.h>
+#include <linux/bitfield.h>
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
@@ -95,6 +97,7 @@ static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct platform_profile_handler *thermal_handler;
 static bool force_rfkill;
 static bool micmute_led_registered;
 static bool mute_led_registered;
@@ -2199,6 +2202,227 @@ static int mute_led_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
+/* Derived from smbios-thermal-ctl
+ *
+ * cbClass 17
+ * cbSelect 19
+ * User Selectable Thermal Tables(USTT)
+ * cbArg1 determines the function to be performed
+ * cbArg1 0x0 = Get Thermal Information
+ *  cbRES1         Standard return codes (0, -1, -2)
+ *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
+ *                  its bit is set to 1
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
+ *                 Each mode corresponds to the supported thermal modes in
+ *                  byte 0. A mode is supported if its bit is set to 1.
+ *     Bit 0 AAC (Balanced)
+ *     Bit 1 AAC (Cool Bottom
+ *     Bit 2 AAC (Quiet)
+ *     Bit 3 AAC (Performance)
+ *  cbRes3, byte 0 Current Thermal Mode
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performanc
+ *  cbRes3, byte 1  AAC Configuration type
+ *          0       Global (AAC enable/disable applies to all supported USTT modes)
+ *          1       USTT mode specific
+ *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+ *     If AAC Configuration Type is Global,
+ *          0       AAC mode disabled
+ *          1       AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+ *          Bit 0 AAC (Balanced)
+ *          Bit 1 AAC (Cool Bottom
+ *          Bit 2 AAC (Quiet)
+ *          Bit 3 AAC (Performance)
+ *  cbRes3, byte 3  Current Fan Failure Mode
+ *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+ *     Bit 1 Catastrophic Fan Failure (all fans have failed)
+ *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+ *               desired AAC mode shall be applied
+ *  cbArg2, byte 0  Desired Thermal Mode to set
+ *                  (only one bit may be set for this parameter)
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+ *     If AAC Configuration Type is Global,
+ *         0  AAC mode disabled
+ *         1  AAC mode enabled
+ *
+ *     If AAC Configuration Type is USTT mode specific
+ *     (multiple bits may be set for this parameter),
+ *         Bit 0 AAC (Balanced)
+ *         Bit 1 AAC (Cool Bottom
+ *         Bit 2 AAC (Quiet)
+ *         Bit 3 AAC (Performance)
+ */
+
+#define DELL_ACC_GET_FIELD GENMASK(19, 16)
+#define DELL_ACC_SET_FIELD GENMASK(11, 8)
+#define DELL_THERMAL_SUPPORTED GENMASK(3, 0)
+
+enum thermal_mode_bits {
+	DELL_BALANCED = BIT(0),
+	DELL_COOL_BOTTOM = BIT(1),
+	DELL_QUIET = BIT(2),
+	DELL_PERFORMANCE = BIT(3),
+};
+
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if (state & DELL_BALANCED)
+		return DELL_BALANCED;
+	else if (state & DELL_COOL_BOTTOM)
+		return DELL_COOL_BOTTOM;
+	else if (state & DELL_QUIET)
+		return DELL_QUIET;
+	else if (state & DELL_PERFORMANCE)
+		return DELL_PERFORMANCE;
+	else
+		return -ENXIO;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		return thermal_set_mode(DELL_BALANCED);
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return thermal_set_mode(DELL_PERFORMANCE);
+	case PLATFORM_PROFILE_QUIET:
+		return thermal_set_mode(DELL_QUIET);
+	case PLATFORM_PROFILE_COOL:
+		return thermal_set_mode(DELL_COOL_BOTTOM);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	int ret = thermal_get_mode();
+
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	ret = thermal_get_supported_modes(&supported_modes);
+	if (ret || !supported_modes)
+		return 0;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if (supported_modes & DELL_QUIET)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if (supported_modes & DELL_COOL_BOTTOM)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if (supported_modes & DELL_BALANCED)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if (supported_modes & DELL_PERFORMANCE)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	// Clean up but do not fail
+	if (platform_profile_register(thermal_handler))
+		kfree(thermal_handler);
+
+	return 0;
+}
+
+void thermal_cleanup(void)
+{
+	if (thermal_handler) {
+		platform_profile_remove();
+		kfree(thermal_handler);
+	}
+}
+
 static struct led_classdev mute_led_cdev = {
 	.name = "platform::mute",
 	.max_brightness = 1,
@@ -2238,6 +2462,11 @@ static int __init dell_init(void)
 		goto fail_rfkill;
 	}
 
+	// Do not fail module if thermal modes not supported, just skip
+	ret = thermal_init();
+	if (ret)
+		goto fail_thermal;
+
 	if (quirks && quirks->touchpad_led)
 		touchpad_led_init(&platform_device->dev);
 
@@ -2317,6 +2546,8 @@ static int __init dell_init(void)
 		led_classdev_unregister(&mute_led_cdev);
 fail_led:
 	dell_cleanup_rfkill();
+fail_thermal:
+	thermal_cleanup();
 fail_rfkill:
 	platform_device_del(platform_device);
 fail_platform_device2:
@@ -2344,6 +2575,7 @@ static void __exit dell_exit(void)
 		platform_device_unregister(platform_device);
 		platform_driver_unregister(&platform_driver);
 	}
+	thermal_cleanup();
 }
 
 /* dell-rbtn.c driver export functions which will not work correctly (and could
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..585d042f1779 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
@ 2024-04-29 17:45   ` Mario Limonciello
  2024-04-29 17:51     ` Mario Limonciello
  2024-04-29 21:21     ` Lyndon Sanche
  2024-04-30 10:31   ` Ilpo Järvinen
                     ` (4 subsequent siblings)
  5 siblings, 2 replies; 72+ messages in thread
From: Mario Limonciello @ 2024-04-29 17:45 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen,
	Matthew Garrett, Hans de Goede, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel

On 4/29/2024 11:48, Lyndon Sanche wrote:
> Some Dell laptops support configuration of preset fan modes through
> smbios tables.
> 
> If the platform supports these fan modes, set up platform_profile to
> change these modes. If not supported, skip enabling platform_profile.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
> v3:
>   - Convert smbios-thermal-ctl docs to multiline comment and wrap
>   - Change thermal_mode_bits enum to directly be BIT() values
>    - Convert related code to use this
>   - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
>    - Correct offset for getting current ACC mode, setting offset
> 		unchanged
>   - Check if thermal_handler is allocated before freeing and
> 	 unregistering platform_profile
> v2:
>   - Wrap smbios-thermal-ctl comment
>   - Return proper error code when invalid state returned
>   - Simplify platform_profile_get returns
>   - Propogate ENOMEM error
> ---
>   drivers/platform/x86/dell/dell-laptop.c | 232 ++++++++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios.h |   1 +
>   2 files changed, 233 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..fa58e7751d06 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,8 @@
>   #include <linux/i8042.h>
>   #include <linux/debugfs.h>
>   #include <linux/seq_file.h>
> +#include <linux/platform_profile.h>
> +#include <linux/bitfield.h>

These should be inserted in alphabetical order.

>   #include <acpi/video.h>
>   #include "dell-rbtn.h"
>   #include "dell-smbios.h"
> @@ -95,6 +97,7 @@ static struct backlight_device *dell_backlight_device;
>   static struct rfkill *wifi_rfkill;
>   static struct rfkill *bluetooth_rfkill;
>   static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>   static bool force_rfkill;
>   static bool micmute_led_registered;
>   static bool mute_led_registered;
> @@ -2199,6 +2202,227 @@ static int mute_led_set(struct led_classdev *led_cdev,
>   	return 0;
>   }
>   
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> + *               desired AAC mode shall be applied
> + *  cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *
> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED GENMASK(3, 0)
> +
> +enum thermal_mode_bits {
> +	DELL_BALANCED = BIT(0),
> +	DELL_COOL_BOTTOM = BIT(1),
> +	DELL_QUIET = BIT(2),
> +	DELL_PERFORMANCE = BIT(3),
> +};
> +
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if (state & DELL_BALANCED)
> +		return DELL_BALANCED;
> +	else if (state & DELL_COOL_BOTTOM)
> +		return DELL_COOL_BOTTOM;
> +	else if (state & DELL_QUIET)
> +		return DELL_QUIET;
> +	else if (state & DELL_PERFORMANCE)
> +		return DELL_PERFORMANCE;
> +	else
> +		return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		return thermal_set_mode(DELL_BALANCED);
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return thermal_set_mode(DELL_PERFORMANCE);
> +	case PLATFORM_PROFILE_QUIET:
> +		return thermal_set_mode(DELL_QUIET);
> +	case PLATFORM_PROFILE_COOL:
> +		return thermal_set_mode(DELL_COOL_BOTTOM);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	int ret = thermal_get_mode();
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (ret) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	ret = thermal_get_supported_modes(&supported_modes);
> +	if (ret || !supported_modes)
> +		return 0;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if (supported_modes & DELL_QUIET)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if (supported_modes & DELL_COOL_BOTTOM)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if (supported_modes & DELL_BALANCED)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if (supported_modes & DELL_PERFORMANCE)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	// Clean up but do not fail

Switch comment style to /* */

> +	if (platform_profile_register(thermal_handler))
> +		kfree(thermal_handler);

Don't you also want to return an error in this case?  Because this means 
that the platform supports thermal modes but it failed to setup due to 
other issues.

It's different than the case of no supported modes in which case 
returning 0 makes sense.

Maybe like this:


ret = platform_profile_register(thermal_handler);
if (ret)
	kfree(thermal_handler);

return ret;


> +
> +	return 0;
> +}
> +
> +void thermal_cleanup(void)
> +{
> +	if (thermal_handler) {
> +		platform_profile_remove();
> +		kfree(thermal_handler);
> +	}
> +}
> +
>   static struct led_classdev mute_led_cdev = {
>   	.name = "platform::mute",
>   	.max_brightness = 1,
> @@ -2238,6 +2462,11 @@ static int __init dell_init(void)
>   		goto fail_rfkill;
>   	}
>   
> +	// Do not fail module if thermal modes not supported, just skip

Switch comment style to /* */

> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>   	if (quirks && quirks->touchpad_led)
>   		touchpad_led_init(&platform_device->dev);
>   
> @@ -2317,6 +2546,8 @@ static int __init dell_init(void)
>   		led_classdev_unregister(&mute_led_cdev);
>   fail_led:
>   	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>   fail_rfkill:
>   	platform_device_del(platform_device);
>   fail_platform_device2:
> @@ -2344,6 +2575,7 @@ static void __exit dell_exit(void)
>   		platform_device_unregister(platform_device);
>   		platform_driver_unregister(&platform_driver);
>   	}
> +	thermal_cleanup();
>   }
>   
>   /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>   /* Classes and selects used only in kernel drivers */
>   #define CLASS_KBD_BACKLIGHT 4
>   #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>   
>   /* Tokens used in kernel drivers, any of these
>    * should be filtered from userspace access


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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 17:45   ` Mario Limonciello
@ 2024-04-29 17:51     ` Mario Limonciello
  2024-04-29 21:25       ` Lyndon Sanche
  2024-04-29 21:21     ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: Mario Limonciello @ 2024-04-29 17:51 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen,
	Matthew Garrett, Hans de Goede, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel

On 4/29/2024 12:45, Mario Limonciello wrote:
> On 4/29/2024 11:48, Lyndon Sanche wrote:
>> Some Dell laptops support configuration of preset fan modes through
>> smbios tables.
>>
>> If the platform supports these fan modes, set up platform_profile to
>> change these modes. If not supported, skip enabling platform_profile.
>>
>> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>> ---
>> v3:
>>   - Convert smbios-thermal-ctl docs to multiline comment and wrap
>>   - Change thermal_mode_bits enum to directly be BIT() values
>>    - Convert related code to use this
>>   - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
>>    - Correct offset for getting current ACC mode, setting offset
>>         unchanged
>>   - Check if thermal_handler is allocated before freeing and
>>      unregistering platform_profile
>> v2:
>>   - Wrap smbios-thermal-ctl comment
>>   - Return proper error code when invalid state returned
>>   - Simplify platform_profile_get returns
>>   - Propogate ENOMEM error
>> ---
>>   drivers/platform/x86/dell/dell-laptop.c | 232 ++++++++++++++++++++++++
>>   drivers/platform/x86/dell/dell-smbios.h |   1 +
>>   2 files changed, 233 insertions(+)
>>
>> diff --git a/drivers/platform/x86/dell/dell-laptop.c 
>> b/drivers/platform/x86/dell/dell-laptop.c
>> index 42f7de2b4522..fa58e7751d06 100644
>> --- a/drivers/platform/x86/dell/dell-laptop.c
>> +++ b/drivers/platform/x86/dell/dell-laptop.c
>> @@ -27,6 +27,8 @@
>>   #include <linux/i8042.h>
>>   #include <linux/debugfs.h>
>>   #include <linux/seq_file.h>
>> +#include <linux/platform_profile.h>
>> +#include <linux/bitfield.h>
> 
> These should be inserted in alphabetical order.
> 
>>   #include <acpi/video.h>
>>   #include "dell-rbtn.h"
>>   #include "dell-smbios.h"
>> @@ -95,6 +97,7 @@ static struct backlight_device *dell_backlight_device;
>>   static struct rfkill *wifi_rfkill;
>>   static struct rfkill *bluetooth_rfkill;
>>   static struct rfkill *wwan_rfkill;
>> +static struct platform_profile_handler *thermal_handler;
>>   static bool force_rfkill;
>>   static bool micmute_led_registered;
>>   static bool mute_led_registered;
>> @@ -2199,6 +2202,227 @@ static int mute_led_set(struct led_classdev 
>> *led_cdev,
>>       return 0;
>>   }
>> +/* Derived from smbios-thermal-ctl
>> + *
>> + * cbClass 17
>> + * cbSelect 19
>> + * User Selectable Thermal Tables(USTT)
>> + * cbArg1 determines the function to be performed
>> + * cbArg1 0x0 = Get Thermal Information
>> + *  cbRES1         Standard return codes (0, -1, -2)
>> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is 
>> supported if
>> + *                  its bit is set to 1
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performance
>> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller 
>> (AAC) modes.
>> + *                 Each mode corresponds to the supported thermal 
>> modes in
>> + *                  byte 0. A mode is supported if its bit is set to 1.
>> + *     Bit 0 AAC (Balanced)
>> + *     Bit 1 AAC (Cool Bottom
>> + *     Bit 2 AAC (Quiet)
>> + *     Bit 3 AAC (Performance)
>> + *  cbRes3, byte 0 Current Thermal Mode
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performanc
>> + *  cbRes3, byte 1  AAC Configuration type
>> + *          0       Global (AAC enable/disable applies to all 
>> supported USTT modes)
>> + *          1       USTT mode specific
>> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
>> + *     If AAC Configuration Type is Global,
>> + *          0       AAC mode disabled
>> + *          1       AAC mode enabled
>> + *     If AAC Configuration Type is USTT mode specific (multiple bits 
>> may be set),
>> + *          Bit 0 AAC (Balanced)
>> + *          Bit 1 AAC (Cool Bottom
>> + *          Bit 2 AAC (Quiet)
>> + *          Bit 3 AAC (Performance)
>> + *  cbRes3, byte 3  Current Fan Failure Mode
>> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one 
>> fan working)
>> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
>> + *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode 
>> and
>> + *               desired AAC mode shall be applied
>> + *  cbArg2, byte 0  Desired Thermal Mode to set
>> + *                  (only one bit may be set for this parameter)
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performance
>> + *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
>> + *     If AAC Configuration Type is Global,
>> + *         0  AAC mode disabled
>> + *         1  AAC mode enabled
>> + *
>> + *     If AAC Configuration Type is USTT mode specific
>> + *     (multiple bits may be set for this parameter),
>> + *         Bit 0 AAC (Balanced)
>> + *         Bit 1 AAC (Cool Bottom
>> + *         Bit 2 AAC (Quiet)
>> + *         Bit 3 AAC (Performance)
>> + */
>> +
>> +#define DELL_ACC_GET_FIELD GENMASK(19, 16)
>> +#define DELL_ACC_SET_FIELD GENMASK(11, 8)
>> +#define DELL_THERMAL_SUPPORTED GENMASK(3, 0)
>> +
>> +enum thermal_mode_bits {
>> +    DELL_BALANCED = BIT(0),
>> +    DELL_COOL_BOTTOM = BIT(1),
>> +    DELL_QUIET = BIT(2),
>> +    DELL_PERFORMANCE = BIT(3),
>> +};
>> +
>> +static int thermal_get_mode(void)
>> +{
>> +    struct calling_interface_buffer buffer;
>> +    int state;
>> +    int ret;
>> +
>> +    dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +    ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +    if (ret)
>> +        return ret;
>> +    state = buffer.output[2];
>> +    if (state & DELL_BALANCED)
>> +        return DELL_BALANCED;
>> +    else if (state & DELL_COOL_BOTTOM)
>> +        return DELL_COOL_BOTTOM;
>> +    else if (state & DELL_QUIET)
>> +        return DELL_QUIET;
>> +    else if (state & DELL_PERFORMANCE)
>> +        return DELL_PERFORMANCE;
>> +    else
>> +        return -ENXIO;
>> +}
>> +
>> +static int thermal_get_supported_modes(int *supported_bits)
>> +{
>> +    struct calling_interface_buffer buffer;
>> +    int ret;
>> +
>> +    dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +    ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +    if (ret)
>> +        return ret;
>> +    *supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, 
>> buffer.output[1]);
>> +    return 0;
>> +}
>> +
>> +static int thermal_get_acc_mode(int *acc_mode)
>> +{
>> +    struct calling_interface_buffer buffer;
>> +    int ret;
>> +
>> +    dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +    ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +    if (ret)
>> +        return ret;
>> +    *acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
>> +    return 0;
>> +}
>> +
>> +static int thermal_set_mode(enum thermal_mode_bits state)
>> +{
>> +    struct calling_interface_buffer buffer;
>> +    int ret;
>> +    int acc_mode;
>> +
>> +    ret = thermal_get_acc_mode(&acc_mode);
>> +    if (ret)
>> +        return ret;
>> +
>> +    dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, 
>> acc_mode) | state, 0, 0);
>> +    ret = dell_send_request(&buffer, CLASS_INFO, 
>> SELECT_THERMAL_MANAGEMENT);
>> +    return ret;
>> +}
>> +
>> +static int thermal_platform_profile_set(struct 
>> platform_profile_handler *pprof,
>> +                    enum platform_profile_option profile)
>> +{
>> +    switch (profile) {
>> +    case PLATFORM_PROFILE_BALANCED:
>> +        return thermal_set_mode(DELL_BALANCED);
>> +    case PLATFORM_PROFILE_PERFORMANCE:
>> +        return thermal_set_mode(DELL_PERFORMANCE);
>> +    case PLATFORM_PROFILE_QUIET:
>> +        return thermal_set_mode(DELL_QUIET);
>> +    case PLATFORM_PROFILE_COOL:
>> +        return thermal_set_mode(DELL_COOL_BOTTOM);
>> +    default:
>> +        return -EOPNOTSUPP;
>> +    }
>> +}
>> +
>> +static int thermal_platform_profile_get(struct 
>> platform_profile_handler *pprof,
>> +                    enum platform_profile_option *profile)
>> +{
>> +    int ret = thermal_get_mode();
>> +
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    switch (ret) {
>> +    case DELL_BALANCED:
>> +        *profile = PLATFORM_PROFILE_BALANCED;
>> +        break;
>> +    case DELL_PERFORMANCE:
>> +        *profile = PLATFORM_PROFILE_PERFORMANCE;
>> +        break;
>> +    case DELL_COOL_BOTTOM:
>> +        *profile = PLATFORM_PROFILE_COOL;
>> +        break;
>> +    case DELL_QUIET:
>> +        *profile = PLATFORM_PROFILE_QUIET;
>> +        break;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +int thermal_init(void)
>> +{
>> +    int ret;
>> +    int supported_modes;
>> +
>> +    ret = thermal_get_supported_modes(&supported_modes);
>> +    if (ret || !supported_modes)
>> +        return 0;
>> +
>> +    thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
>> +    if (!thermal_handler)
>> +        return -ENOMEM;
>> +    thermal_handler->profile_get = thermal_platform_profile_get;
>> +    thermal_handler->profile_set = thermal_platform_profile_set;
>> +
>> +    if (supported_modes & DELL_QUIET)
>> +        set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
>> +    if (supported_modes & DELL_COOL_BOTTOM)
>> +        set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
>> +    if (supported_modes & DELL_BALANCED)
>> +        set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
>> +    if (supported_modes & DELL_PERFORMANCE)
>> +        set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
>> +
>> +    // Clean up but do not fail
> 
> Switch comment style to /* */
> 
>> +    if (platform_profile_register(thermal_handler))
>> +        kfree(thermal_handler);
> 
> Don't you also want to return an error in this case?  Because this means 
> that the platform supports thermal modes but it failed to setup due to 
> other issues.
> 
> It's different than the case of no supported modes in which case 
> returning 0 makes sense.
> 
> Maybe like this:
> 
> 
> ret = platform_profile_register(thermal_handler);
> if (ret)
>      kfree(thermal_handler);
> 
> return ret;
> 
> 
>> +
>> +    return 0;
>> +}
>> +
>> +void thermal_cleanup(void)
>> +{
>> +    if (thermal_handler) {
>> +        platform_profile_remove();
>> +        kfree(thermal_handler);
>> +    }
>> +}
>> +
>>   static struct led_classdev mute_led_cdev = {
>>       .name = "platform::mute",
>>       .max_brightness = 1,
>> @@ -2238,6 +2462,11 @@ static int __init dell_init(void)
>>           goto fail_rfkill;
>>       }
>> +    // Do not fail module if thermal modes not supported, just skip
> 
> Switch comment style to /* */
> 
>> +    ret = thermal_init();
>> +    if (ret)
>> +        goto fail_thermal;
>> +
>>       if (quirks && quirks->touchpad_led)
>>           touchpad_led_init(&platform_device->dev);
>> @@ -2317,6 +2546,8 @@ static int __init dell_init(void)
>>           led_classdev_unregister(&mute_led_cdev);
>>   fail_led:
>>       dell_cleanup_rfkill();
>> +fail_thermal:
>> +    thermal_cleanup();
>>   fail_rfkill:
>>       platform_device_del(platform_device);
>>   fail_platform_device2:
>> @@ -2344,6 +2575,7 @@ static void __exit dell_exit(void)
>>           platform_device_unregister(platform_device);
>>           platform_driver_unregister(&platform_driver);
>>       }
>> +    thermal_cleanup();
>>   }
>>   /* dell-rbtn.c driver export functions which will not work correctly 
>> (and could
>> diff --git a/drivers/platform/x86/dell/dell-smbios.h 
>> b/drivers/platform/x86/dell/dell-smbios.h
>> index eb341bf000c6..585d042f1779 100644
>> --- a/drivers/platform/x86/dell/dell-smbios.h
>> +++ b/drivers/platform/x86/dell/dell-smbios.h
>> @@ -19,6 +19,7 @@
>>   /* Classes and selects used only in kernel drivers */
>>   #define CLASS_KBD_BACKLIGHT 4
>>   #define SELECT_KBD_BACKLIGHT 11
>> +#define SELECT_THERMAL_MANAGEMENT 19

I think you should insert this into dell-smbios-base.c under 
call_blacklist.  This will prevent userspace from fighting with the 
kernel on the same data when this code goes in.

>>   /* Tokens used in kernel drivers, any of these
>>    * should be filtered from userspace access
> 


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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 17:45   ` Mario Limonciello
  2024-04-29 17:51     ` Mario Limonciello
@ 2024-04-29 21:21     ` Lyndon Sanche
  1 sibling, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-29 21:21 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen,
	Matthew Garrett, Hans de Goede, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On Mon, Apr 29 2024 at 12:45:19 PM -05:00:00, Mario Limonciello 
<mario.limonciello@amd.com> wrote:
> On 4/29/2024 11:48, Lyndon Sanche wrote:
>>   #include <linux/i8042.h>
>>   #include <linux/debugfs.h>
>>   #include <linux/seq_file.h>
>> +#include <linux/platform_profile.h>
>> +#include <linux/bitfield.h>
> 
> These should be inserted in alphabetical order.

Agree

>> +
>> +	// Clean up but do not fail
> 
> Switch comment style to /* */

Agree

> 
>> +	if (platform_profile_register(thermal_handler))
>> +		kfree(thermal_handler);
> 
> Don't you also want to return an error in this case?  Because this 
> means that the platform supports thermal modes but it failed to setup 
> due to other issues.
> 
> It's different than the case of no supported modes in which case 
> returning 0 makes sense.
> 
> Maybe like this:
> 
> 
> ret = platform_profile_register(thermal_handler);
> if (ret)
> 	kfree(thermal_handler);
> 
> return ret;

Good idea, I will propogate this error. Failure of module will then 
occur on allocation or platform_profile error.

> 
> 
>> 
>>   		goto fail_rfkill;
>>   	}
>>   \x7f+	// Do not fail module if thermal modes not supported, just skip
> 
> Switch comment style to /* */

Agree.

Thank you for this feedback.

Lyndon
> 



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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 17:51     ` Mario Limonciello
@ 2024-04-29 21:25       ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-29 21:25 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen,
	Matthew Garrett, Hans de Goede, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On Mon, Apr 29 2024 at 12:51:31 PM -05:00:00, Mario Limonciello 
<mario.limonciello@amd.com> wrote:
> On 4/29/2024 12:45, Mario Limonciello wrote:
>> On 4/29/2024 11:48, Lyndon Sanche wrote:
>>>   #define CLASS_KBD_BACKLIGHT 4
>>>   #define SELECT_KBD_BACKLIGHT 11
>>> +#define SELECT_THERMAL_MANAGEMENT 19
> 
> I think you should insert this into dell-smbios-base.c under 
> call_blacklist.  This will prevent userspace from fighting with the 
> kernel on the same data when this code goes in.

Good idea, I have been using smbios-thermal-ctl for checking the state 
when testing. I will include this in the patch, then smbios-thermal-ctl 
cannot interfere.

Thanks,

Lyndon



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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
  2024-04-29 17:45   ` Mario Limonciello
@ 2024-04-30 10:31   ` Ilpo Järvinen
  2024-04-30 18:38     ` Lyndon Sanche
  2024-04-30 15:36   ` kernel test robot
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 72+ messages in thread
From: Ilpo Järvinen @ 2024-04-30 10:31 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	Matthew Garrett, Hans de Goede, platform-driver-x86, LKML,
	Dell.Client.Kernel

On Mon, 29 Apr 2024, Lyndon Sanche wrote:

> Some Dell laptops support configuration of preset fan modes through
> smbios tables.
> 
> If the platform supports these fan modes, set up platform_profile to
> change these modes. If not supported, skip enabling platform_profile.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
> v3:
>  - Convert smbios-thermal-ctl docs to multiline comment and wrap
>  - Change thermal_mode_bits enum to directly be BIT() values
>   - Convert related code to use this
>  - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
>   - Correct offset for getting current ACC mode, setting offset
> 		unchanged
>  - Check if thermal_handler is allocated before freeing and
> 	 unregistering platform_profile
> v2:
>  - Wrap smbios-thermal-ctl comment
>  - Return proper error code when invalid state returned
>  - Simplify platform_profile_get returns
>  - Propogate ENOMEM error
> ---
>  drivers/platform/x86/dell/dell-laptop.c | 232 ++++++++++++++++++++++++
>  drivers/platform/x86/dell/dell-smbios.h |   1 +
>  2 files changed, 233 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..fa58e7751d06 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,8 @@
>  #include <linux/i8042.h>
>  #include <linux/debugfs.h>
>  #include <linux/seq_file.h>
> +#include <linux/platform_profile.h>
> +#include <linux/bitfield.h>
>  #include <acpi/video.h>
>  #include "dell-rbtn.h"
>  #include "dell-smbios.h"
> @@ -95,6 +97,7 @@ static struct backlight_device *dell_backlight_device;
>  static struct rfkill *wifi_rfkill;
>  static struct rfkill *bluetooth_rfkill;
>  static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>  static bool force_rfkill;
>  static bool micmute_led_registered;
>  static bool mute_led_registered;
> @@ -2199,6 +2202,227 @@ static int mute_led_set(struct led_classdev *led_cdev,
>  	return 0;
>  }
>  
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> + *               desired AAC mode shall be applied
> + *  cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *
> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED GENMASK(3, 0)

Please align these with tabs.

> +enum thermal_mode_bits {
> +	DELL_BALANCED = BIT(0),
> +	DELL_COOL_BOTTOM = BIT(1),
> +	DELL_QUIET = BIT(2),
> +	DELL_PERFORMANCE = BIT(3),

You need #include <linux/bits.h> for BIT().

> +};
> +
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if (state & DELL_BALANCED)
> +		return DELL_BALANCED;
> +	else if (state & DELL_COOL_BOTTOM)
> +		return DELL_COOL_BOTTOM;
> +	else if (state & DELL_QUIET)
> +		return DELL_QUIET;
> +	else if (state & DELL_PERFORMANCE)
> +		return DELL_PERFORMANCE;
> +	else
> +		return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		return thermal_set_mode(DELL_BALANCED);
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return thermal_set_mode(DELL_PERFORMANCE);
> +	case PLATFORM_PROFILE_QUIET:
> +		return thermal_set_mode(DELL_QUIET);
> +	case PLATFORM_PROFILE_COOL:
> +		return thermal_set_mode(DELL_COOL_BOTTOM);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	int ret = thermal_get_mode();
> +
> +	if (ret < 0)

I think I already mentioned about this, change to:

	int ret;

	ret = thermal_get_mode();
	if (ret < 0)

> +		return ret;
> +
> +	switch (ret) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	ret = thermal_get_supported_modes(&supported_modes);
> +	if (ret || !supported_modes)
> +		return 0;

I think you should propagate the error code differently from nothing 
supported:

	if (ret < 0)
		return ret;
	if (!supported_modes)
		return 0;

-- 
 i.

> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if (supported_modes & DELL_QUIET)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if (supported_modes & DELL_COOL_BOTTOM)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if (supported_modes & DELL_BALANCED)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if (supported_modes & DELL_PERFORMANCE)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	// Clean up but do not fail
> +	if (platform_profile_register(thermal_handler))
> +		kfree(thermal_handler);
> +
> +	return 0;
> +}
> +
> +void thermal_cleanup(void)
> +{
> +	if (thermal_handler) {
> +		platform_profile_remove();
> +		kfree(thermal_handler);
> +	}
> +}
> +
>  static struct led_classdev mute_led_cdev = {
>  	.name = "platform::mute",
>  	.max_brightness = 1,
> @@ -2238,6 +2462,11 @@ static int __init dell_init(void)
>  		goto fail_rfkill;
>  	}
>  
> +	// Do not fail module if thermal modes not supported, just skip
> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>  	if (quirks && quirks->touchpad_led)
>  		touchpad_led_init(&platform_device->dev);
>  
> @@ -2317,6 +2546,8 @@ static int __init dell_init(void)
>  		led_classdev_unregister(&mute_led_cdev);
>  fail_led:
>  	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>  fail_rfkill:
>  	platform_device_del(platform_device);
>  fail_platform_device2:
> @@ -2344,6 +2575,7 @@ static void __exit dell_exit(void)
>  		platform_device_unregister(platform_device);
>  		platform_driver_unregister(&platform_driver);
>  	}
> +	thermal_cleanup();
>  }
>  
>  /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>  /* Classes and selects used only in kernel drivers */
>  #define CLASS_KBD_BACKLIGHT 4
>  #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>  
>  /* Tokens used in kernel drivers, any of these
>   * should be filtered from userspace access
> 

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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
  2024-04-29 17:45   ` Mario Limonciello
  2024-04-30 10:31   ` Ilpo Järvinen
@ 2024-04-30 15:36   ` kernel test robot
  2024-05-01  8:16   ` kernel test robot
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 72+ messages in thread
From: kernel test robot @ 2024-04-30 15:36 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: oe-kbuild-all, mario.limonciello, pali, W_Armin,
	srinivas.pandruvada, ilpo.jarvinen, Matthew Garrett,
	Hans de Goede, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Hi Lyndon,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.9-rc6 next-20240430]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240430-135932
base:   linus/master
patch link:    https://lore.kernel.org/r/20240429164844.7544-2-lsanche%40lyndeno.ca
patch subject: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20240430/202404302351.31IWk45T-lkp@intel.com/config)
compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240430/202404302351.31IWk45T-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404302351.31IWk45T-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/platform/x86/dell/dell-laptop.c:2387:5: warning: no previous prototype for 'thermal_init' [-Wmissing-prototypes]
    2387 | int thermal_init(void)
         |     ^~~~~~~~~~~~
>> drivers/platform/x86/dell/dell-laptop.c:2418:6: warning: no previous prototype for 'thermal_cleanup' [-Wmissing-prototypes]
    2418 | void thermal_cleanup(void)
         |      ^~~~~~~~~~~~~~~


vim +/thermal_init +2387 drivers/platform/x86/dell/dell-laptop.c

  2386	
> 2387	int thermal_init(void)
  2388	{
  2389		int ret;
  2390		int supported_modes;
  2391	
  2392		ret = thermal_get_supported_modes(&supported_modes);
  2393		if (ret || !supported_modes)
  2394			return 0;
  2395	
  2396		thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
  2397		if (!thermal_handler)
  2398			return -ENOMEM;
  2399		thermal_handler->profile_get = thermal_platform_profile_get;
  2400		thermal_handler->profile_set = thermal_platform_profile_set;
  2401	
  2402		if (supported_modes & DELL_QUIET)
  2403			set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
  2404		if (supported_modes & DELL_COOL_BOTTOM)
  2405			set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
  2406		if (supported_modes & DELL_BALANCED)
  2407			set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
  2408		if (supported_modes & DELL_PERFORMANCE)
  2409			set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
  2410	
  2411		// Clean up but do not fail
  2412		if (platform_profile_register(thermal_handler))
  2413			kfree(thermal_handler);
  2414	
  2415		return 0;
  2416	}
  2417	
> 2418	void thermal_cleanup(void)
  2419	{
  2420		if (thermal_handler) {
  2421			platform_profile_remove();
  2422			kfree(thermal_handler);
  2423		}
  2424	}
  2425	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-30 10:31   ` Ilpo Järvinen
@ 2024-04-30 18:38     ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-04-30 18:38 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	Matthew Garrett, Hans de Goede, platform-driver-x86, LKML,
	Dell.Client.Kernel

On Tue, Apr 30, 2024, at 4:31 AM, Ilpo Järvinen wrote:
> On Mon, 29 Apr 2024, Lyndon Sanche wrote:
>> + */
>> +
>> +#define DELL_ACC_GET_FIELD GENMASK(19, 16)
>> +#define DELL_ACC_SET_FIELD GENMASK(11, 8)
>> +#define DELL_THERMAL_SUPPORTED GENMASK(3, 0)
>
> Please align these with tabs.
>

Agreed.

>> +enum thermal_mode_bits {
>> +	DELL_BALANCED = BIT(0),
>> +	DELL_COOL_BOTTOM = BIT(1),
>> +	DELL_QUIET = BIT(2),
>> +	DELL_PERFORMANCE = BIT(3),
>
> You need #include <linux/bits.h> for BIT().
>

Agreed.

>> +	}
>> +}
>> +
>> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
>> +					enum platform_profile_option *profile)
>> +{
>> +	int ret = thermal_get_mode();
>> +
>> +	if (ret < 0)
>
> I think I already mentioned about this, change to:
>
> 	int ret;
>
> 	ret = thermal_get_mode();
> 	if (ret < 0)
>

I missed this.

>> +		return ret;
>> +
>> +	switch (ret) {
>> +	case DELL_BALANCED:
>> +		*profile = PLATFORM_PROFILE_BALANCED;
>> +		break;
>> +	case DELL_PERFORMANCE:
>> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
>> +		break;
>> +	case DELL_COOL_BOTTOM:
>> +		*profile = PLATFORM_PROFILE_COOL;
>> +		break;
>> +	case DELL_QUIET:
>> +		*profile = PLATFORM_PROFILE_QUIET;
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int thermal_init(void)
>> +{
>> +	int ret;
>> +	int supported_modes;
>> +
>> +	ret = thermal_get_supported_modes(&supported_modes);
>> +	if (ret || !supported_modes)
>> +		return 0;
>
> I think you should propagate the error code differently from nothing 
> supported:
>
> 	if (ret < 0)
> 		return ret;
> 	if (!supported_modes)
> 		return 0;
>

Agreed.

Thank you for your feedback.

Lyndon

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

* [PATCH v4] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (5 preceding siblings ...)
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
@ 2024-05-01  1:14 ` Lyndon Sanche
  2024-05-01  1:36   ` Pali Rohár
  2024-05-01 21:58 ` [PATCH v5] " Lyndon Sanche
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-01  1:14 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, Matthew Garrett, Hans de Goede,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Some Dell laptops support configuration of preset fan modes through
smbios tables.

If the platform supports these fan modes, set up platform_profile to
change these modes. If not supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
v4:
 - Make thermal_init and thermal_cleanup static
 - Rearrange order of added includes, did not edit current includes
 - Include bits.h
 - Switch comment style
 - Return error if platform_profile registering failed
 - Add thermal calls to call_blacklist
 - Align defines with tabs
 - Correct separation of function and error handling
 - Propagate error codes up
v3:
 - Convert smbios-thermal-ctl docs to multiline comment and wrap
 - Change thermal_mode_bits enum to directly be BIT() values
	- Convert related code to use this
 - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
	- Correct offset for getting current ACC mode, setting offset
		unchanged
 - Check if thermal_handler is allocated before freeing and
	 unregistering platform_profile
v2:
 - Wrap smbios-thermal-ctl comment
 - Return proper error code when invalid state returned
 - Simplify platform_profile_get returns
 - Propogate ENOMEM error
---
 drivers/platform/x86/dell/dell-laptop.c      | 238 +++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios-base.c |   2 +
 drivers/platform/x86/dell/dell-smbios.h      |   1 +
 3 files changed, 241 insertions(+)

diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..530ee6079447 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -27,6 +27,9 @@
 #include <linux/i8042.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/platform_profile.h>
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
@@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct platform_profile_handler *thermal_handler;
 static bool force_rfkill;
 static bool micmute_led_registered;
 static bool mute_led_registered;
@@ -2199,6 +2203,232 @@ static int mute_led_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
+/* Derived from smbios-thermal-ctl
+ *
+ * cbClass 17
+ * cbSelect 19
+ * User Selectable Thermal Tables(USTT)
+ * cbArg1 determines the function to be performed
+ * cbArg1 0x0 = Get Thermal Information
+ *  cbRES1         Standard return codes (0, -1, -2)
+ *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
+ *                  its bit is set to 1
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
+ *                 Each mode corresponds to the supported thermal modes in
+ *                  byte 0. A mode is supported if its bit is set to 1.
+ *     Bit 0 AAC (Balanced)
+ *     Bit 1 AAC (Cool Bottom
+ *     Bit 2 AAC (Quiet)
+ *     Bit 3 AAC (Performance)
+ *  cbRes3, byte 0 Current Thermal Mode
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performanc
+ *  cbRes3, byte 1  AAC Configuration type
+ *          0       Global (AAC enable/disable applies to all supported USTT modes)
+ *          1       USTT mode specific
+ *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+ *     If AAC Configuration Type is Global,
+ *          0       AAC mode disabled
+ *          1       AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+ *          Bit 0 AAC (Balanced)
+ *          Bit 1 AAC (Cool Bottom
+ *          Bit 2 AAC (Quiet)
+ *          Bit 3 AAC (Performance)
+ *  cbRes3, byte 3  Current Fan Failure Mode
+ *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+ *     Bit 1 Catastrophic Fan Failure (all fans have failed)
+ *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+ *               desired AAC mode shall be applied
+ *  cbArg2, byte 0  Desired Thermal Mode to set
+ *                  (only one bit may be set for this parameter)
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+ *     If AAC Configuration Type is Global,
+ *         0  AAC mode disabled
+ *         1  AAC mode enabled
+ *
+ *     If AAC Configuration Type is USTT mode specific
+ *     (multiple bits may be set for this parameter),
+ *         Bit 0 AAC (Balanced)
+ *         Bit 1 AAC (Cool Bottom
+ *         Bit 2 AAC (Quiet)
+ *         Bit 3 AAC (Performance)
+ */
+
+#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
+#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
+#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
+
+enum thermal_mode_bits {
+	DELL_BALANCED = BIT(0),
+	DELL_COOL_BOTTOM = BIT(1),
+	DELL_QUIET = BIT(2),
+	DELL_PERFORMANCE = BIT(3),
+};
+
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if (state & DELL_BALANCED)
+		return DELL_BALANCED;
+	else if (state & DELL_COOL_BOTTOM)
+		return DELL_COOL_BOTTOM;
+	else if (state & DELL_QUIET)
+		return DELL_QUIET;
+	else if (state & DELL_PERFORMANCE)
+		return DELL_PERFORMANCE;
+	else
+		return -ENXIO;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		return thermal_set_mode(DELL_BALANCED);
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return thermal_set_mode(DELL_PERFORMANCE);
+	case PLATFORM_PROFILE_QUIET:
+		return thermal_set_mode(DELL_QUIET);
+	case PLATFORM_PROFILE_COOL:
+		return thermal_set_mode(DELL_COOL_BOTTOM);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	int ret;
+
+	ret = thermal_get_mode();
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	/* If thermal modes not supported, exit without error */
+	ret = thermal_get_supported_modes(&supported_modes);
+	if (ret < 0)
+		return ret;
+	if (!supported_modes)
+		return 0;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if (supported_modes & DELL_QUIET)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if (supported_modes & DELL_COOL_BOTTOM)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if (supported_modes & DELL_BALANCED)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if (supported_modes & DELL_PERFORMANCE)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	/* Clean up if failed */
+	ret = platform_profile_register(thermal_handler);
+	if (ret)
+		kfree(thermal_handler);
+
+	return ret;
+}
+
+static void thermal_cleanup(void)
+{
+	if (thermal_handler) {
+		platform_profile_remove();
+		kfree(thermal_handler);
+	}
+}
+
 static struct led_classdev mute_led_cdev = {
 	.name = "platform::mute",
 	.max_brightness = 1,
@@ -2238,6 +2468,11 @@ static int __init dell_init(void)
 		goto fail_rfkill;
 	}
 
+	/* Do not fail module if thermal modes not supported, just skip */
+	ret = thermal_init();
+	if (ret)
+		goto fail_thermal;
+
 	if (quirks && quirks->touchpad_led)
 		touchpad_led_init(&platform_device->dev);
 
@@ -2317,6 +2552,8 @@ static int __init dell_init(void)
 		led_classdev_unregister(&mute_led_cdev);
 fail_led:
 	dell_cleanup_rfkill();
+fail_thermal:
+	thermal_cleanup();
 fail_rfkill:
 	platform_device_del(platform_device);
 fail_platform_device2:
@@ -2344,6 +2581,7 @@ static void __exit dell_exit(void)
 		platform_device_unregister(platform_device);
 		platform_driver_unregister(&platform_driver);
 	}
+	thermal_cleanup();
 }
 
 /* dell-rbtn.c driver export functions which will not work correctly (and could
diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index e61bfaf8b5c4..40aa4469b38b 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -9,6 +9,7 @@
  *  Based on documentation in the libsmbios package:
  *  Copyright (C) 2005-2014 Dell Inc.
  */
+#include "linux/wmi.h"
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
@@ -71,6 +72,7 @@ static struct smbios_call call_blacklist[] = {
 	/* handled by kernel: dell-laptop */
 	{0x0000, CLASS_INFO, SELECT_RFKILL},
 	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
+	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
 };
 
 struct token_range {
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..585d042f1779 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* Re: [PATCH v4] platform/x86: dell-laptop: Implement platform_profile
  2024-05-01  1:14 ` [PATCH v4] " Lyndon Sanche
@ 2024-05-01  1:36   ` Pali Rohár
  2024-05-01  1:42     ` Lyndon Sanche
  0 siblings, 1 reply; 72+ messages in thread
From: Pali Rohár @ 2024-05-01  1:36 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, W_Armin, srinivas.pandruvada, ilpo.jarvinen,
	lkp, Matthew Garrett, Hans de Goede, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel

On Tuesday 30 April 2024 19:14:52 Lyndon Sanche wrote:
> Some Dell laptops support configuration of preset fan modes through
> smbios tables.
> 
> If the platform supports these fan modes, set up platform_profile to
> change these modes. If not supported, skip enabling platform_profile.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
> v4:
>  - Make thermal_init and thermal_cleanup static
>  - Rearrange order of added includes, did not edit current includes
>  - Include bits.h
>  - Switch comment style
>  - Return error if platform_profile registering failed
>  - Add thermal calls to call_blacklist
>  - Align defines with tabs
>  - Correct separation of function and error handling
>  - Propagate error codes up
> v3:
>  - Convert smbios-thermal-ctl docs to multiline comment and wrap
>  - Change thermal_mode_bits enum to directly be BIT() values
> 	- Convert related code to use this
>  - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
> 	- Correct offset for getting current ACC mode, setting offset
> 		unchanged
>  - Check if thermal_handler is allocated before freeing and
> 	 unregistering platform_profile
> v2:
>  - Wrap smbios-thermal-ctl comment
>  - Return proper error code when invalid state returned
>  - Simplify platform_profile_get returns
>  - Propogate ENOMEM error
> ---
>  drivers/platform/x86/dell/dell-laptop.c      | 238 +++++++++++++++++++
>  drivers/platform/x86/dell/dell-smbios-base.c |   2 +
>  drivers/platform/x86/dell/dell-smbios.h      |   1 +
>  3 files changed, 241 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..530ee6079447 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,9 @@
>  #include <linux/i8042.h>
>  #include <linux/debugfs.h>
>  #include <linux/seq_file.h>
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/platform_profile.h>
>  #include <acpi/video.h>
>  #include "dell-rbtn.h"
>  #include "dell-smbios.h"
> @@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
>  static struct rfkill *wifi_rfkill;
>  static struct rfkill *bluetooth_rfkill;
>  static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>  static bool force_rfkill;
>  static bool micmute_led_registered;
>  static bool mute_led_registered;
> @@ -2199,6 +2203,232 @@ static int mute_led_set(struct led_classdev *led_cdev,
>  	return 0;
>  }
>  
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and

Broken indentation. cbArg1 should have only one space after "*" and be
at the same level as the previous cbArg1 description.

And I would suggest to add a newline before cbArg1 as it start
description of the next command.

> + *               desired AAC mode shall be applied
> + *  cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *

And here I would suggest to remove empty line as the comment below
belongs to the AAC description above the empty line.

> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
> +
> +enum thermal_mode_bits {
> +	DELL_BALANCED = BIT(0),
> +	DELL_COOL_BOTTOM = BIT(1),
> +	DELL_QUIET = BIT(2),
> +	DELL_PERFORMANCE = BIT(3),
> +};
> +
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if (state & DELL_BALANCED)
> +		return DELL_BALANCED;
> +	else if (state & DELL_COOL_BOTTOM)
> +		return DELL_COOL_BOTTOM;
> +	else if (state & DELL_QUIET)
> +		return DELL_QUIET;
> +	else if (state & DELL_PERFORMANCE)
> +		return DELL_PERFORMANCE;
> +	else
> +		return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		return thermal_set_mode(DELL_BALANCED);
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return thermal_set_mode(DELL_PERFORMANCE);
> +	case PLATFORM_PROFILE_QUIET:
> +		return thermal_set_mode(DELL_QUIET);
> +	case PLATFORM_PROFILE_COOL:
> +		return thermal_set_mode(DELL_COOL_BOTTOM);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	int ret;
> +
> +	ret = thermal_get_mode();
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (ret) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	/* If thermal modes not supported, exit without error */
> +	ret = thermal_get_supported_modes(&supported_modes);
> +	if (ret < 0)
> +		return ret;
> +	if (!supported_modes)
> +		return 0;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if (supported_modes & DELL_QUIET)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if (supported_modes & DELL_COOL_BOTTOM)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if (supported_modes & DELL_BALANCED)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if (supported_modes & DELL_PERFORMANCE)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	/* Clean up if failed */
> +	ret = platform_profile_register(thermal_handler);
> +	if (ret)
> +		kfree(thermal_handler);
> +
> +	return ret;
> +}
> +
> +static void thermal_cleanup(void)
> +{
> +	if (thermal_handler) {
> +		platform_profile_remove();
> +		kfree(thermal_handler);
> +	}
> +}
> +
>  static struct led_classdev mute_led_cdev = {
>  	.name = "platform::mute",
>  	.max_brightness = 1,
> @@ -2238,6 +2468,11 @@ static int __init dell_init(void)
>  		goto fail_rfkill;
>  	}
>  
> +	/* Do not fail module if thermal modes not supported, just skip */
> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>  	if (quirks && quirks->touchpad_led)
>  		touchpad_led_init(&platform_device->dev);
>  
> @@ -2317,6 +2552,8 @@ static int __init dell_init(void)
>  		led_classdev_unregister(&mute_led_cdev);
>  fail_led:
>  	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>  fail_rfkill:
>  	platform_device_del(platform_device);
>  fail_platform_device2:
> @@ -2344,6 +2581,7 @@ static void __exit dell_exit(void)
>  		platform_device_unregister(platform_device);
>  		platform_driver_unregister(&platform_driver);
>  	}
> +	thermal_cleanup();
>  }
>  
>  /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
> index e61bfaf8b5c4..40aa4469b38b 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -9,6 +9,7 @@
>   *  Based on documentation in the libsmbios package:
>   *  Copyright (C) 2005-2014 Dell Inc.
>   */
> +#include "linux/wmi.h"

Is this include file really used? Because only SELECT_THERMAL_MANAGEMENT
was added and it is in the dell-smbios.h. And others constants like
SELECT_KBD_BACKLIGHT did not needed it.

>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
>  #include <linux/kernel.h>
> @@ -71,6 +72,7 @@ static struct smbios_call call_blacklist[] = {
>  	/* handled by kernel: dell-laptop */
>  	{0x0000, CLASS_INFO, SELECT_RFKILL},
>  	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
> +	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>  };
>  
>  struct token_range {
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>  /* Classes and selects used only in kernel drivers */
>  #define CLASS_KBD_BACKLIGHT 4
>  #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>  
>  /* Tokens used in kernel drivers, any of these
>   * should be filtered from userspace access
> -- 
> 2.42.0
> 

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

* Re: [PATCH v4] platform/x86: dell-laptop: Implement platform_profile
  2024-05-01  1:36   ` Pali Rohár
@ 2024-05-01  1:42     ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-01  1:42 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Mario Limonciello, W_Armin, srinivas.pandruvada,
	Ilpo Järvinen, lkp, Matthew Garrett, Hans de Goede,
	platform-driver-x86, LKML, Dell.Client.Kernel

On Tue, Apr 30, 2024, at 7:36 PM, Pali Rohár wrote:
> On Tuesday 30 April 2024 19:14:52 Lyndon Sanche wrote:
>> + *          Bit 2 AAC (Quiet)
>> + *          Bit 3 AAC (Performance)
>> + *  cbRes3, byte 3  Current Fan Failure Mode
>> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
>> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
>> + *  cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
>
> Broken indentation. cbArg1 should have only one space after "*" and be
> at the same level as the previous cbArg1 description.
>
> And I would suggest to add a newline before cbArg1 as it start
> description of the next command.
>

I will fix this.

>> + *               desired AAC mode shall be applied
>> + *  cbArg2, byte 0  Desired Thermal Mode to set
>> + *                  (only one bit may be set for this parameter)
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performance
>> + *  cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
>> + *     If AAC Configuration Type is Global,
>> + *         0  AAC mode disabled
>> + *         1  AAC mode enabled
>> + *
>
> And here I would suggest to remove empty line as the comment below
> belongs to the AAC description above the empty line.
>

Agreed.

>>  
>>  /* dell-rbtn.c driver export functions which will not work correctly (and could
>> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
>> index e61bfaf8b5c4..40aa4469b38b 100644
>> --- a/drivers/platform/x86/dell/dell-smbios-base.c
>> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
>> @@ -9,6 +9,7 @@
>>   *  Based on documentation in the libsmbios package:
>>   *  Copyright (C) 2005-2014 Dell Inc.
>>   */
>> +#include "linux/wmi.h"
>
> Is this include file really used? Because only SELECT_THERMAL_MANAGEMENT
> was added and it is in the dell-smbios.h. And others constants like
> SELECT_KBD_BACKLIGHT did not needed it.
>

No it is not. It seems my IDE automatically inserted this. I glossed over it when committing it seems.

Thank you for your quick feedback.

Lyndon

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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
                     ` (2 preceding siblings ...)
  2024-04-30 15:36   ` kernel test robot
@ 2024-05-01  8:16   ` kernel test robot
  2024-05-01 16:35   ` kernel test robot
  2024-05-01 17:07   ` kernel test robot
  5 siblings, 0 replies; 72+ messages in thread
From: kernel test robot @ 2024-05-01  8:16 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: llvm, oe-kbuild-all, mario.limonciello, pali, W_Armin,
	srinivas.pandruvada, ilpo.jarvinen, Matthew Garrett,
	Hans de Goede, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Hi Lyndon,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.9-rc6 next-20240430]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240430-135932
base:   linus/master
patch link:    https://lore.kernel.org/r/20240429164844.7544-2-lsanche%40lyndeno.ca
patch subject: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
config: i386-buildonly-randconfig-001-20240501 (https://download.01.org/0day-ci/archive/20240501/202405011636.CDJVLh7l-lkp@intel.com/config)
compiler: clang version 18.1.4 (https://github.com/llvm/llvm-project e6c3289804a67ea0bb6a86fadbe454dd93b8d855)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240501/202405011636.CDJVLh7l-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405011636.CDJVLh7l-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/platform/x86/dell/dell-laptop.c:2387:5: warning: no previous prototype for function 'thermal_init' [-Wmissing-prototypes]
    2387 | int thermal_init(void)
         |     ^
   drivers/platform/x86/dell/dell-laptop.c:2387:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    2387 | int thermal_init(void)
         | ^
         | static 
>> drivers/platform/x86/dell/dell-laptop.c:2418:6: warning: no previous prototype for function 'thermal_cleanup' [-Wmissing-prototypes]
    2418 | void thermal_cleanup(void)
         |      ^
   drivers/platform/x86/dell/dell-laptop.c:2418:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    2418 | void thermal_cleanup(void)
         | ^
         | static 
   2 warnings generated.


vim +/thermal_init +2387 drivers/platform/x86/dell/dell-laptop.c

  2386	
> 2387	int thermal_init(void)
  2388	{
  2389		int ret;
  2390		int supported_modes;
  2391	
  2392		ret = thermal_get_supported_modes(&supported_modes);
  2393		if (ret || !supported_modes)
  2394			return 0;
  2395	
  2396		thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
  2397		if (!thermal_handler)
  2398			return -ENOMEM;
  2399		thermal_handler->profile_get = thermal_platform_profile_get;
  2400		thermal_handler->profile_set = thermal_platform_profile_set;
  2401	
  2402		if (supported_modes & DELL_QUIET)
  2403			set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
  2404		if (supported_modes & DELL_COOL_BOTTOM)
  2405			set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
  2406		if (supported_modes & DELL_BALANCED)
  2407			set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
  2408		if (supported_modes & DELL_PERFORMANCE)
  2409			set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
  2410	
  2411		// Clean up but do not fail
  2412		if (platform_profile_register(thermal_handler))
  2413			kfree(thermal_handler);
  2414	
  2415		return 0;
  2416	}
  2417	
> 2418	void thermal_cleanup(void)
  2419	{
  2420		if (thermal_handler) {
  2421			platform_profile_remove();
  2422			kfree(thermal_handler);
  2423		}
  2424	}
  2425	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
                     ` (3 preceding siblings ...)
  2024-05-01  8:16   ` kernel test robot
@ 2024-05-01 16:35   ` kernel test robot
  2024-05-01 17:07   ` kernel test robot
  5 siblings, 0 replies; 72+ messages in thread
From: kernel test robot @ 2024-05-01 16:35 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: oe-kbuild-all, mario.limonciello, pali, W_Armin,
	srinivas.pandruvada, ilpo.jarvinen, Matthew Garrett,
	Hans de Goede, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Hi Lyndon,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.9-rc6 next-20240501]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240430-135932
base:   linus/master
patch link:    https://lore.kernel.org/r/20240429164844.7544-2-lsanche%40lyndeno.ca
patch subject: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
config: x86_64-buildonly-randconfig-001-20240501 (https://download.01.org/0day-ci/archive/20240502/202405020004.y49VOvGS-lkp@intel.com/config)
compiler: gcc-9 (Ubuntu 9.5.0-4ubuntu2) 9.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240502/202405020004.y49VOvGS-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405020004.y49VOvGS-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/tests/drm_probe_helper_test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/tests/drm_rect_test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/gud/gud.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/udl/udl.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/base/regmap/regmap-kunit.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/base/regmap/regmap-ram.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/base/regmap/regmap-raw-ram.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/base/regmap/regmap-spmi.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mfd/pcf50633-gpio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/dax/dax.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/firewire/firewire-uapi-test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/misc/isight_firmware.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/mon/usbmon.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/chipidea/ci_hdrc_msm.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/libcomposite.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_acm.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_ss_lb.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/u_serial.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_serial.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/u_ether.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_ncm.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_ecm.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_mass_storage.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_printer.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/function/usb_f_tcm.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/usb/gadget/legacy/g_zero.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/touchscreen/cyttsp_i2c_common.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/tests/input_test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/lib_test.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/rtc-goldfish.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/i2c/busses/i2c-ali1563.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hwmon/corsair-cpro.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/watchdog/menz69_wdt.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/mmc_core.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/mmc/core/sdio_uart.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-a4tech.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-apple.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-aureal.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-betopff.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-bigbenff.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-cherry.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-chicony.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-dr.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-emsff.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-elecom.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-elo.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-holtek-kbd.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-holtek-mouse.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-ite.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-keytouch.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-lcpower.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-letsketch.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-logitech.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-lg-g15.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-magicmouse.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-maltron.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-mf.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-megaworld.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-microsoft.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-ntrig.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-ortek.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-pl.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-razer.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-redragon.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-retrode.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-saitek.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-semitek.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-sony.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-speedlink.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-steam.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-steelseries.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-sunplus.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-gaff.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-tmff.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-tivo.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-twinhan.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-uclogic.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-zydacron.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-waltop.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/greybus/gb-es2.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-bootrom.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-hid.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-loopback.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-power-supply.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-gbphy.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-gpio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/staging/greybus/gb-usb.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/platform/x86/intel/speed_select_if/isst_if_common.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/platform/goldfish/goldfish_pipe.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/devfreq/governor_powersave.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hwtracing/intel_th/intel_th_msu_sink.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/siox/siox-bus-gpio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_cif.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/uio/uio_netx.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/dca/dca.o
WARNING: modpost: missing MODULE_DESCRIPTION() in samples/configfs/configfs_sample.o
WARNING: modpost: missing MODULE_DESCRIPTION() in samples/kprobes/kprobe_example.o
WARNING: modpost: missing MODULE_DESCRIPTION() in samples/kprobes/kretprobe_example.o
>> ERROR: modpost: "platform_profile_register" [drivers/platform/x86/dell/dell-laptop.ko] undefined!
>> ERROR: modpost: "platform_profile_remove" [drivers/platform/x86/dell/dell-laptop.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
  2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
                     ` (4 preceding siblings ...)
  2024-05-01 16:35   ` kernel test robot
@ 2024-05-01 17:07   ` kernel test robot
  5 siblings, 0 replies; 72+ messages in thread
From: kernel test robot @ 2024-05-01 17:07 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: oe-kbuild-all, mario.limonciello, pali, W_Armin,
	srinivas.pandruvada, ilpo.jarvinen, Matthew Garrett,
	Hans de Goede, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Hi Lyndon,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.9-rc6 next-20240501]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240430-135932
base:   linus/master
patch link:    https://lore.kernel.org/r/20240429164844.7544-2-lsanche%40lyndeno.ca
patch subject: [PATCH v3] platform/x86: dell-laptop: Implement platform_profile
config: x86_64-randconfig-r122-20240501 (https://download.01.org/0day-ci/archive/20240502/202405020009.iVV1DXVS-lkp@intel.com/config)
compiler: clang version 18.1.4 (https://github.com/llvm/llvm-project e6c3289804a67ea0bb6a86fadbe454dd93b8d855)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240502/202405020009.iVV1DXVS-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405020009.iVV1DXVS-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/platform/x86/dell/dell-laptop.c:2418:6: sparse: sparse: symbol 'thermal_cleanup' was not declared. Should it be static?

vim +/thermal_cleanup +2418 drivers/platform/x86/dell/dell-laptop.c

  2386	
> 2387	int thermal_init(void)
  2388	{
  2389		int ret;
  2390		int supported_modes;
  2391	
  2392		ret = thermal_get_supported_modes(&supported_modes);
  2393		if (ret || !supported_modes)
  2394			return 0;
  2395	
  2396		thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
  2397		if (!thermal_handler)
  2398			return -ENOMEM;
  2399		thermal_handler->profile_get = thermal_platform_profile_get;
  2400		thermal_handler->profile_set = thermal_platform_profile_set;
  2401	
  2402		if (supported_modes & DELL_QUIET)
  2403			set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
  2404		if (supported_modes & DELL_COOL_BOTTOM)
  2405			set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
  2406		if (supported_modes & DELL_BALANCED)
  2407			set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
  2408		if (supported_modes & DELL_PERFORMANCE)
  2409			set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
  2410	
  2411		// Clean up but do not fail
  2412		if (platform_profile_register(thermal_handler))
  2413			kfree(thermal_handler);
  2414	
  2415		return 0;
  2416	}
  2417	
> 2418	void thermal_cleanup(void)
  2419	{
  2420		if (thermal_handler) {
  2421			platform_profile_remove();
  2422			kfree(thermal_handler);
  2423		}
  2424	}
  2425	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (6 preceding siblings ...)
  2024-05-01  1:14 ` [PATCH v4] " Lyndon Sanche
@ 2024-05-01 21:58 ` Lyndon Sanche
  2024-05-03 10:19   ` kernel test robot
                     ` (2 more replies)
  2024-05-11  2:36 ` [PATCH v6 0/2] " Lyndon Sanche
                   ` (3 subsequent siblings)
  11 siblings, 3 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-01 21:58 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, Hans de Goede, Matthew Garrett,
	Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Some Dell laptops support configuration of preset fan modes through
smbios tables.

If the platform supports these fan modes, set up platform_profile to
change these modes. If not supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
v5:
 - Fix indent in smbios-thermal-ctl comment
 - Remove linux/wmi.h include
 - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
v4:
 - Make thermal_init and thermal_cleanup static
 - Rearrange order of added includes, did not edit current includes
 - Include bits.h
 - Switch comment style
 - Return error if platform_profile registering failed
 - Add thermal calls to call_blacklist
 - Align defines with tabs
 - Correct separation of function and error handling
 - Propagate error codes up
v3:
 - Convert smbios-thermal-ctl docs to multiline comment and wrap
 - Change thermal_mode_bits enum to directly be BIT() values
	- Convert related code to use this
 - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
	- Correct offset for getting current ACC mode, setting offset
		unchanged
 - Check if thermal_handler is allocated before freeing and
	 unregistering platform_profile
v2:
 - Wrap smbios-thermal-ctl comment
 - Return proper error code when invalid state returned
 - Simplify platform_profile_get returns
 - Propogate ENOMEM error
---
 drivers/platform/x86/dell/Kconfig            |   1 +
 drivers/platform/x86/dell/dell-laptop.c      | 238 +++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios-base.c |   1 +
 drivers/platform/x86/dell/dell-smbios.h      |   1 +
 4 files changed, 241 insertions(+)

diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
index bd9f445974cc..5195ad59b44d 100644
--- a/drivers/platform/x86/dell/Kconfig
+++ b/drivers/platform/x86/dell/Kconfig
@@ -57,6 +57,7 @@ config DELL_LAPTOP
 	select POWER_SUPPLY
 	select LEDS_CLASS
 	select NEW_LEDS
+	select ACPI_PLATFORM_PROFILE
 	help
 	This driver adds support for rfkill and backlight control to Dell
 	laptops (except for some models covered by the Compal driver).
diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..dc530a4f5047 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -27,6 +27,9 @@
 #include <linux/i8042.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/platform_profile.h>
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
@@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct platform_profile_handler *thermal_handler;
 static bool force_rfkill;
 static bool micmute_led_registered;
 static bool mute_led_registered;
@@ -2199,6 +2203,232 @@ static int mute_led_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
+/* Derived from smbios-thermal-ctl
+ *
+ * cbClass 17
+ * cbSelect 19
+ * User Selectable Thermal Tables(USTT)
+ * cbArg1 determines the function to be performed
+ * cbArg1 0x0 = Get Thermal Information
+ *  cbRES1         Standard return codes (0, -1, -2)
+ *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
+ *                  its bit is set to 1
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
+ *                 Each mode corresponds to the supported thermal modes in
+ *                  byte 0. A mode is supported if its bit is set to 1.
+ *     Bit 0 AAC (Balanced)
+ *     Bit 1 AAC (Cool Bottom
+ *     Bit 2 AAC (Quiet)
+ *     Bit 3 AAC (Performance)
+ *  cbRes3, byte 0 Current Thermal Mode
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performanc
+ *  cbRes3, byte 1  AAC Configuration type
+ *          0       Global (AAC enable/disable applies to all supported USTT modes)
+ *          1       USTT mode specific
+ *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+ *     If AAC Configuration Type is Global,
+ *          0       AAC mode disabled
+ *          1       AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+ *          Bit 0 AAC (Balanced)
+ *          Bit 1 AAC (Cool Bottom
+ *          Bit 2 AAC (Quiet)
+ *          Bit 3 AAC (Performance)
+ *  cbRes3, byte 3  Current Fan Failure Mode
+ *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+ *     Bit 1 Catastrophic Fan Failure (all fans have failed)
+ *
+ * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+ *               desired AAC mode shall be applied
+ * cbArg2, byte 0  Desired Thermal Mode to set
+ *                  (only one bit may be set for this parameter)
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+ *     If AAC Configuration Type is Global,
+ *         0  AAC mode disabled
+ *         1  AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific
+ *     (multiple bits may be set for this parameter),
+ *         Bit 0 AAC (Balanced)
+ *         Bit 1 AAC (Cool Bottom
+ *         Bit 2 AAC (Quiet)
+ *         Bit 3 AAC (Performance)
+ */
+
+#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
+#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
+#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
+
+enum thermal_mode_bits {
+	DELL_BALANCED = BIT(0),
+	DELL_COOL_BOTTOM = BIT(1),
+	DELL_QUIET = BIT(2),
+	DELL_PERFORMANCE = BIT(3),
+};
+
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if (state & DELL_BALANCED)
+		return DELL_BALANCED;
+	else if (state & DELL_COOL_BOTTOM)
+		return DELL_COOL_BOTTOM;
+	else if (state & DELL_QUIET)
+		return DELL_QUIET;
+	else if (state & DELL_PERFORMANCE)
+		return DELL_PERFORMANCE;
+	else
+		return -ENXIO;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		return thermal_set_mode(DELL_BALANCED);
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return thermal_set_mode(DELL_PERFORMANCE);
+	case PLATFORM_PROFILE_QUIET:
+		return thermal_set_mode(DELL_QUIET);
+	case PLATFORM_PROFILE_COOL:
+		return thermal_set_mode(DELL_COOL_BOTTOM);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	int ret;
+
+	ret = thermal_get_mode();
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	/* If thermal modes not supported, exit without error */
+	ret = thermal_get_supported_modes(&supported_modes);
+	if (ret < 0)
+		return ret;
+	if (!supported_modes)
+		return 0;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if (supported_modes & DELL_QUIET)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if (supported_modes & DELL_COOL_BOTTOM)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if (supported_modes & DELL_BALANCED)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if (supported_modes & DELL_PERFORMANCE)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	/* Clean up if failed */
+	ret = platform_profile_register(thermal_handler);
+	if (ret)
+		kfree(thermal_handler);
+
+	return ret;
+}
+
+static void thermal_cleanup(void)
+{
+	if (thermal_handler) {
+		platform_profile_remove();
+		kfree(thermal_handler);
+	}
+}
+
 static struct led_classdev mute_led_cdev = {
 	.name = "platform::mute",
 	.max_brightness = 1,
@@ -2238,6 +2468,11 @@ static int __init dell_init(void)
 		goto fail_rfkill;
 	}
 
+	/* Do not fail module if thermal modes not supported, just skip */
+	ret = thermal_init();
+	if (ret)
+		goto fail_thermal;
+
 	if (quirks && quirks->touchpad_led)
 		touchpad_led_init(&platform_device->dev);
 
@@ -2317,6 +2552,8 @@ static int __init dell_init(void)
 		led_classdev_unregister(&mute_led_cdev);
 fail_led:
 	dell_cleanup_rfkill();
+fail_thermal:
+	thermal_cleanup();
 fail_rfkill:
 	platform_device_del(platform_device);
 fail_platform_device2:
@@ -2344,6 +2581,7 @@ static void __exit dell_exit(void)
 		platform_device_unregister(platform_device);
 		platform_driver_unregister(&platform_driver);
 	}
+	thermal_cleanup();
 }
 
 /* dell-rbtn.c driver export functions which will not work correctly (and could
diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index e61bfaf8b5c4..5bc2e394dd1c 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
 	/* handled by kernel: dell-laptop */
 	{0x0000, CLASS_INFO, SELECT_RFKILL},
 	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
+	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
 };
 
 struct token_range {
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..585d042f1779 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-01 21:58 ` [PATCH v5] " Lyndon Sanche
@ 2024-05-03 10:19   ` kernel test robot
  2024-05-04  1:03     ` Lyndon Sanche
  2024-05-03 21:19   ` Armin Wolf
  2024-05-08 14:24   ` Shen, Yijun
  2 siblings, 1 reply; 72+ messages in thread
From: kernel test robot @ 2024-05-03 10:19 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Paul Gazzillo, Necip Fazil Yildiran, oe-kbuild-all,
	mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, Hans de Goede, Matthew Garrett,
	Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Hi Lyndon,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.9-rc6 next-20240503]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240502-060146
base:   linus/master
patch link:    https://lore.kernel.org/r/20240501215829.4991-2-lsanche%40lyndeno.ca
patch subject: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
config: i386-kismet-CONFIG_ACPI_PLATFORM_PROFILE-CONFIG_DELL_LAPTOP-0-0 (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/config)
reproduce: (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405031851.NYy0ZB02-lkp@intel.com/

kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for ACPI_PLATFORM_PROFILE when selected by DELL_LAPTOP
   WARNING: unmet direct dependencies detected for ACPI_PLATFORM_PROFILE
     Depends on [n]: ACPI [=n]
     Selected by [y]:
     - DELL_LAPTOP [=y] && X86_PLATFORM_DEVICES [=y] && X86_PLATFORM_DRIVERS_DELL [=y] && DMI [=y] && BACKLIGHT_CLASS_DEVICE [=y] && (ACPI_VIDEO [=n] || ACPI_VIDEO [=n]=n) && (RFKILL [=n] || RFKILL [=n]=n) && (DELL_WMI [=n] || DELL_WMI [=n]=n) && SERIO_I8042 [=y] && DELL_SMBIOS [=y]

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-01 21:58 ` [PATCH v5] " Lyndon Sanche
  2024-05-03 10:19   ` kernel test robot
@ 2024-05-03 21:19   ` Armin Wolf
  2024-05-04  0:59     ` Lyndon Sanche
  2024-05-08 14:24   ` Shen, Yijun
  2 siblings, 1 reply; 72+ messages in thread
From: Armin Wolf @ 2024-05-03 21:19 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, pali, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Am 01.05.24 um 23:58 schrieb Lyndon Sanche:

> Some Dell laptops support configuration of preset fan modes through
> smbios tables.
>
> If the platform supports these fan modes, set up platform_profile to
> change these modes. If not supported, skip enabling platform_profile.
>
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
> v5:
>   - Fix indent in smbios-thermal-ctl comment
>   - Remove linux/wmi.h include
>   - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
> v4:
>   - Make thermal_init and thermal_cleanup static
>   - Rearrange order of added includes, did not edit current includes
>   - Include bits.h
>   - Switch comment style
>   - Return error if platform_profile registering failed
>   - Add thermal calls to call_blacklist
>   - Align defines with tabs
>   - Correct separation of function and error handling
>   - Propagate error codes up
> v3:
>   - Convert smbios-thermal-ctl docs to multiline comment and wrap
>   - Change thermal_mode_bits enum to directly be BIT() values
> 	- Convert related code to use this
>   - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
> 	- Correct offset for getting current ACC mode, setting offset
> 		unchanged
>   - Check if thermal_handler is allocated before freeing and
> 	 unregistering platform_profile
> v2:
>   - Wrap smbios-thermal-ctl comment
>   - Return proper error code when invalid state returned
>   - Simplify platform_profile_get returns
>   - Propogate ENOMEM error
> ---
>   drivers/platform/x86/dell/Kconfig            |   1 +
>   drivers/platform/x86/dell/dell-laptop.c      | 238 +++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios-base.c |   1 +
>   drivers/platform/x86/dell/dell-smbios.h      |   1 +
>   4 files changed, 241 insertions(+)
>
> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
> index bd9f445974cc..5195ad59b44d 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -57,6 +57,7 @@ config DELL_LAPTOP
>   	select POWER_SUPPLY
>   	select LEDS_CLASS
>   	select NEW_LEDS
> +	select ACPI_PLATFORM_PROFILE
>   	help
>   	This driver adds support for rfkill and backlight control to Dell
>   	laptops (except for some models covered by the Compal driver).
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..dc530a4f5047 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,9 @@
>   #include <linux/i8042.h>
>   #include <linux/debugfs.h>
>   #include <linux/seq_file.h>
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/platform_profile.h>
>   #include <acpi/video.h>
>   #include "dell-rbtn.h"
>   #include "dell-smbios.h"
> @@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
>   static struct rfkill *wifi_rfkill;
>   static struct rfkill *bluetooth_rfkill;
>   static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>   static bool force_rfkill;
>   static bool micmute_led_registered;
>   static bool mute_led_registered;
> @@ -2199,6 +2203,232 @@ static int mute_led_set(struct led_classdev *led_cdev,
>   	return 0;
>   }
>
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *
> + * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> + *               desired AAC mode shall be applied
> + * cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
> +
> +enum thermal_mode_bits {
> +	DELL_BALANCED = BIT(0),
> +	DELL_COOL_BOTTOM = BIT(1),
> +	DELL_QUIET = BIT(2),
> +	DELL_PERFORMANCE = BIT(3),
> +};
> +
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if (state & DELL_BALANCED)
> +		return DELL_BALANCED;
> +	else if (state & DELL_COOL_BOTTOM)
> +		return DELL_COOL_BOTTOM;
> +	else if (state & DELL_QUIET)
> +		return DELL_QUIET;
> +	else if (state & DELL_PERFORMANCE)
> +		return DELL_PERFORMANCE;
> +	else
> +		return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		return thermal_set_mode(DELL_BALANCED);
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return thermal_set_mode(DELL_PERFORMANCE);
> +	case PLATFORM_PROFILE_QUIET:
> +		return thermal_set_mode(DELL_QUIET);
> +	case PLATFORM_PROFILE_COOL:
> +		return thermal_set_mode(DELL_COOL_BOTTOM);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	int ret;
> +
> +	ret = thermal_get_mode();
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (ret) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	/* If thermal modes not supported, exit without error */
> +	ret = thermal_get_supported_modes(&supported_modes);
> +	if (ret < 0)
> +		return ret;

Hi,

some older models might not support the USTT commands, which would prevent dell-laptop
from loading on such machines.
Since dell-smbios-base already knows which commands are supported (stored in da_supported_commands),
maybe you can add a function for checking if a certain class of commands is supported and
skip thermal_init() if the USTT commands are not supported.

Thanks,
Armin Wolf

> +	if (!supported_modes)
> +		return 0;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if (supported_modes & DELL_QUIET)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if (supported_modes & DELL_COOL_BOTTOM)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if (supported_modes & DELL_BALANCED)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if (supported_modes & DELL_PERFORMANCE)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	/* Clean up if failed */
> +	ret = platform_profile_register(thermal_handler);
> +	if (ret)
> +		kfree(thermal_handler);
> +
> +	return ret;
> +}
> +
> +static void thermal_cleanup(void)
> +{
> +	if (thermal_handler) {
> +		platform_profile_remove();
> +		kfree(thermal_handler);
> +	}
> +}
> +
>   static struct led_classdev mute_led_cdev = {
>   	.name = "platform::mute",
>   	.max_brightness = 1,
> @@ -2238,6 +2468,11 @@ static int __init dell_init(void)
>   		goto fail_rfkill;
>   	}
>
> +	/* Do not fail module if thermal modes not supported, just skip */
> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>   	if (quirks && quirks->touchpad_led)
>   		touchpad_led_init(&platform_device->dev);
>
> @@ -2317,6 +2552,8 @@ static int __init dell_init(void)
>   		led_classdev_unregister(&mute_led_cdev);
>   fail_led:
>   	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>   fail_rfkill:
>   	platform_device_del(platform_device);
>   fail_platform_device2:
> @@ -2344,6 +2581,7 @@ static void __exit dell_exit(void)
>   		platform_device_unregister(platform_device);
>   		platform_driver_unregister(&platform_driver);
>   	}
> +	thermal_cleanup();
>   }
>
>   /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
> index e61bfaf8b5c4..5bc2e394dd1c 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
>   	/* handled by kernel: dell-laptop */
>   	{0x0000, CLASS_INFO, SELECT_RFKILL},
>   	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
> +	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>   };
>
>   struct token_range {
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>   /* Classes and selects used only in kernel drivers */
>   #define CLASS_KBD_BACKLIGHT 4
>   #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>
>   /* Tokens used in kernel drivers, any of these
>    * should be filtered from userspace access

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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-03 21:19   ` Armin Wolf
@ 2024-05-04  0:59     ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-04  0:59 UTC (permalink / raw)
  To: Armin Wolf
  Cc: mario.limonciello, pali, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel



On Fri, May 3 2024 at 11:19:07 PM +02:00:00, Armin Wolf 
<W_Armin@gmx.de> wrote:
> Am 01.05.24 um 23:58 schrieb Lyndon Sanche:
>> +static int thermal_init(void)
>> +{
>> +	int ret;
>> +	int supported_modes;
>> +
>> +	/* If thermal modes not supported, exit without error */
>> +	ret = thermal_get_supported_modes(&supported_modes);
>> +	if (ret < 0)
>> +		return ret;
> 
> Hi,
> 
> some older models might not support the USTT commands, which would 
> prevent dell-laptop
> from loading on such machines.
> Since dell-smbios-base already knows which commands are supported 
> (stored in da_supported_commands),
> maybe you can add a function for checking if a certain class of 
> commands is supported and
> skip thermal_init() if the USTT commands are not supported.
> 
> Thanks,
> Armin Wolf

This is a good idea, I will have a look at dell-smbios-base to see 
exactly how I can check for support. If support is not available, 
thermal_init will skip or return 0 (depending on where I put the check).

Thanks,

Lyndon



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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-03 10:19   ` kernel test robot
@ 2024-05-04  1:03     ` Lyndon Sanche
  2024-05-06 10:18       ` Hans de Goede
  0 siblings, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-04  1:03 UTC (permalink / raw)
  To: kernel test robot
  Cc: Paul Gazzillo, Necip Fazil Yildiran, oe-kbuild-all,
	mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, Hans de Goede, Matthew Garrett, Jonathan Corbet,
	Heiner Kallweit, Vegard Nossum, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On Fri, May 3 2024 at 06:19:18 PM +08:00:00, kernel test robot 
<lkp@intel.com> wrote:
> Hi Lyndon,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on linus/master]
> [also build test WARNING on v6.9-rc6 next-20240503]
> [If your patch is applied to the wrong git tree, kindly drop us a 
> note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    
> https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240502-060146
> base:   linus/master
> patch link:    
> https://lore.kernel.org/r/20240501215829.4991-2-lsanche%40lyndeno.ca
> patch subject: [PATCH v5] platform/x86: dell-laptop: Implement 
> platform_profile
> config: 
> i386-kismet-CONFIG_ACPI_PLATFORM_PROFILE-CONFIG_DELL_LAPTOP-0-0 
> (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/config)
> reproduce: 
> (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new 
> version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: 
> https://lore.kernel.org/oe-kbuild-all/202405031851.NYy0ZB02-lkp@intel.com/
> 
> kismet warnings: (new ones prefixed by >>)
>>>  kismet: WARNING: unmet direct dependencies detected for 
>>> ACPI_PLATFORM_PROFILE when selected by DELL_LAPTOP
>    WARNING: unmet direct dependencies detected for 
> ACPI_PLATFORM_PROFILE
>      Depends on [n]: ACPI [=n]
>      Selected by [y]:
>      - DELL_LAPTOP [=y] && X86_PLATFORM_DEVICES [=y] && 
> X86_PLATFORM_DRIVERS_DELL [=y] && DMI [=y] && BACKLIGHT_CLASS_DEVICE 
> [=y] && (ACPI_VIDEO [=n] || ACPI_VIDEO [=n]=n) && (RFKILL [=n] || 
> RFKILL [=n]=n) && (DELL_WMI [=n] || DELL_WMI [=n]=n) && SERIO_I8042 
> [=y] && DELL_SMBIOS [=y]
> 
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki

I will try reproducing this test on my machine, to avoid spamming the 
mailing list with the same error over and over.








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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-04  1:03     ` Lyndon Sanche
@ 2024-05-06 10:18       ` Hans de Goede
  2024-05-07 16:00         ` Lyndon Sanche
  0 siblings, 1 reply; 72+ messages in thread
From: Hans de Goede @ 2024-05-06 10:18 UTC (permalink / raw)
  To: Lyndon Sanche, kernel test robot
  Cc: Paul Gazzillo, Necip Fazil Yildiran, oe-kbuild-all,
	mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Hi Lyndon,

Thank you for your patch!

On 5/4/24 3:03 AM, Lyndon Sanche wrote:
> 
> 
> On Fri, May 3 2024 at 06:19:18 PM +08:00:00, kernel test robot <lkp@intel.com> wrote:
>> Hi Lyndon,
>>
>> kernel test robot noticed the following build warnings:
>>
>> [auto build test WARNING on linus/master]
>> [also build test WARNING on v6.9-rc6 next-20240503]
>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>> And when submitting patch, we suggest to use '--base' as documented in
>> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>>
>> url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240502-060146
>> base:   linus/master
>> patch link:    https://lore.kernel.org/r/20240501215829.4991-2-lsanche%40lyndeno.ca
>> patch subject: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>> config: i386-kismet-CONFIG_ACPI_PLATFORM_PROFILE-CONFIG_DELL_LAPTOP-0-0 (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/config)
>> reproduce: (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/reproduce)
>>
>> If you fix the issue in a separate patch/commit (i.e. not just a new version of
>> the same patch/commit), kindly add following tags
>> | Reported-by: kernel test robot <lkp@intel.com>
>> | Closes: https://lore.kernel.org/oe-kbuild-all/202405031851.NYy0ZB02-lkp@intel.com/
>>
>> kismet warnings: (new ones prefixed by >>)
>>>>  kismet: WARNING: unmet direct dependencies detected for ACPI_PLATFORM_PROFILE when selected by DELL_LAPTOP
>>    WARNING: unmet direct dependencies detected for ACPI_PLATFORM_PROFILE
>>      Depends on [n]: ACPI [=n]
>>      Selected by [y]:
>>      - DELL_LAPTOP [=y] && X86_PLATFORM_DEVICES [=y] && X86_PLATFORM_DRIVERS_DELL [=y] && DMI [=y] && BACKLIGHT_CLASS_DEVICE [=y] && (ACPI_VIDEO [=n] || ACPI_VIDEO [=n]=n) && (RFKILL [=n] || RFKILL [=n]=n) && (DELL_WMI [=n] || DELL_WMI [=n]=n) && SERIO_I8042 [=y] && DELL_SMBIOS [=y]
>>
>> -- 
>> 0-DAY CI Kernel Test Service
>> https://github.com/intel/lkp-tests/wiki
> 
> I will try reproducing this test on my machine, to avoid spamming the mailing list with the same error over and over.

No need to reproduce this. When you select something in Kconfig you must ensure
that the item doing the selecting depends on all the dependencies of what you
are selecting.

IOW if you add this change to your next version then that should fix this:

diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
index bd9f445974cc..d18fbc6a5fbf 100644
--- a/drivers/platform/x86/dell/Kconfig
+++ b/drivers/platform/x86/dell/Kconfig
@@ -47,6 +47,7 @@ config DCDBAS
 config DELL_LAPTOP
 	tristate "Dell Laptop Extras"
 	default m
+	depends on ACPI
 	depends on DMI
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on ACPI_VIDEO || ACPI_VIDEO = n

And please also address Armin's remark about making sure that failure
to initialize platform_profile support should not cause the entire driver
to fail to probe.

I see that Armin suggests to check da_supported_commands for this,
this is a good idea but atm this is private to dell-smbios-base. So
you will first need to do a small preparation patch adding a small:

bool dell_laptop_check_supported_cmds(struct calling_interface_buffer *buffer)
{
	return da_supported_commands & (1 << buffer->cmd_class);
}
EXPORT_SYMBOL_GPL(dell_laptop_check_supported_cmds):

helper for this.

If this check fails (returns false) make the code not register
the platform_profile() while allowing probe() to continue / succeed,
please do not log anything in this case (or use dev_dbg())

If this check succeeds but subsequent dell_smbios_call()'s
fail during probe, then it is ok to log an error but please
still let probe() continue / succeed (without registering
a platform_profile handler).

Regards,

Hans



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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-06 10:18       ` Hans de Goede
@ 2024-05-07 16:00         ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-07 16:00 UTC (permalink / raw)
  To: Hans de Goede
  Cc: kernel test robot, Paul Gazzillo, Necip Fazil Yildiran,
	oe-kbuild-all, mario.limonciello, pali, W_Armin,
	srinivas.pandruvada, ilpo.jarvinen, Matthew Garrett,
	Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel



On Mon, May 6 2024 at 12:18:05 PM +02:00:00, Hans de Goede 
<hdegoede@redhat.com> wrote:
> Hi Lyndon,
> 
> Thank you for your patch!
> 
> On 5/4/24 3:03 AM, Lyndon Sanche wrote:
>> 
>> 
>>  On Fri, May 3 2024 at 06:19:18 PM +08:00:00, kernel test robot 
>> <lkp@intel.com> wrote:
>>>  Hi Lyndon,
>>> 
>>>  kernel test robot noticed the following build warnings:
>>> 
>>>  [auto build test WARNING on linus/master]
>>>  [also build test WARNING on v6.9-rc6 next-20240503]
>>>  [If your patch is applied to the wrong git tree, kindly drop us a 
>>> note.
>>>  And when submitting patch, we suggest to use '--base' as 
>>> documented in
>>>  https://git-scm.com/docs/git-format-patch#_base_tree_information]
>>> 
>>>  url:    
>>> https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240502-060146
>>>  base:   linus/master
>>>  patch link:    
>>> https://lore.kernel.org/r/20240501215829.4991-2-lsanche%40lyndeno.ca
>>>  patch subject: [PATCH v5] platform/x86: dell-laptop: Implement 
>>> platform_profile
>>>  config: 
>>> i386-kismet-CONFIG_ACPI_PLATFORM_PROFILE-CONFIG_DELL_LAPTOP-0-0 
>>> (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/config)
>>>  reproduce: 
>>> (https://download.01.org/0day-ci/archive/20240503/202405031851.NYy0ZB02-lkp@intel.com/reproduce)
>>> 
>>>  If you fix the issue in a separate patch/commit (i.e. not just a 
>>> new version of
>>>  the same patch/commit), kindly add following tags
>>>  | Reported-by: kernel test robot <lkp@intel.com>
>>>  | Closes: 
>>> https://lore.kernel.org/oe-kbuild-all/202405031851.NYy0ZB02-lkp@intel.com/
>>> 
>>>  kismet warnings: (new ones prefixed by >>)
>>>>>   kismet: WARNING: unmet direct dependencies detected for 
>>>>> ACPI_PLATFORM_PROFILE when selected by DELL_LAPTOP
>>>     WARNING: unmet direct dependencies detected for 
>>> ACPI_PLATFORM_PROFILE
>>>       Depends on [n]: ACPI [=n]
>>>       Selected by [y]:
>>>       - DELL_LAPTOP [=y] && X86_PLATFORM_DEVICES [=y] && 
>>> X86_PLATFORM_DRIVERS_DELL [=y] && DMI [=y] && 
>>> BACKLIGHT_CLASS_DEVICE [=y] && (ACPI_VIDEO [=n] || ACPI_VIDEO 
>>> [=n]=n) && (RFKILL [=n] || RFKILL [=n]=n) && (DELL_WMI [=n] || 
>>> DELL_WMI [=n]=n) && SERIO_I8042 [=y] && DELL_SMBIOS [=y]
>>> 
>>>  --
>>>  0-DAY CI Kernel Test Service
>>>  https://github.com/intel/lkp-tests/wiki
>> 
>>  I will try reproducing this test on my machine, to avoid spamming 
>> the mailing list with the same error over and over.
> 
> No need to reproduce this. When you select something in Kconfig you 
> must ensure
> that the item doing the selecting depends on all the dependencies of 
> what you
> are selecting.
> 
> IOW if you add this change to your next version then that should fix 
> this:
> 
> diff --git a/drivers/platform/x86/dell/Kconfig 
> b/drivers/platform/x86/dell/Kconfig
> index bd9f445974cc..d18fbc6a5fbf 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -47,6 +47,7 @@ config DCDBAS
>  config DELL_LAPTOP
>  	tristate "Dell Laptop Extras"
>  	default m
> +	depends on ACPI
>  	depends on DMI
>  	depends on BACKLIGHT_CLASS_DEVICE
>  	depends on ACPI_VIDEO || ACPI_VIDEO = n
> 
> And please also address Armin's remark about making sure that failure
> to initialize platform_profile support should not cause the entire 
> driver
> to fail to probe.
> 
> I see that Armin suggests to check da_supported_commands for this,
> this is a good idea but atm this is private to dell-smbios-base. So
> you will first need to do a small preparation patch adding a small:
> 
> bool dell_laptop_check_supported_cmds(struct calling_interface_buffer 
> *buffer)
> {
> 	return da_supported_commands & (1 << buffer->cmd_class);
> }
> EXPORT_SYMBOL_GPL(dell_laptop_check_supported_cmds):
> 
> helper for this.
> 
> If this check fails (returns false) make the code not register
> the platform_profile() while allowing probe() to continue / succeed,
> please do not log anything in this case (or use dev_dbg())
> 
> If this check succeeds but subsequent dell_smbios_call()'s
> fail during probe, then it is ok to log an error but please
> still let probe() continue / succeed (without registering
> a platform_profile handler).
> 
> Regards,
> 
> Hans
> 
> 
Hello Hans:

Thank you very much for your feedback and suggestions! I have been busy 
the past few days, but will be able to tackle this this week. These are 
good ideas which I plan to implement.

Thank you,

Lyndon



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

* RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-01 21:58 ` [PATCH v5] " Lyndon Sanche
  2024-05-03 10:19   ` kernel test robot
  2024-05-03 21:19   ` Armin Wolf
@ 2024-05-08 14:24   ` Shen, Yijun
  2024-05-08 15:53     ` Mario Limonciello
  2024-05-09 15:10     ` Lyndon Sanche
  2 siblings, 2 replies; 72+ messages in thread
From: Shen, Yijun @ 2024-05-08 14:24 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, Hans de Goede, Matthew Garrett,
	Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell Client Kernel

Hi Lyndon,

 Thanks for working on this patch.


Internal Use - Confidential
> -----Original Message-----
> From: Lyndon Sanche <lsanche@lyndeno.ca>
> Sent: Thursday, May 2, 2024 5:58 AM
> To: lsanche@lyndeno.ca
> Cc: mario.limonciello@amd.com; pali@kernel.org; W_Armin@gmx.de;
> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
> Kernel <Dell.Client.Kernel@dell.com>
> Subject: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>
>
> [EXTERNAL EMAIL]
>
> Some Dell laptops support configuration of preset fan modes through smbios
> tables.
>
> If the platform supports these fan modes, set up platform_profile to change
> these modes. If not supported, skip enabling platform_profile.
>
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
> v5:
>  - Fix indent in smbios-thermal-ctl comment
>  - Remove linux/wmi.h include
>  - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
> v4:
>  - Make thermal_init and thermal_cleanup static
>  - Rearrange order of added includes, did not edit current includes
>  - Include bits.h
>  - Switch comment style
>  - Return error if platform_profile registering failed
>  - Add thermal calls to call_blacklist
>  - Align defines with tabs
>  - Correct separation of function and error handling
>  - Propagate error codes up
> v3:
>  - Convert smbios-thermal-ctl docs to multiline comment and wrap
>  - Change thermal_mode_bits enum to directly be BIT() values
>       - Convert related code to use this
>  - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
>       - Correct offset for getting current ACC mode, setting offset
>               unchanged
>  - Check if thermal_handler is allocated before freeing and
>        unregistering platform_profile
> v2:
>  - Wrap smbios-thermal-ctl comment
>  - Return proper error code when invalid state returned
>  - Simplify platform_profile_get returns
>  - Propogate ENOMEM error
> ---

 Dell side has an initial testing with this patch on some laptops, it looks good. While changing the platform profile:
1. The corresponding USTT option in BIOS will be changed.
2. thermald will not be impacted. The related PSVT and ITMT will be loaded.
 Some Dell DTs does not have the USTT, Dell'll have a check if nothing is broken.

  Additional, with this patch, follow behavior is found:
 1. For example, the platform profile is quiet.
 2. Reboot the system and change the USTT to performance.
 3. Boot to desktop, the platform profile is "quiet", the USTT will be changed back to "quiet".
 This looks like not a proper user experience. The platform profile should honor the BIOS setting, aka, the platform profile should be switched to "performance".

>  drivers/platform/x86/dell/Kconfig            |   1 +
>  drivers/platform/x86/dell/dell-laptop.c      | 238 +++++++++++++++++++
>  drivers/platform/x86/dell/dell-smbios-base.c |   1 +
>  drivers/platform/x86/dell/dell-smbios.h      |   1 +
>  4 files changed, 241 insertions(+)
>
> diff --git a/drivers/platform/x86/dell/Kconfig
> b/drivers/platform/x86/dell/Kconfig
> index bd9f445974cc..5195ad59b44d 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -57,6 +57,7 @@ config DELL_LAPTOP
>       select POWER_SUPPLY
>       select LEDS_CLASS
>       select NEW_LEDS
> +     select ACPI_PLATFORM_PROFILE
>       help
>       This driver adds support for rfkill and backlight control to Dell
>       laptops (except for some models covered by the Compal driver).
> diff --git a/drivers/platform/x86/dell/dell-laptop.c
> b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..dc530a4f5047 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,9 @@
>  #include <linux/i8042.h>
>  #include <linux/debugfs.h>
>  #include <linux/seq_file.h>
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/platform_profile.h>
>  #include <acpi/video.h>
>  #include "dell-rbtn.h"
>  #include "dell-smbios.h"
> @@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
> static struct rfkill *wifi_rfkill;  static struct rfkill *bluetooth_rfkill;  static struct
> rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>  static bool force_rfkill;
>  static bool micmute_led_registered;
>  static bool mute_led_registered;
> @@ -2199,6 +2203,232 @@ static int mute_led_set(struct led_classdev
> *led_cdev,
>       return 0;
>  }
>
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is
> supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC)
> modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT
> modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be
> set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *
> + * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> + *               desired AAC mode shall be applied
> + * cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD           GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD           GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED       GENMASK(3, 0)
> +
> +enum thermal_mode_bits {
> +     DELL_BALANCED = BIT(0),
> +     DELL_COOL_BOTTOM = BIT(1),
> +     DELL_QUIET = BIT(2),
> +     DELL_PERFORMANCE = BIT(3),
> +};
> +
> +static int thermal_get_mode(void)
> +{
> +     struct calling_interface_buffer buffer;
> +     int state;
> +     int ret;
> +
> +     dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +     ret = dell_send_request(&buffer, CLASS_INFO,
> SELECT_THERMAL_MANAGEMENT);
> +     if (ret)
> +             return ret;
> +     state = buffer.output[2];
> +     if (state & DELL_BALANCED)
> +             return DELL_BALANCED;
> +     else if (state & DELL_COOL_BOTTOM)
> +             return DELL_COOL_BOTTOM;
> +     else if (state & DELL_QUIET)
> +             return DELL_QUIET;
> +     else if (state & DELL_PERFORMANCE)
> +             return DELL_PERFORMANCE;
> +     else
> +             return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits) {
> +     struct calling_interface_buffer buffer;
> +     int ret;
> +
> +     dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +     ret = dell_send_request(&buffer, CLASS_INFO,
> SELECT_THERMAL_MANAGEMENT);
> +     if (ret)
> +             return ret;
> +     *supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED,
> buffer.output[1]);
> +     return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode) {
> +     struct calling_interface_buffer buffer;
> +     int ret;
> +
> +     dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +     ret = dell_send_request(&buffer, CLASS_INFO,
> SELECT_THERMAL_MANAGEMENT);
> +     if (ret)
> +             return ret;
> +     *acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +     return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state) {
> +     struct calling_interface_buffer buffer;
> +     int ret;
> +     int acc_mode;
> +
> +     ret = thermal_get_acc_mode(&acc_mode);
> +     if (ret)
> +             return ret;
> +
> +     dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD,
> acc_mode) | state, 0, 0);
> +     ret = dell_send_request(&buffer, CLASS_INFO,
> SELECT_THERMAL_MANAGEMENT);
> +     return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler
> *pprof,
> +                                     enum platform_profile_option
> profile) {
> +     switch (profile) {
> +     case PLATFORM_PROFILE_BALANCED:
> +             return thermal_set_mode(DELL_BALANCED);
> +     case PLATFORM_PROFILE_PERFORMANCE:
> +             return thermal_set_mode(DELL_PERFORMANCE);
> +     case PLATFORM_PROFILE_QUIET:
> +             return thermal_set_mode(DELL_QUIET);
> +     case PLATFORM_PROFILE_COOL:
> +             return thermal_set_mode(DELL_COOL_BOTTOM);
> +     default:
> +             return -EOPNOTSUPP;
> +     }
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler
> *pprof,
> +                                     enum platform_profile_option
> *profile) {
> +     int ret;
> +
> +     ret = thermal_get_mode();
> +     if (ret < 0)
> +             return ret;
> +
> +     switch (ret) {
> +     case DELL_BALANCED:
> +             *profile = PLATFORM_PROFILE_BALANCED;
> +             break;
> +     case DELL_PERFORMANCE:
> +             *profile = PLATFORM_PROFILE_PERFORMANCE;
> +             break;
> +     case DELL_COOL_BOTTOM:
> +             *profile = PLATFORM_PROFILE_COOL;
> +             break;
> +     case DELL_QUIET:
> +             *profile = PLATFORM_PROFILE_QUIET;
> +             break;
> +     default:
> +             return -EINVAL;
> +     }
> +
> +     return 0;
> +}
> +
> +static int thermal_init(void)
> +{
> +     int ret;
> +     int supported_modes;
> +
> +     /* If thermal modes not supported, exit without error */
> +     ret = thermal_get_supported_modes(&supported_modes);
> +     if (ret < 0)
> +             return ret;
> +     if (!supported_modes)
> +             return 0;
> +
> +     thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +     if (!thermal_handler)
> +             return -ENOMEM;
> +     thermal_handler->profile_get = thermal_platform_profile_get;
> +     thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +     if (supported_modes & DELL_QUIET)
> +             set_bit(PLATFORM_PROFILE_QUIET, thermal_handler-
> >choices);
> +     if (supported_modes & DELL_COOL_BOTTOM)
> +             set_bit(PLATFORM_PROFILE_COOL, thermal_handler-
> >choices);
> +     if (supported_modes & DELL_BALANCED)
> +             set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler-
> >choices);
> +     if (supported_modes & DELL_PERFORMANCE)
> +             set_bit(PLATFORM_PROFILE_PERFORMANCE,
> thermal_handler->choices);
> +
> +     /* Clean up if failed */
> +     ret = platform_profile_register(thermal_handler);
> +     if (ret)
> +             kfree(thermal_handler);
> +
> +     return ret;
> +}
> +
> +static void thermal_cleanup(void)
> +{
> +     if (thermal_handler) {
> +             platform_profile_remove();
> +             kfree(thermal_handler);
> +     }
> +}
> +
>  static struct led_classdev mute_led_cdev = {
>       .name = "platform::mute",
>       .max_brightness = 1,
> @@ -2238,6 +2468,11 @@ static int __init dell_init(void)
>               goto fail_rfkill;
>       }
>
> +     /* Do not fail module if thermal modes not supported, just skip */
> +     ret = thermal_init();
> +     if (ret)
> +             goto fail_thermal;
> +
>       if (quirks && quirks->touchpad_led)
>               touchpad_led_init(&platform_device->dev);
>
> @@ -2317,6 +2552,8 @@ static int __init dell_init(void)
>               led_classdev_unregister(&mute_led_cdev);
>  fail_led:
>       dell_cleanup_rfkill();
> +fail_thermal:
> +     thermal_cleanup();
>  fail_rfkill:
>       platform_device_del(platform_device);
>  fail_platform_device2:
> @@ -2344,6 +2581,7 @@ static void __exit dell_exit(void)
>               platform_device_unregister(platform_device);
>               platform_driver_unregister(&platform_driver);
>       }
> +     thermal_cleanup();
>  }
>
>  /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c
> b/drivers/platform/x86/dell/dell-smbios-base.c
> index e61bfaf8b5c4..5bc2e394dd1c 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
>       /* handled by kernel: dell-laptop */
>       {0x0000, CLASS_INFO, SELECT_RFKILL},
>       {0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
> +     {0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>  };
>
>  struct token_range {
> diff --git a/drivers/platform/x86/dell/dell-smbios.h
> b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..585d042f1779 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>  /* Classes and selects used only in kernel drivers */  #define
> CLASS_KBD_BACKLIGHT 4  #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>
>  /* Tokens used in kernel drivers, any of these
>   * should be filtered from userspace access
> --
> 2.42.0


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

* Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-08 14:24   ` Shen, Yijun
@ 2024-05-08 15:53     ` Mario Limonciello
  2024-05-11 15:05       ` Shen, Yijun
  2024-05-09 15:10     ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: Mario Limonciello @ 2024-05-08 15:53 UTC (permalink / raw)
  To: Shen, Yijun, Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell Client Kernel

On 5/8/2024 09:24, Shen, Yijun wrote:
> Hi Lyndon,
> 
>   Thanks for working on this patch.
> 
>>
>   Dell side has an initial testing with this patch on some laptops, it looks good. While changing the platform profile:
> 1. The corresponding USTT option in BIOS will be changed.
> 2. thermald will not be impacted. The related PSVT and ITMT will be loaded.
>   Some Dell DTs does not have the USTT, Dell'll have a check if nothing is broken.

Hi Alex!

Have you had a check both on both your AMD laptops and workstations too, 
or just the Intel ones?  I think it would be good to make sure it's 
getting the correct experience in both cases.

> 
>    Additional, with this patch, follow behavior is found:
>   1. For example, the platform profile is quiet.
>   2. Reboot the system and change the USTT to performance.
>   3. Boot to desktop, the platform profile is "quiet", the USTT will be changed back to "quiet".
>   This looks like not a proper user experience. The platform profile should honor the BIOS setting, aka, the platform profile should be switched to "performance".
> 

I agree, this sounds like the initial profile needs to be read from the 
BIOS settings too.

Furthermore I wanted to ask is there also a WMI setting that corresponds 
to this that dell-wmi-sysman offers?  I'm wondering if both should be 
probed in case the SMBIOS one goes away one day.  Or should that one 
just be used as preference?

It seems like maybe ThermalManagement corresponds.  There was some test 
data in fwupd for it:

https://github.com/fwupd/fwupd/tree/main/libfwupdplugin/tests/bios-attrs/dell-xps13-9310/dell-wmi-sysman/attributes/ThermalManagement

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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-08 14:24   ` Shen, Yijun
  2024-05-08 15:53     ` Mario Limonciello
@ 2024-05-09 15:10     ` Lyndon Sanche
  2024-05-11  1:49       ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-09 15:10 UTC (permalink / raw)
  To: Shen, Yijun
  Cc: Mario Limonciello, Pali Rohár, Armin Wolf,
	srinivas.pandruvada, Ilpo Järvinen, kernel test robot,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, LKML, Dell Client Kernel

On Wed, May 8, 2024, at 8:24 AM, Shen, Yijun wrote:
> Hi Lyndon,
>
>  Thanks for working on this patch.
>
>
> Internal Use - Confidential
>> -----Original Message-----
>> From: Lyndon Sanche <lsanche@lyndeno.ca>
>> Sent: Thursday, May 2, 2024 5:58 AM
>> To: lsanche@lyndeno.ca
>> Cc: mario.limonciello@amd.com; pali@kernel.org; W_Armin@gmx.de;
>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
>> Kernel <Dell.Client.Kernel@dell.com>
>> Subject: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>>
>>
>> [EXTERNAL EMAIL]
>>
>> Some Dell laptops support configuration of preset fan modes through smbios
>> tables.
>>
>> If the platform supports these fan modes, set up platform_profile to change
>> these modes. If not supported, skip enabling platform_profile.
>>
>> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>> ---
>> v5:
>>  - Fix indent in smbios-thermal-ctl comment
>>  - Remove linux/wmi.h include
>>  - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
>> v4:
>>  - Make thermal_init and thermal_cleanup static
>>  - Rearrange order of added includes, did not edit current includes
>>  - Include bits.h
>>  - Switch comment style
>>  - Return error if platform_profile registering failed
>>  - Add thermal calls to call_blacklist
>>  - Align defines with tabs
>>  - Correct separation of function and error handling
>>  - Propagate error codes up
>> v3:
>>  - Convert smbios-thermal-ctl docs to multiline comment and wrap
>>  - Change thermal_mode_bits enum to directly be BIT() values
>>       - Convert related code to use this
>>  - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
>>       - Correct offset for getting current ACC mode, setting offset
>>               unchanged
>>  - Check if thermal_handler is allocated before freeing and
>>        unregistering platform_profile
>> v2:
>>  - Wrap smbios-thermal-ctl comment
>>  - Return proper error code when invalid state returned
>>  - Simplify platform_profile_get returns
>>  - Propogate ENOMEM error
>> ---
>
>  Dell side has an initial testing with this patch on some laptops, it 
> looks good. While changing the platform profile:
> 1. The corresponding USTT option in BIOS will be changed.
> 2. thermald will not be impacted. The related PSVT and ITMT will be 
> loaded.
>  Some Dell DTs does not have the USTT, Dell'll have a check if nothing 
> is broken.
>
>   Additional, with this patch, follow behavior is found:
>  1. For example, the platform profile is quiet.
>  2. Reboot the system and change the USTT to performance.
>  3. Boot to desktop, the platform profile is "quiet", the USTT will be 
> changed back to "quiet".
>  This looks like not a proper user experience. The platform profile 
> should honor the BIOS setting, aka, the platform profile should be 
> switched to "performance".

Hello:

Thank you for your email. This is definitely undesirable behaviour, I will have a look at the code to see why this is happening. Does it always revert to quiet on boot, or always the mode that you had switched to prior to reboot?

Do you happen to have power-profiles-daemon or something similar running? My understanding is it remembers profiles across reboots, this could potentially also revert the profile back to what it was. See this release for details:
https://gitlab.freedesktop.org/upower/power-profiles-daemon/-/releases/0.9.0

I will assume there is a bug in my code at this point. I will test with and without ppd running on my system to see if it changes across reboots.

Are USTT settings exposed in your BIOS configuration menu? On my laptop they are not and I have to use smbios-thermal-ctl.

Thank you,

Lyndon

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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-09 15:10     ` Lyndon Sanche
@ 2024-05-11  1:49       ` Lyndon Sanche
  2024-05-11 15:22         ` Shen, Yijun
  0 siblings, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11  1:49 UTC (permalink / raw)
  To: Shen, Yijun
  Cc: Mario Limonciello, Pali Rohár, Armin Wolf,
	srinivas.pandruvada, Ilpo Järvinen, kernel test robot,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, LKML, Dell Client Kernel



On Thu, May 9 2024 at 09:10:51 AM -06:00:00, Lyndon Sanche 
<lsanche@lyndeno.ca> wrote:
> On Wed, May 8, 2024, at 8:24 AM, Shen, Yijun wrote:
>>  Hi Lyndon,
>> 
>>   Thanks for working on this patch.
>> 
>> 
>>   Dell side has an initial testing with this patch on some laptops, 
>> it
>>  looks good. While changing the platform profile:
>>  1. The corresponding USTT option in BIOS will be changed.
>>  2. thermald will not be impacted. The related PSVT and ITMT will be
>>  loaded.
>>   Some Dell DTs does not have the USTT, Dell'll have a check if 
>> nothing
>>  is broken.
>> 
>>    Additional, with this patch, follow behavior is found:
>>   1. For example, the platform profile is quiet.
>>   2. Reboot the system and change the USTT to performance.
>>   3. Boot to desktop, the platform profile is "quiet", the USTT will 
>> be
>>  changed back to "quiet".
>>   This looks like not a proper user experience. The platform profile
>>  should honor the BIOS setting, aka, the platform profile should be
>>  switched to "performance".
> 
> Hello:
> 
> Thank you for your email. This is definitely undesirable behaviour, I 
> will have a look at the code to see why this is happening. Does it 
> always revert to quiet on boot, or always the mode that you had 
> switched to prior to reboot?
> 
> Do you happen to have power-profiles-daemon or something similar 
> running? My understanding is it remembers profiles across reboots, 
> this could potentially also revert the profile back to what it was. 
> See this release for details:
> https://gitlab.freedesktop.org/upower/power-profiles-daemon/-/releases/0.9.0
> 
> I will assume there is a bug in my code at this point. I will test 
> with and without ppd running on my system to see if it changes across 
> reboots.
> 
> Are USTT settings exposed in your BIOS configuration menu? On my 
> laptop they are not and I have to use smbios-thermal-ctl.
> 
> Thank you,
> 
> Lyndon

Hi Yijun:

I tested this on my computer (XPS 9560). I do not have access to the 
USTT settings in the BIOS screen so to substitute that, I booted 
without the patch and set the USTT manually using smbios-thermal-ctl. 
Here are my findings:

Scenario #1: Without power-profiles-daemon (ppd) running

1. Boot with patch, set platform_profile to quiet
2. Boot without patch applied (no platform_profile)
 - smbios-thermal-ctl confirms USTT is set to quiet
 - use smbios-thermal-ctl to set USTT to performance
 - confirm set to performance
3. Boot with patch again
 - platform_profile is set to performance

Scenario #2: With ppd running
1. Boot with patch, set platform_profile to performance with ppd
 - Confirm platform_profile is performance
2. Boot without patch applied (no platform_profile)
 - smbios-thermal-ctl confirms USTT is set to performance
 - ppd reverts to balanced (only controlling intel_pstate in this case)
 - use smbios-thermal-ctl to set USTT to quiet
 - confirm set to quiet
3. Boot with patch again
 - platform_profile and ppd is set to performance

In my case, the setting in the smbios is honored if it was switched 
with another method. When using a userspace program that manipulates 
the platform_profile, the program seems to remember the previous state 
and switch to that.

So I do not think there is a bug in this patch related to this issue, 
at least in my case. Please let me know if you have any questions.

Thanks,

Lyndon





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

* [PATCH v6 0/2] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (7 preceding siblings ...)
  2024-05-01 21:58 ` [PATCH v5] " Lyndon Sanche
@ 2024-05-11  2:36 ` Lyndon Sanche
  2024-05-11  2:36 ` [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands Lyndon Sanche
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11  2:36 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Heiner Kallweit, Vegard Nossum, Jonathan Corbet,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Some Dell laptops support configuration of preset fan modes through
smbios tables.

If the platform supports these fan modes, set up platform_profile to
change these modes. If not supported, skip enabling platform_profile.

v6:
 - Add ACPI dependency for dell-laptop
 - Add and use helper symbol for checking supported commands
v5:
 - Fix indent in smbios-thermal-ctl comment
 - Remove linux/wmi.h include
 - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
v4:
 - Make thermal_init and thermal_cleanup static
 - Rearrange order of added includes, did not edit current includes
 - Include bits.h
 - Switch comment style
 - Return error if platform_profile registering failed
 - Add thermal calls to call_blacklist
 - Align defines with tabs
 - Correct separation of function and error handling
 - Propagate error codes up
v3:
 - Convert smbios-thermal-ctl docs to multiline comment and wrap
 - Change thermal_mode_bits enum to directly be BIT() values
	- Convert related code to use this
 - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
	- Correct offset for getting current ACC mode, setting offset
		unchanged
 - Check if thermal_handler is allocated before freeing and
	 unregistering platform_profile
v2:
 - Wrap smbios-thermal-ctl comment
 - Return proper error code when invalid state returned
 - Simplify platform_profile_get returns
 - Propogate ENOMEM error

Lyndon Sanche (2):
  platform/x86: dell-smbios: Add helper for checking supported commands
  platform/x86: dell-laptop: Implement platform_profile

 drivers/platform/x86/dell/Kconfig            |   2 +
 drivers/platform/x86/dell/dell-laptop.c      | 242 +++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios-base.c |   7 +
 drivers/platform/x86/dell/dell-smbios.h      |   2 +
 4 files changed, 253 insertions(+)

-- 
2.42.0


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

* [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (8 preceding siblings ...)
  2024-05-11  2:36 ` [PATCH v6 0/2] " Lyndon Sanche
@ 2024-05-11  2:36 ` Lyndon Sanche
  2024-05-11 15:13   ` Limonciello, Mario
  2024-05-12 18:00   ` Armin Wolf
  2024-05-11  2:36 ` [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
  2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
  11 siblings, 2 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11  2:36 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Heiner Kallweit, Randy Dunlap, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Add symbol to check if a specific class of smbios command is supported.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 drivers/platform/x86/dell/dell-smbios-base.c | 6 ++++++
 drivers/platform/x86/dell/dell-smbios.h      | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index e61bfaf8b5c4..6ae09d7f76fb 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -350,6 +350,12 @@ void dell_laptop_call_notifier(unsigned long action, void *data)
 }
 EXPORT_SYMBOL_GPL(dell_laptop_call_notifier);
 
+bool dell_laptop_check_supported_cmds(u16 class)
+{
+	return da_supported_commands & (1 << class);
+}
+EXPORT_SYMBOL_GPL(dell_laptop_check_supported_cmds);
+
 static void __init parse_da_table(const struct dmi_header *dm)
 {
 	/* Final token is a terminator, so we don't want to copy it */
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..63116671eada 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -73,6 +73,7 @@ enum dell_laptop_notifier_actions {
 int dell_laptop_register_notifier(struct notifier_block *nb);
 int dell_laptop_unregister_notifier(struct notifier_block *nb);
 void dell_laptop_call_notifier(unsigned long action, void *data);
+bool dell_laptop_check_supported_cmds(u16 class);
 
 /* for the supported backends */
 #ifdef CONFIG_DELL_SMBIOS_WMI
-- 
2.42.0


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

* [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (9 preceding siblings ...)
  2024-05-11  2:36 ` [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands Lyndon Sanche
@ 2024-05-11  2:36 ` Lyndon Sanche
  2024-05-11 15:16   ` Limonciello, Mario
  2024-05-12 18:05   ` Armin Wolf
  2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
  11 siblings, 2 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11  2:36 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Heiner Kallweit, Randy Dunlap, Jonathan Corbet, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Some Dell laptops support configuration of preset fan modes through
smbios tables.

If the platform supports these fan modes, set up platform_profile to
change these modes. If not supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 drivers/platform/x86/dell/Kconfig            |   2 +
 drivers/platform/x86/dell/dell-laptop.c      | 242 +++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios-base.c |   1 +
 drivers/platform/x86/dell/dell-smbios.h      |   1 +
 4 files changed, 246 insertions(+)

diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
index bd9f445974cc..26679f22733c 100644
--- a/drivers/platform/x86/dell/Kconfig
+++ b/drivers/platform/x86/dell/Kconfig
@@ -47,6 +47,7 @@ config DCDBAS
 config DELL_LAPTOP
 	tristate "Dell Laptop Extras"
 	default m
+	depends on ACPI
 	depends on DMI
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on ACPI_VIDEO || ACPI_VIDEO = n
@@ -57,6 +58,7 @@ config DELL_LAPTOP
 	select POWER_SUPPLY
 	select LEDS_CLASS
 	select NEW_LEDS
+	select ACPI_PLATFORM_PROFILE
 	help
 	This driver adds support for rfkill and backlight control to Dell
 	laptops (except for some models covered by the Compal driver).
diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..07f54f1cbac5 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -27,6 +27,9 @@
 #include <linux/i8042.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/platform_profile.h>
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
@@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct platform_profile_handler *thermal_handler;
 static bool force_rfkill;
 static bool micmute_led_registered;
 static bool mute_led_registered;
@@ -2199,6 +2203,236 @@ static int mute_led_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
+/* Derived from smbios-thermal-ctl
+ *
+ * cbClass 17
+ * cbSelect 19
+ * User Selectable Thermal Tables(USTT)
+ * cbArg1 determines the function to be performed
+ * cbArg1 0x0 = Get Thermal Information
+ *  cbRES1         Standard return codes (0, -1, -2)
+ *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
+ *                  its bit is set to 1
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
+ *                 Each mode corresponds to the supported thermal modes in
+ *                  byte 0. A mode is supported if its bit is set to 1.
+ *     Bit 0 AAC (Balanced)
+ *     Bit 1 AAC (Cool Bottom
+ *     Bit 2 AAC (Quiet)
+ *     Bit 3 AAC (Performance)
+ *  cbRes3, byte 0 Current Thermal Mode
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performanc
+ *  cbRes3, byte 1  AAC Configuration type
+ *          0       Global (AAC enable/disable applies to all supported USTT modes)
+ *          1       USTT mode specific
+ *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+ *     If AAC Configuration Type is Global,
+ *          0       AAC mode disabled
+ *          1       AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+ *          Bit 0 AAC (Balanced)
+ *          Bit 1 AAC (Cool Bottom
+ *          Bit 2 AAC (Quiet)
+ *          Bit 3 AAC (Performance)
+ *  cbRes3, byte 3  Current Fan Failure Mode
+ *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+ *     Bit 1 Catastrophic Fan Failure (all fans have failed)
+ *
+ * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+ *               desired AAC mode shall be applied
+ * cbArg2, byte 0  Desired Thermal Mode to set
+ *                  (only one bit may be set for this parameter)
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+ *     If AAC Configuration Type is Global,
+ *         0  AAC mode disabled
+ *         1  AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific
+ *     (multiple bits may be set for this parameter),
+ *         Bit 0 AAC (Balanced)
+ *         Bit 1 AAC (Cool Bottom
+ *         Bit 2 AAC (Quiet)
+ *         Bit 3 AAC (Performance)
+ */
+
+#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
+#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
+#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
+
+enum thermal_mode_bits {
+	DELL_BALANCED = BIT(0),
+	DELL_COOL_BOTTOM = BIT(1),
+	DELL_QUIET = BIT(2),
+	DELL_PERFORMANCE = BIT(3),
+};
+
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if (state & DELL_BALANCED)
+		return DELL_BALANCED;
+	else if (state & DELL_COOL_BOTTOM)
+		return DELL_COOL_BOTTOM;
+	else if (state & DELL_QUIET)
+		return DELL_QUIET;
+	else if (state & DELL_PERFORMANCE)
+		return DELL_PERFORMANCE;
+	else
+		return -ENXIO;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		return thermal_set_mode(DELL_BALANCED);
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return thermal_set_mode(DELL_PERFORMANCE);
+	case PLATFORM_PROFILE_QUIET:
+		return thermal_set_mode(DELL_QUIET);
+	case PLATFORM_PROFILE_COOL:
+		return thermal_set_mode(DELL_COOL_BOTTOM);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	int ret;
+
+	ret = thermal_get_mode();
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	/* If thermal commands not supported, exit without error */
+	if (!dell_laptop_check_supported_cmds(CLASS_INFO))
+		return 0;
+
+	/* If thermal modes not supported, exit without error */
+	ret = thermal_get_supported_modes(&supported_modes);
+	if (ret < 0)
+		return ret;
+	if (!supported_modes)
+		return 0;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if (supported_modes & DELL_QUIET)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if (supported_modes & DELL_COOL_BOTTOM)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if (supported_modes & DELL_BALANCED)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if (supported_modes & DELL_PERFORMANCE)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	/* Clean up if failed */
+	ret = platform_profile_register(thermal_handler);
+	if (ret)
+		kfree(thermal_handler);
+
+	return ret;
+}
+
+static void thermal_cleanup(void)
+{
+	if (thermal_handler) {
+		platform_profile_remove();
+		kfree(thermal_handler);
+	}
+}
+
 static struct led_classdev mute_led_cdev = {
 	.name = "platform::mute",
 	.max_brightness = 1,
@@ -2238,6 +2472,11 @@ static int __init dell_init(void)
 		goto fail_rfkill;
 	}
 
+	/* Do not fail module if thermal modes not supported, just skip */
+	ret = thermal_init();
+	if (ret)
+		goto fail_thermal;
+
 	if (quirks && quirks->touchpad_led)
 		touchpad_led_init(&platform_device->dev);
 
@@ -2317,6 +2556,8 @@ static int __init dell_init(void)
 		led_classdev_unregister(&mute_led_cdev);
 fail_led:
 	dell_cleanup_rfkill();
+fail_thermal:
+	thermal_cleanup();
 fail_rfkill:
 	platform_device_del(platform_device);
 fail_platform_device2:
@@ -2344,6 +2585,7 @@ static void __exit dell_exit(void)
 		platform_device_unregister(platform_device);
 		platform_driver_unregister(&platform_driver);
 	}
+	thermal_cleanup();
 }
 
 /* dell-rbtn.c driver export functions which will not work correctly (and could
diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index 6ae09d7f76fb..387fa5618f7a 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
 	/* handled by kernel: dell-laptop */
 	{0x0000, CLASS_INFO, SELECT_RFKILL},
 	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
+	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
 };
 
 struct token_range {
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index 63116671eada..5d7178df80c6 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* RE: RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-08 15:53     ` Mario Limonciello
@ 2024-05-11 15:05       ` Shen, Yijun
  2024-05-11 15:12         ` Limonciello, Mario
  2024-05-11 16:02         ` Lyndon Sanche
  0 siblings, 2 replies; 72+ messages in thread
From: Shen, Yijun @ 2024-05-11 15:05 UTC (permalink / raw)
  To: Mario Limonciello, Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell Client Kernel


Internal Use - Confidential
> -----Original Message-----
> From: Mario Limonciello <mario.limonciello@amd.com>
> Sent: Wednesday, May 8, 2024 11:53 PM
> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
> <lsanche@lyndeno.ca>
> Cc: pali@kernel.org; W_Armin@gmx.de;
> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
> Kernel <Dell.Client.Kernel@dell.com>
> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
> platform_profile
>
>
> [EXTERNAL EMAIL]
>
> On 5/8/2024 09:24, Shen, Yijun wrote:
> > Hi Lyndon,
> >
> >   Thanks for working on this patch.
> >
> >>
> >   Dell side has an initial testing with this patch on some laptops, it looks
> good. While changing the platform profile:
> > 1. The corresponding USTT option in BIOS will be changed.
> > 2. thermald will not be impacted. The related PSVT and ITMT will be loaded.
> >   Some Dell DTs does not have the USTT, Dell'll have a check if nothing is
> broken.
>
> Hi Alex!
>
> Have you had a check both on both your AMD laptops and workstations too,
> or just the Intel ones?  I think it would be good to make sure it's getting the
> correct experience in both cases.
>
Hi Mario,

 I've a check for this, for both laptop and workstation, the dell_laptop module will not be loaded. So, AMD platform will not be impacted by this patch series.
Follow is one example output with workstation.
 #lsmod | grep dell
   dell_wmi               28672  0
   dell_smbios            32768  1 dell_wmi
   dcdbas                 20480  1 dell_smbios
   dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
   sparse_keymap          12288  1 dell_wmi
   ledtrig_audio          12288  3 snd_ctl_led,snd_hda_codec_generic,dell_wmi
   video                  73728  2 dell_wmi,nvidia_modeset
   wmi                    40960  5 video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor

> >
> >    Additional, with this patch, follow behavior is found:
> >   1. For example, the platform profile is quiet.
> >   2. Reboot the system and change the USTT to performance.
> >   3. Boot to desktop, the platform profile is "quiet", the USTT will be
> changed back to "quiet".
> >   This looks like not a proper user experience. The platform profile should
> honor the BIOS setting, aka, the platform profile should be switched to
> "performance".
> >
>
> I agree, this sounds like the initial profile needs to be read from the BIOS
> settings too.
>
> Furthermore I wanted to ask is there also a WMI setting that corresponds to
> this that dell-wmi-sysman offers?
 Yes, Mario, you're right. This thermal setting could also be toggled by dell-wmi-sysman.
But, for the Dell consumer AMD laptops, like Alienware, the BIOS is another variant which is different with the workstation one.
With this variant BIOS, there is no USTT and also no dell_wmi/dell-wmi-sysman.

> I'm wondering if both should be probed in case the SMBIOS one goes away one day.
 Yep, I think this is a good suggestion.

>
> It seems like maybe ThermalManagement corresponds.  There was some test
> data in fwupd for it:
>
> https://urldefense.com/v3/__https://github.com/fwupd/fwupd/tree/main/lib
> fwupdplugin/tests/bios-attrs/dell-xps13-9310/dell-wmi-
> sysman/attributes/ThermalManagement__;!!LpKI!iyfGSyfnGxLymc-
> cEg93dfcnBIOtTJbfmCckZlj46eGqvJ_pHJ7WqFZ7-
> zrklKWKkZifqNgJ13LFm6wuz2UlzYqMPXciVw$ [github[.]com]

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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:05       ` Shen, Yijun
@ 2024-05-11 15:12         ` Limonciello, Mario
  2024-05-11 15:56           ` Shen, Yijun
  2024-05-11 16:02         ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: Limonciello, Mario @ 2024-05-11 15:12 UTC (permalink / raw)
  To: Shen, Yijun, Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell Client Kernel



On 5/11/2024 10:05 AM, Shen, Yijun wrote:
> 
> Internal Use - Confidential
>> -----Original Message-----
>> From: Mario Limonciello <mario.limonciello@amd.com>
>> Sent: Wednesday, May 8, 2024 11:53 PM
>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>> <lsanche@lyndeno.ca>
>> Cc: pali@kernel.org; W_Armin@gmx.de;
>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
>> Kernel <Dell.Client.Kernel@dell.com>
>> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
>> platform_profile
>>
>>
>> [EXTERNAL EMAIL]
>>
>> On 5/8/2024 09:24, Shen, Yijun wrote:
>>> Hi Lyndon,
>>>
>>>    Thanks for working on this patch.
>>>
>>>>
>>>    Dell side has an initial testing with this patch on some laptops, it looks
>> good. While changing the platform profile:
>>> 1. The corresponding USTT option in BIOS will be changed.
>>> 2. thermald will not be impacted. The related PSVT and ITMT will be loaded.
>>>    Some Dell DTs does not have the USTT, Dell'll have a check if nothing is
>> broken.
>>
>> Hi Alex!
>>
>> Have you had a check both on both your AMD laptops and workstations too,
>> or just the Intel ones?  I think it would be good to make sure it's getting the
>> correct experience in both cases.
>>
> Hi Mario,
> 
>   I've a check for this, for both laptop and workstation, the dell_laptop module will not be loaded. So, AMD platform will not be impacted by this patch series.
> Follow is one example output with workstation.
>   #lsmod | grep dell
>     dell_wmi               28672  0
>     dell_smbios            32768  1 dell_wmi
>     dcdbas                 20480  1 dell_smbios
>     dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
>     sparse_keymap          12288  1 dell_wmi
>     ledtrig_audio          12288  3 snd_ctl_led,snd_hda_codec_generic,dell_wmi
>     video                  73728  2 dell_wmi,nvidia_modeset
>     wmi                    40960  5 video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor
> 

Ah; right that makes sense.  In that case, is dell-laptop even the right 
place for this patch series?  I would think the same policies for the 
platform profile should be able to apply to desktop/workstation.

The v6 of this series would block smbios-thermal-ctl from working on a 
workstation too.

>>>
>>>     Additional, with this patch, follow behavior is found:
>>>    1. For example, the platform profile is quiet.
>>>    2. Reboot the system and change the USTT to performance.
>>>    3. Boot to desktop, the platform profile is "quiet", the USTT will be
>> changed back to "quiet".
>>>    This looks like not a proper user experience. The platform profile should
>> honor the BIOS setting, aka, the platform profile should be switched to
>> "performance".
>>>
>>
>> I agree, this sounds like the initial profile needs to be read from the BIOS
>> settings too.
>>
>> Furthermore I wanted to ask is there also a WMI setting that corresponds to
>> this that dell-wmi-sysman offers?
>   Yes, Mario, you're right. This thermal setting could also be toggled by dell-wmi-sysman.
> But, for the Dell consumer AMD laptops, like Alienware, the BIOS is another variant which is different with the workstation one.
> With this variant BIOS, there is no USTT and also no dell_wmi/dell-wmi-sysman.
> 
>> I'm wondering if both should be probed in case the SMBIOS one goes away one day.
>   Yep, I think this is a good suggestion.
> 

Great! Although something I wonder is if the policy when changed with 
dell-wmi-sysman is immediate or requires a reboot.  A lot of the 
settings in there aren't effective until after a reboot.

If this is one of them then it might not be a good idea to make it work 
for both.

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

* Re: [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands
  2024-05-11  2:36 ` [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands Lyndon Sanche
@ 2024-05-11 15:13   ` Limonciello, Mario
  2024-05-12 18:00   ` Armin Wolf
  1 sibling, 0 replies; 72+ messages in thread
From: Limonciello, Mario @ 2024-05-11 15:13 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp, hdegoede,
	Yijun.Shen, Matthew Garrett, Heiner Kallweit, Randy Dunlap,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel



On 5/10/2024 9:36 PM, Lyndon Sanche wrote:
> Add symbol to check if a specific class of smbios command is supported.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
> ---
>   drivers/platform/x86/dell/dell-smbios-base.c | 6 ++++++
>   drivers/platform/x86/dell/dell-smbios.h      | 1 +
>   2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
> index e61bfaf8b5c4..6ae09d7f76fb 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -350,6 +350,12 @@ void dell_laptop_call_notifier(unsigned long action, void *data)
>   }
>   EXPORT_SYMBOL_GPL(dell_laptop_call_notifier);
>   
> +bool dell_laptop_check_supported_cmds(u16 class)
> +{
> +	return da_supported_commands & (1 << class);
> +}
> +EXPORT_SYMBOL_GPL(dell_laptop_check_supported_cmds);
> +
>   static void __init parse_da_table(const struct dmi_header *dm)
>   {
>   	/* Final token is a terminator, so we don't want to copy it */
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..63116671eada 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -73,6 +73,7 @@ enum dell_laptop_notifier_actions {
>   int dell_laptop_register_notifier(struct notifier_block *nb);
>   int dell_laptop_unregister_notifier(struct notifier_block *nb);
>   void dell_laptop_call_notifier(unsigned long action, void *data);
> +bool dell_laptop_check_supported_cmds(u16 class);
>   
>   /* for the supported backends */
>   #ifdef CONFIG_DELL_SMBIOS_WMI

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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11  2:36 ` [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
@ 2024-05-11 15:16   ` Limonciello, Mario
  2024-05-11 15:59     ` Lyndon Sanche
  2024-05-12  0:14     ` Lyndon Sanche
  2024-05-12 18:05   ` Armin Wolf
  1 sibling, 2 replies; 72+ messages in thread
From: Limonciello, Mario @ 2024-05-11 15:16 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp, hdegoede,
	Yijun.Shen, Matthew Garrett, Heiner Kallweit, Randy Dunlap,
	Jonathan Corbet, Vegard Nossum, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On 5/10/2024 9:36 PM, Lyndon Sanche wrote:
> Some Dell laptops support configuration of preset fan modes through
> smbios tables.
> 
> If the platform supports these fan modes, set up platform_profile to
> change these modes. If not supported, skip enabling platform_profile.
> 
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
>   drivers/platform/x86/dell/Kconfig            |   2 +
>   drivers/platform/x86/dell/dell-laptop.c      | 242 +++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios-base.c |   1 +
>   drivers/platform/x86/dell/dell-smbios.h      |   1 +
>   4 files changed, 246 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
> index bd9f445974cc..26679f22733c 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -47,6 +47,7 @@ config DCDBAS
>   config DELL_LAPTOP
>   	tristate "Dell Laptop Extras"
>   	default m
> +	depends on ACPI
>   	depends on DMI
>   	depends on BACKLIGHT_CLASS_DEVICE
>   	depends on ACPI_VIDEO || ACPI_VIDEO = n
> @@ -57,6 +58,7 @@ config DELL_LAPTOP
>   	select POWER_SUPPLY
>   	select LEDS_CLASS
>   	select NEW_LEDS
> +	select ACPI_PLATFORM_PROFILE
>   	help
>   	This driver adds support for rfkill and backlight control to Dell
>   	laptops (except for some models covered by the Compal driver).
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..07f54f1cbac5 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,9 @@
>   #include <linux/i8042.h>
>   #include <linux/debugfs.h>
>   #include <linux/seq_file.h>
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/platform_profile.h>
>   #include <acpi/video.h>
>   #include "dell-rbtn.h"
>   #include "dell-smbios.h"
> @@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
>   static struct rfkill *wifi_rfkill;
>   static struct rfkill *bluetooth_rfkill;
>   static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>   static bool force_rfkill;
>   static bool micmute_led_registered;
>   static bool mute_led_registered;
> @@ -2199,6 +2203,236 @@ static int mute_led_set(struct led_classdev *led_cdev,
>   	return 0;
>   }
>   
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *
> + * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> + *               desired AAC mode shall be applied
> + * cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
> +
> +enum thermal_mode_bits {
> +	DELL_BALANCED = BIT(0),
> +	DELL_COOL_BOTTOM = BIT(1),
> +	DELL_QUIET = BIT(2),
> +	DELL_PERFORMANCE = BIT(3),
> +};
> +
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if (state & DELL_BALANCED)
> +		return DELL_BALANCED;
> +	else if (state & DELL_COOL_BOTTOM)
> +		return DELL_COOL_BOTTOM;
> +	else if (state & DELL_QUIET)
> +		return DELL_QUIET;
> +	else if (state & DELL_PERFORMANCE)
> +		return DELL_PERFORMANCE;
> +	else
> +		return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		return thermal_set_mode(DELL_BALANCED);
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return thermal_set_mode(DELL_PERFORMANCE);
> +	case PLATFORM_PROFILE_QUIET:
> +		return thermal_set_mode(DELL_QUIET);
> +	case PLATFORM_PROFILE_COOL:
> +		return thermal_set_mode(DELL_COOL_BOTTOM);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	int ret;
> +
> +	ret = thermal_get_mode();
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (ret) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	/* If thermal commands not supported, exit without error */
> +	if (!dell_laptop_check_supported_cmds(CLASS_INFO))
> +		return 0;
> +
> +	/* If thermal modes not supported, exit without error */
> +	ret = thermal_get_supported_modes(&supported_modes);
> +	if (ret < 0)
> +		return ret;
> +	if (!supported_modes)
> +		return 0;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if (supported_modes & DELL_QUIET)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if (supported_modes & DELL_COOL_BOTTOM)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if (supported_modes & DELL_BALANCED)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if (supported_modes & DELL_PERFORMANCE)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	/* Clean up if failed */
> +	ret = platform_profile_register(thermal_handler);
> +	if (ret)
> +		kfree(thermal_handler);
> +
> +	return ret;
> +}
> +
> +static void thermal_cleanup(void)
> +{
> +	if (thermal_handler) {
> +		platform_profile_remove();
> +		kfree(thermal_handler);
> +	}
> +}
> +
>   static struct led_classdev mute_led_cdev = {
>   	.name = "platform::mute",
>   	.max_brightness = 1,
> @@ -2238,6 +2472,11 @@ static int __init dell_init(void)
>   		goto fail_rfkill;
>   	}
>   
> +	/* Do not fail module if thermal modes not supported, just skip */
> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>   	if (quirks && quirks->touchpad_led)
>   		touchpad_led_init(&platform_device->dev);
>   
> @@ -2317,6 +2556,8 @@ static int __init dell_init(void)
>   		led_classdev_unregister(&mute_led_cdev);
>   fail_led:
>   	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>   fail_rfkill:
>   	platform_device_del(platform_device);
>   fail_platform_device2:
> @@ -2344,6 +2585,7 @@ static void __exit dell_exit(void)
>   		platform_device_unregister(platform_device);
>   		platform_driver_unregister(&platform_driver);
>   	}
> +	thermal_cleanup();
>   }
>   
>   /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
> index 6ae09d7f76fb..387fa5618f7a 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
>   	/* handled by kernel: dell-laptop */
>   	{0x0000, CLASS_INFO, SELECT_RFKILL},
>   	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
> +	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>   };

So when Alex checked on v5 that this doesn't load on workstations, it 
has made me realize that doing this will block the interface totally 
even on workstations.

So I think there are a few ways to go to handle this:

1) Rename dell-laptop to dell-client or dell-pc and let dell-laptop load 
on more form factors.  This would require some internal handling in the 
module for which features make sense for different form factors.

2) Add a new module just for the thermal handling and put all this code 
into it instead.

I don't have a strong opinion, but I do think one of them should be done 
to ensure there aren't problems on workstations losing access to thermal 
control.

>   
>   struct token_range {
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index 63116671eada..5d7178df80c6 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>   /* Classes and selects used only in kernel drivers */
>   #define CLASS_KBD_BACKLIGHT 4
>   #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>   
>   /* Tokens used in kernel drivers, any of these
>    * should be filtered from userspace access

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

* RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11  1:49       ` Lyndon Sanche
@ 2024-05-11 15:22         ` Shen, Yijun
  2024-05-11 15:54           ` Lyndon Sanche
  0 siblings, 1 reply; 72+ messages in thread
From: Shen, Yijun @ 2024-05-11 15:22 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Mario Limonciello, Pali Rohár, Armin Wolf,
	srinivas.pandruvada, Ilpo Järvinen, kernel test robot,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, LKML, Dell Client Kernel




Internal Use - Confidential
> -----Original Message-----
> From: Lyndon Sanche <lsanche@lyndeno.ca>
> Sent: Saturday, May 11, 2024 9:49 AM
> To: Shen, Yijun <Yijun_Shen@Dell.com>
> Cc: Mario Limonciello <mario.limonciello@amd.com>; Pali Rohár
> <pali@kernel.org>; Armin Wolf <W_Armin@gmx.de>;
> srinivas.pandruvada@linux.intel.com; Ilpo Järvinen
> <ilpo.jarvinen@linux.intel.com>; kernel test robot <lkp@intel.com>; Hans de
> Goede <hdegoede@redhat.com>; Matthew Garrett <mjg59@srcf.ucam.org>;
> Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
> platform-driver-x86@vger.kernel.org; LKML <linux-kernel@vger.kernel.org>;
> Dell Client Kernel <Dell.Client.Kernel@dell.com>
> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>
>
> [EXTERNAL EMAIL]
>
>
>
> On Thu, May 9 2024 at 09:10:51 AM -06:00:00, Lyndon Sanche
> <lsanche@lyndeno.ca> wrote:
> > On Wed, May 8, 2024, at 8:24 AM, Shen, Yijun wrote:
> >>  Hi Lyndon,
> >>
> >>   Thanks for working on this patch.
> >>
> >>
> >>   Dell side has an initial testing with this patch on some laptops,
> >> it  looks good. While changing the platform profile:
> >>  1. The corresponding USTT option in BIOS will be changed.
> >>  2. thermald will not be impacted. The related PSVT and ITMT will be
> >> loaded.
> >>   Some Dell DTs does not have the USTT, Dell'll have a check if
> >> nothing  is broken.
> >>
> >>    Additional, with this patch, follow behavior is found:
> >>   1. For example, the platform profile is quiet.
> >>   2. Reboot the system and change the USTT to performance.
> >>   3. Boot to desktop, the platform profile is "quiet", the USTT will
> >> be  changed back to "quiet".
> >>   This looks like not a proper user experience. The platform profile
> >> should honor the BIOS setting, aka, the platform profile should be
> >> switched to "performance".
> >
> > Hello:
> >
> > Thank you for your email. This is definitely undesirable behaviour, I
> > will have a look at the code to see why this is happening. Does it
> > always revert to quiet on boot, or always the mode that you had
> > switched to prior to reboot?
> >
> > Do you happen to have power-profiles-daemon or something similar
> > running? My understanding is it remembers profiles across reboots,
> > this could potentially also revert the profile back to what it was.
> > See this release for details:
> > https://urldefense.com/v3/__https://gitlab.freedesktop.org/upower/powe
> > r-profiles-daemon/-/releases/0.9.0__;!!LpKI!jUAEHb-9foumkcmPlEKD6tnQrZ
> > sqjB1sXdPDsYvH2fJ-gPV6G35MUtDW4q3xhlJ4IeLcIgmVpb3ztXqaOg8$
> > [gitlab[.]freedesktop[.]org]
> >
> > I will assume there is a bug in my code at this point. I will test
> > with and without ppd running on my system to see if it changes across
> > reboots.
> >
> > Are USTT settings exposed in your BIOS configuration menu? On my
> > laptop they are not and I have to use smbios-thermal-ctl.
> >
> > Thank you,
> >
> > Lyndon
>
> Hi Yijun:
>
> I tested this on my computer (XPS 9560). I do not have access to the USTT
> settings in the BIOS screen so to substitute that, I booted without the patch
> and set the USTT manually using smbios-thermal-ctl.
> Here are my findings:
>
> Scenario #1: Without power-profiles-daemon (ppd) running
>
> 1. Boot with patch, set platform_profile to quiet 2. Boot without patch applied
> (no platform_profile)
>  - smbios-thermal-ctl confirms USTT is set to quiet
>  - use smbios-thermal-ctl to set USTT to performance
>  - confirm set to performance
> 3. Boot with patch again
>  - platform_profile is set to performance
>
> Scenario #2: With ppd running
> 1. Boot with patch, set platform_profile to performance with ppd
>  - Confirm platform_profile is performance 2. Boot without patch applied (no
> platform_profile)
>  - smbios-thermal-ctl confirms USTT is set to performance
>  - ppd reverts to balanced (only controlling intel_pstate in this case)
>  - use smbios-thermal-ctl to set USTT to quiet
>  - confirm set to quiet
> 3. Boot with patch again
>  - platform_profile and ppd is set to performance
>
> In my case, the setting in the smbios is honored if it was switched with
> another method. When using a userspace program that manipulates the
> platform_profile, the program seems to remember the previous state and
> switch to that.
>
> So I do not think there is a bug in this patch related to this issue, at least in my
> case. Please let me know if you have any questions.
>
> Thanks,
>
> Lyndon
>
>
>
Hi Lyndon,

 I've made a video recorder of the issue: https://dell.box.com/s/3f3znz1z8c6htbcll9juj6tyyu0zvvut
 My test environment is that I freshly installed the Fedora 40 and will not do any online updates. Then install the kernel with the v5 patch applied.

 XPS 9560 is a pretty old system which is RTS with 2017. No USTT setting in the BIOS is expected.
 I've a check that the Dell system, at least shipped from 2022, the USTT setting will be valid in the BIOS. The system used in above link, it is Latitude 7350 which is shipped by 2024 April.

 I think the key point to duplicate of this issue that, the USTT needs to be changed under BIOS but not under the Linux OS.

Thanks



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

* RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:22         ` Shen, Yijun
@ 2024-05-11 15:54           ` Lyndon Sanche
  2024-05-11 16:12             ` Shen, Yijun
  0 siblings, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11 15:54 UTC (permalink / raw)
  To: Shen, Yijun
  Cc: Mario Limonciello, Pali Rohár, Armin Wolf,
	srinivas.pandruvada, Ilpo Järvinen, kernel test robot,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, LKML, Dell Client Kernel



On May 11, 2024 9:22:23 a.m. MDT, "Shen, Yijun" <Yijun.Shen@dell.com> wrote:
>
>
>
>Internal Use - Confidential
>> -----Original Message-----
>> From: Lyndon Sanche <lsanche@lyndeno.ca>
>> Sent: Saturday, May 11, 2024 9:49 AM
>> To: Shen, Yijun <Yijun_Shen@Dell.com>
>> Cc: Mario Limonciello <mario.limonciello@amd.com>; Pali Rohár
>> <pali@kernel.org>; Armin Wolf <W_Armin@gmx.de>;
>> srinivas.pandruvada@linux.intel.com; Ilpo Järvinen
>> <ilpo.jarvinen@linux.intel.com>; kernel test robot <lkp@intel.com>; Hans de
>> Goede <hdegoede@redhat.com>; Matthew Garrett <mjg59@srcf.ucam.org>;
>> Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>> platform-driver-x86@vger.kernel.org; LKML <linux-kernel@vger.kernel.org>;
>> Dell Client Kernel <Dell.Client.Kernel@dell.com>
>> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>>
>>
>> [EXTERNAL EMAIL]
>>
>>
>>
>> On Thu, May 9 2024 at 09:10:51 AM -06:00:00, Lyndon Sanche
>> <lsanche@lyndeno.ca> wrote:
>> > On Wed, May 8, 2024, at 8:24 AM, Shen, Yijun wrote:
>> >>  Hi Lyndon,
>> >>
>> >>   Thanks for working on this patch.
>> >>
>> >>
>> >>   Dell side has an initial testing with this patch on some laptops,
>> >> it  looks good. While changing the platform profile:
>> >>  1. The corresponding USTT option in BIOS will be changed.
>> >>  2. thermald will not be impacted. The related PSVT and ITMT will be
>> >> loaded.
>> >>   Some Dell DTs does not have the USTT, Dell'll have a check if
>> >> nothing  is broken.
>> >>
>> >>    Additional, with this patch, follow behavior is found:
>> >>   1. For example, the platform profile is quiet.
>> >>   2. Reboot the system and change the USTT to performance.
>> >>   3. Boot to desktop, the platform profile is "quiet", the USTT will
>> >> be  changed back to "quiet".
>> >>   This looks like not a proper user experience. The platform profile
>> >> should honor the BIOS setting, aka, the platform profile should be
>> >> switched to "performance".
>> >
>> > Hello:
>> >
>> > Thank you for your email. This is definitely undesirable behaviour, I
>> > will have a look at the code to see why this is happening. Does it
>> > always revert to quiet on boot, or always the mode that you had
>> > switched to prior to reboot?
>> >
>> > Do you happen to have power-profiles-daemon or something similar
>> > running? My understanding is it remembers profiles across reboots,
>> > this could potentially also revert the profile back to what it was.
>> > See this release for details:
>> > https://urldefense.com/v3/__https://gitlab.freedesktop.org/upower/powe
>> > r-profiles-daemon/-/releases/0.9.0__;!!LpKI!jUAEHb-9foumkcmPlEKD6tnQrZ
>> > sqjB1sXdPDsYvH2fJ-gPV6G35MUtDW4q3xhlJ4IeLcIgmVpb3ztXqaOg8$
>> > [gitlab[.]freedesktop[.]org]
>> >
>> > I will assume there is a bug in my code at this point. I will test
>> > with and without ppd running on my system to see if it changes across
>> > reboots.
>> >
>> > Are USTT settings exposed in your BIOS configuration menu? On my
>> > laptop they are not and I have to use smbios-thermal-ctl.
>> >
>> > Thank you,
>> >
>> > Lyndon
>>
>> Hi Yijun:
>>
>> I tested this on my computer (XPS 9560). I do not have access to the USTT
>> settings in the BIOS screen so to substitute that, I booted without the patch
>> and set the USTT manually using smbios-thermal-ctl.
>> Here are my findings:
>>
>> Scenario #1: Without power-profiles-daemon (ppd) running
>>
>> 1. Boot with patch, set platform_profile to quiet 2. Boot without patch applied
>> (no platform_profile)
>>  - smbios-thermal-ctl confirms USTT is set to quiet
>>  - use smbios-thermal-ctl to set USTT to performance
>>  - confirm set to performance
>> 3. Boot with patch again
>>  - platform_profile is set to performance
>>
>> Scenario #2: With ppd running
>> 1. Boot with patch, set platform_profile to performance with ppd
>>  - Confirm platform_profile is performance 2. Boot without patch applied (no
>> platform_profile)
>>  - smbios-thermal-ctl confirms USTT is set to performance
>>  - ppd reverts to balanced (only controlling intel_pstate in this case)
>>  - use smbios-thermal-ctl to set USTT to quiet
>>  - confirm set to quiet
>> 3. Boot with patch again
>>  - platform_profile and ppd is set to performance
>>
>> In my case, the setting in the smbios is honored if it was switched with
>> another method. When using a userspace program that manipulates the
>> platform_profile, the program seems to remember the previous state and
>> switch to that.
>>
>> So I do not think there is a bug in this patch related to this issue, at least in my
>> case. Please let me know if you have any questions.
>>
>> Thanks,
>>
>> Lyndon
>>
>>
>>
>Hi Lyndon,
>
> I've made a video recorder of the issue: https://dell.box.com/s/3f3znz1z8c6htbcll9juj6tyyu0zvvut
> My test environment is that I freshly installed the Fedora 40 and will not do any online updates. Then install the kernel with the v5 patch applied.
>
> XPS 9560 is a pretty old system which is RTS with 2017. No USTT setting in the BIOS is expected.
> I've a check that the Dell system, at least shipped from 2022, the USTT setting will be valid in the BIOS. The system used in above link, it is Latitude 7350 which is shipped by 2024 April.
>
> I think the key point to duplicate of this issue that, the USTT needs to be changed under BIOS but not under the Linux OS.
>
>Thanks
>
>


Thanks for the video.

Fedora 40 has power-profiles-daemon enabled by default AFAIK. This would be changing the platform profile at load to match the last known state.

Are you able to rerun this test with PPD disabled? Just in case it is a difference between setting it in BIOS and smbios-thermal-ctl.

Thanks,

Lyndon

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

* RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:12         ` Limonciello, Mario
@ 2024-05-11 15:56           ` Shen, Yijun
  2024-05-12 17:53             ` Armin Wolf
  0 siblings, 1 reply; 72+ messages in thread
From: Shen, Yijun @ 2024-05-11 15:56 UTC (permalink / raw)
  To: Limonciello, Mario, Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell Client Kernel


Internal Use - Confidential
> -----Original Message-----
> From: Limonciello, Mario <mario.limonciello@amd.com>
> Sent: Saturday, May 11, 2024 11:13 PM
> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
> <lsanche@lyndeno.ca>
> Cc: pali@kernel.org; W_Armin@gmx.de;
> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
> Kernel <Dell.Client.Kernel@dell.com>
> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>
>
> [EXTERNAL EMAIL]
>
>
>
> On 5/11/2024 10:05 AM, Shen, Yijun wrote:
> >
> > Internal Use - Confidential
> >> -----Original Message-----
> >> From: Mario Limonciello <mario.limonciello@amd.com>
> >> Sent: Wednesday, May 8, 2024 11:53 PM
> >> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
> >> <lsanche@lyndeno.ca>
> >> Cc: pali@kernel.org; W_Armin@gmx.de;
> >> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
> >> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew
> Garrett
> >> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner
> >> Kallweit <hkallweit1@gmail.com>; Vegard Nossum
> >> <vegard.nossum@oracle.com>; platform-driver-x86@vger.kernel.org;
> >> linux-kernel@vger.kernel.org; Dell Client Kernel
> >> <Dell.Client.Kernel@dell.com>
> >> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
> >> platform_profile
> >>
> >>
> >> [EXTERNAL EMAIL]
> >>
> >> On 5/8/2024 09:24, Shen, Yijun wrote:
> >>> Hi Lyndon,
> >>>
> >>>    Thanks for working on this patch.
> >>>
> >>>>
> >>>    Dell side has an initial testing with this patch on some laptops,
> >>> it looks
> >> good. While changing the platform profile:
> >>> 1. The corresponding USTT option in BIOS will be changed.
> >>> 2. thermald will not be impacted. The related PSVT and ITMT will be
> loaded.
> >>>    Some Dell DTs does not have the USTT, Dell'll have a check if
> >>> nothing is
> >> broken.
> >>
> >> Hi Alex!
> >>
> >> Have you had a check both on both your AMD laptops and workstations
> >> too, or just the Intel ones?  I think it would be good to make sure
> >> it's getting the correct experience in both cases.
> >>
> > Hi Mario,
> >
> >   I've a check for this, for both laptop and workstation, the dell_laptop
> module will not be loaded. So, AMD platform will not be impacted by this
> patch series.
> > Follow is one example output with workstation.
> >   #lsmod | grep dell
> >     dell_wmi               28672  0
> >     dell_smbios            32768  1 dell_wmi
> >     dcdbas                 20480  1 dell_smbios
> >     dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
> >     sparse_keymap          12288  1 dell_wmi
> >     ledtrig_audio          12288  3 snd_ctl_led,snd_hda_codec_generic,dell_wmi
> >     video                  73728  2 dell_wmi,nvidia_modeset
> >     wmi                    40960  5
> video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor
> >
>
> Ah; right that makes sense.  In that case, is dell-laptop even the right place for
> this patch series?  I would think the same policies for the platform profile
> should be able to apply to desktop/workstation.
>
> The v6 of this series would block smbios-thermal-ctl from working on a
> workstation too.
>
> >>>
> >>>     Additional, with this patch, follow behavior is found:
> >>>    1. For example, the platform profile is quiet.
> >>>    2. Reboot the system and change the USTT to performance.
> >>>    3. Boot to desktop, the platform profile is "quiet", the USTT
> >>> will be
> >> changed back to "quiet".
> >>>    This looks like not a proper user experience. The platform
> >>> profile should
> >> honor the BIOS setting, aka, the platform profile should be switched
> >> to "performance".
> >>>
> >>
> >> I agree, this sounds like the initial profile needs to be read from
> >> the BIOS settings too.
> >>
> >> Furthermore I wanted to ask is there also a WMI setting that
> >> corresponds to this that dell-wmi-sysman offers?
> >   Yes, Mario, you're right. This thermal setting could also be toggled by dell-
> wmi-sysman.
> > But, for the Dell consumer AMD laptops, like Alienware, the BIOS is another
> variant which is different with the workstation one.
> > With this variant BIOS, there is no USTT and also no dell_wmi/dell-wmi-
> sysman.
> >
> >> I'm wondering if both should be probed in case the SMBIOS one goes
> away one day.
> >   Yep, I think this is a good suggestion.
> >
>
> Great! Although something I wonder is if the policy when changed with dell-
> wmi-sysman is immediate or requires a reboot.  A lot of the settings in there
> aren't effective until after a reboot.
>
> If this is one of them then it might not be a good idea to make it work for
> both.

Hi Mario,

 Just have a check, the check steps are:
1. stop the thermald
2. run the stress test
3. Toggle the thermal setting between UltraPerformance and Quiet via dell-wmi-sysman
4. Check the CPU FAN speed
 The system reboot is not needed, the CPU fan speed changes immediately.
 A screen recorder here: https://dell.box.com/s/p2bhd2b6cv8z5buk9eao3bosgrrp1lf9

Thanks


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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:16   ` Limonciello, Mario
@ 2024-05-11 15:59     ` Lyndon Sanche
       [not found]       ` <48JCDS.E4RT1F9DTKFU1@lyndeno.ca>
  2024-05-12  0:14     ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11 15:59 UTC (permalink / raw)
  To: Limonciello, Mario
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp, hdegoede,
	Yijun.Shen, Matthew Garrett, Heiner Kallweit, Randy Dunlap,
	Jonathan Corbet, Vegard Nossum, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On May 11, 2024 9:16:56 a.m. MDT, "Limonciello, Mario" <mario.limonciello@amd.com> wrote:
>
>
>On 5/10/2024 9:36 PM, Lyndon Sanche wrote:
>> Some Dell laptops support configuration of preset fan modes through
>> smbios tables.
>> 
>> If the platform supports these fan modes, set up platform_profile to
>> change these modes. If not supported, skip enabling platform_profile.
>> 
>> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
>> ---
>>   drivers/platform/x86/dell/Kconfig            |   2 +
>>   drivers/platform/x86/dell/dell-laptop.c      | 242 +++++++++++++++++++
>>   drivers/platform/x86/dell/dell-smbios-base.c |   1 +
>>   drivers/platform/x86/dell/dell-smbios.h      |   1 +
>>   4 files changed, 246 insertions(+)
>> 
>> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
>> index bd9f445974cc..26679f22733c 100644
>> --- a/drivers/platform/x86/dell/Kconfig
>> +++ b/drivers/platform/x86/dell/Kconfig
>> @@ -47,6 +47,7 @@ config DCDBAS
>>   config DELL_LAPTOP
>>   	tristate "Dell Laptop Extras"
>>   	default m
>> +	depends on ACPI
>>   	depends on DMI
>>   	depends on BACKLIGHT_CLASS_DEVICE
>>   	depends on ACPI_VIDEO || ACPI_VIDEO = n
>> @@ -57,6 +58,7 @@ config DELL_LAPTOP
>>   	select POWER_SUPPLY
>>   	select LEDS_CLASS
>>   	select NEW_LEDS
>> +	select ACPI_PLATFORM_PROFILE
>>   	help
>>   	This driver adds support for rfkill and backlight control to Dell
>>   	laptops (except for some models covered by the Compal driver).
>> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
>> index 42f7de2b4522..07f54f1cbac5 100644
>> --- a/drivers/platform/x86/dell/dell-laptop.c
>> +++ b/drivers/platform/x86/dell/dell-laptop.c
>> @@ -27,6 +27,9 @@
>>   #include <linux/i8042.h>
>>   #include <linux/debugfs.h>
>>   #include <linux/seq_file.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/bits.h>
>> +#include <linux/platform_profile.h>
>>   #include <acpi/video.h>
>>   #include "dell-rbtn.h"
>>   #include "dell-smbios.h"
>> @@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
>>   static struct rfkill *wifi_rfkill;
>>   static struct rfkill *bluetooth_rfkill;
>>   static struct rfkill *wwan_rfkill;
>> +static struct platform_profile_handler *thermal_handler;
>>   static bool force_rfkill;
>>   static bool micmute_led_registered;
>>   static bool mute_led_registered;
>> @@ -2199,6 +2203,236 @@ static int mute_led_set(struct led_classdev *led_cdev,
>>   	return 0;
>>   }
>>   +/* Derived from smbios-thermal-ctl
>> + *
>> + * cbClass 17
>> + * cbSelect 19
>> + * User Selectable Thermal Tables(USTT)
>> + * cbArg1 determines the function to be performed
>> + * cbArg1 0x0 = Get Thermal Information
>> + *  cbRES1         Standard return codes (0, -1, -2)
>> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
>> + *                  its bit is set to 1
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performance
>> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
>> + *                 Each mode corresponds to the supported thermal modes in
>> + *                  byte 0. A mode is supported if its bit is set to 1.
>> + *     Bit 0 AAC (Balanced)
>> + *     Bit 1 AAC (Cool Bottom
>> + *     Bit 2 AAC (Quiet)
>> + *     Bit 3 AAC (Performance)
>> + *  cbRes3, byte 0 Current Thermal Mode
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performanc
>> + *  cbRes3, byte 1  AAC Configuration type
>> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
>> + *          1       USTT mode specific
>> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
>> + *     If AAC Configuration Type is Global,
>> + *          0       AAC mode disabled
>> + *          1       AAC mode enabled
>> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
>> + *          Bit 0 AAC (Balanced)
>> + *          Bit 1 AAC (Cool Bottom
>> + *          Bit 2 AAC (Quiet)
>> + *          Bit 3 AAC (Performance)
>> + *  cbRes3, byte 3  Current Fan Failure Mode
>> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
>> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
>> + *
>> + * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
>> + *               desired AAC mode shall be applied
>> + * cbArg2, byte 0  Desired Thermal Mode to set
>> + *                  (only one bit may be set for this parameter)
>> + *     Bit 0 Balanced
>> + *     Bit 1 Cool Bottom
>> + *     Bit 2 Quiet
>> + *     Bit 3 Performance
>> + * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
>> + *     If AAC Configuration Type is Global,
>> + *         0  AAC mode disabled
>> + *         1  AAC mode enabled
>> + *     If AAC Configuration Type is USTT mode specific
>> + *     (multiple bits may be set for this parameter),
>> + *         Bit 0 AAC (Balanced)
>> + *         Bit 1 AAC (Cool Bottom
>> + *         Bit 2 AAC (Quiet)
>> + *         Bit 3 AAC (Performance)
>> + */
>> +
>> +#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
>> +#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
>> +#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
>> +
>> +enum thermal_mode_bits {
>> +	DELL_BALANCED = BIT(0),
>> +	DELL_COOL_BOTTOM = BIT(1),
>> +	DELL_QUIET = BIT(2),
>> +	DELL_PERFORMANCE = BIT(3),
>> +};
>> +
>> +static int thermal_get_mode(void)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int state;
>> +	int ret;
>> +
>> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
>> +	if (ret)
>> +		return ret;
>> +	state = buffer.output[2];
>> +	if (state & DELL_BALANCED)
>> +		return DELL_BALANCED;
>> +	else if (state & DELL_COOL_BOTTOM)
>> +		return DELL_COOL_BOTTOM;
>> +	else if (state & DELL_QUIET)
>> +		return DELL_QUIET;
>> +	else if (state & DELL_PERFORMANCE)
>> +		return DELL_PERFORMANCE;
>> +	else
>> +		return -ENXIO;
>> +}
>> +
>> +static int thermal_get_supported_modes(int *supported_bits)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int ret;
>> +
>> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
>> +	if (ret)
>> +		return ret;
>> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
>> +	return 0;
>> +}
>> +
>> +static int thermal_get_acc_mode(int *acc_mode)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int ret;
>> +
>> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
>> +	if (ret)
>> +		return ret;
>> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
>> +	return 0;
>> +}
>> +
>> +static int thermal_set_mode(enum thermal_mode_bits state)
>> +{
>> +	struct calling_interface_buffer buffer;
>> +	int ret;
>> +	int acc_mode;
>> +
>> +	ret = thermal_get_acc_mode(&acc_mode);
>> +	if (ret)
>> +		return ret;
>> +
>> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
>> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
>> +	return ret;
>> +}
>> +
>> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
>> +					enum platform_profile_option profile)
>> +{
>> +	switch (profile) {
>> +	case PLATFORM_PROFILE_BALANCED:
>> +		return thermal_set_mode(DELL_BALANCED);
>> +	case PLATFORM_PROFILE_PERFORMANCE:
>> +		return thermal_set_mode(DELL_PERFORMANCE);
>> +	case PLATFORM_PROFILE_QUIET:
>> +		return thermal_set_mode(DELL_QUIET);
>> +	case PLATFORM_PROFILE_COOL:
>> +		return thermal_set_mode(DELL_COOL_BOTTOM);
>> +	default:
>> +		return -EOPNOTSUPP;
>> +	}
>> +}
>> +
>> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
>> +					enum platform_profile_option *profile)
>> +{
>> +	int ret;
>> +
>> +	ret = thermal_get_mode();
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	switch (ret) {
>> +	case DELL_BALANCED:
>> +		*profile = PLATFORM_PROFILE_BALANCED;
>> +		break;
>> +	case DELL_PERFORMANCE:
>> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
>> +		break;
>> +	case DELL_COOL_BOTTOM:
>> +		*profile = PLATFORM_PROFILE_COOL;
>> +		break;
>> +	case DELL_QUIET:
>> +		*profile = PLATFORM_PROFILE_QUIET;
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int thermal_init(void)
>> +{
>> +	int ret;
>> +	int supported_modes;
>> +
>> +	/* If thermal commands not supported, exit without error */
>> +	if (!dell_laptop_check_supported_cmds(CLASS_INFO))
>> +		return 0;
>> +
>> +	/* If thermal modes not supported, exit without error */
>> +	ret = thermal_get_supported_modes(&supported_modes);
>> +	if (ret < 0)
>> +		return ret;
>> +	if (!supported_modes)
>> +		return 0;
>> +
>> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
>> +	if (!thermal_handler)
>> +		return -ENOMEM;
>> +	thermal_handler->profile_get = thermal_platform_profile_get;
>> +	thermal_handler->profile_set = thermal_platform_profile_set;
>> +
>> +	if (supported_modes & DELL_QUIET)
>> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
>> +	if (supported_modes & DELL_COOL_BOTTOM)
>> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
>> +	if (supported_modes & DELL_BALANCED)
>> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
>> +	if (supported_modes & DELL_PERFORMANCE)
>> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
>> +
>> +	/* Clean up if failed */
>> +	ret = platform_profile_register(thermal_handler);
>> +	if (ret)
>> +		kfree(thermal_handler);
>> +
>> +	return ret;
>> +}
>> +
>> +static void thermal_cleanup(void)
>> +{
>> +	if (thermal_handler) {
>> +		platform_profile_remove();
>> +		kfree(thermal_handler);
>> +	}
>> +}
>> +
>>   static struct led_classdev mute_led_cdev = {
>>   	.name = "platform::mute",
>>   	.max_brightness = 1,
>> @@ -2238,6 +2472,11 @@ static int __init dell_init(void)
>>   		goto fail_rfkill;
>>   	}
>>   +	/* Do not fail module if thermal modes not supported, just skip */
>> +	ret = thermal_init();
>> +	if (ret)
>> +		goto fail_thermal;
>> +
>>   	if (quirks && quirks->touchpad_led)
>>   		touchpad_led_init(&platform_device->dev);
>>   @@ -2317,6 +2556,8 @@ static int __init dell_init(void)
>>   		led_classdev_unregister(&mute_led_cdev);
>>   fail_led:
>>   	dell_cleanup_rfkill();
>> +fail_thermal:
>> +	thermal_cleanup();
>>   fail_rfkill:
>>   	platform_device_del(platform_device);
>>   fail_platform_device2:
>> @@ -2344,6 +2585,7 @@ static void __exit dell_exit(void)
>>   		platform_device_unregister(platform_device);
>>   		platform_driver_unregister(&platform_driver);
>>   	}
>> +	thermal_cleanup();
>>   }
>>     /* dell-rbtn.c driver export functions which will not work correctly (and could
>> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
>> index 6ae09d7f76fb..387fa5618f7a 100644
>> --- a/drivers/platform/x86/dell/dell-smbios-base.c
>> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
>> @@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
>>   	/* handled by kernel: dell-laptop */
>>   	{0x0000, CLASS_INFO, SELECT_RFKILL},
>>   	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
>> +	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>>   };
>
>So when Alex checked on v5 that this doesn't load on workstations, it has made me realize that doing this will block the interface totally even on workstations.
>
>So I think there are a few ways to go to handle this:
>
>1) Rename dell-laptop to dell-client or dell-pc and let dell-laptop load on more form factors.  This would require some internal handling in the module for which features make sense for different form factors.
>
>2) Add a new module just for the thermal handling and put all this code into it instead.
>
>I don't have a strong opinion, but I do think one of them should be done to ensure there aren't problems on workstations losing access to thermal control.
>

A dell-client/laptop separation makes more sense IMO. I don't think keyboard control would belong in a the dell-client module either. Separating just thermal control would be easier, but not as clean I think.

Thanks,

Lyndon

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

* RE: RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:05       ` Shen, Yijun
  2024-05-11 15:12         ` Limonciello, Mario
@ 2024-05-11 16:02         ` Lyndon Sanche
  1 sibling, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-11 16:02 UTC (permalink / raw)
  To: Shen, Yijun, Mario Limonciello
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell Client Kernel



On May 11, 2024 9:05:15 a.m. MDT, "Shen, Yijun" <Yijun.Shen@dell.com> wrote:
>
>Internal Use - Confidential
>> -----Original Message-----
>> From: Mario Limonciello <mario.limonciello@amd.com>
>> Sent: Wednesday, May 8, 2024 11:53 PM
>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>> <lsanche@lyndeno.ca>
>> Cc: pali@kernel.org; W_Armin@gmx.de;
>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
>> Kernel <Dell.Client.Kernel@dell.com>
>> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
>> platform_profile
>>
>>
>> [EXTERNAL EMAIL]
>>
>> On 5/8/2024 09:24, Shen, Yijun wrote:
>> > Hi Lyndon,
>> >
>> >   Thanks for working on this patch.
>> >
>> >>
>> >   Dell side has an initial testing with this patch on some laptops, it looks
>> good. While changing the platform profile:
>> > 1. The corresponding USTT option in BIOS will be changed.
>> > 2. thermald will not be impacted. The related PSVT and ITMT will be loaded.
>> >   Some Dell DTs does not have the USTT, Dell'll have a check if nothing is
>> broken.
>>
>> Hi Alex!
>>
>> Have you had a check both on both your AMD laptops and workstations too,
>> or just the Intel ones?  I think it would be good to make sure it's getting the
>> correct experience in both cases.
>>
>Hi Mario,
>
> I've a check for this, for both laptop and workstation, the dell_laptop module will not be loaded. So, AMD platform will not be impacted by this patch series.
>Follow is one example output with workstation.
> #lsmod | grep dell
>   dell_wmi               28672  0
>   dell_smbios            32768  1 dell_wmi
>   dcdbas                 20480  1 dell_smbios
>   dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
>   sparse_keymap          12288  1 dell_wmi
>   ledtrig_audio          12288  3 snd_ctl_led,snd_hda_codec_generic,dell_wmi
>   video                  73728  2 dell_wmi,nvidia_modeset
>   wmi                    40960  5 video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor
>

Should AMD platforms be affected? Do they support the USTT modes as well?

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

* RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:54           ` Lyndon Sanche
@ 2024-05-11 16:12             ` Shen, Yijun
  0 siblings, 0 replies; 72+ messages in thread
From: Shen, Yijun @ 2024-05-11 16:12 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: Mario Limonciello, Pali Rohár, Armin Wolf,
	srinivas.pandruvada, Ilpo Järvinen, kernel test robot,
	Hans de Goede, Matthew Garrett, Jonathan Corbet, Heiner Kallweit,
	Vegard Nossum, platform-driver-x86, LKML, Dell Client Kernel


Internal Use - Confidential
> -----Original Message-----
> From: Lyndon Sanche <lsanche@lyndeno.ca>
> Sent: Saturday, May 11, 2024 11:54 PM
> To: Shen, Yijun <Yijun_Shen@Dell.com>
> Cc: Mario Limonciello <mario.limonciello@amd.com>; Pali Rohár
> <pali@kernel.org>; Armin Wolf <W_Armin@gmx.de>;
> srinivas.pandruvada@linux.intel.com; Ilpo Järvinen
> <ilpo.jarvinen@linux.intel.com>; kernel test robot <lkp@intel.com>; Hans de
> Goede <hdegoede@redhat.com>; Matthew Garrett <mjg59@srcf.ucam.org>;
> Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
> platform-driver-x86@vger.kernel.org; LKML <linux-kernel@vger.kernel.org>;
> Dell Client Kernel <Dell.Client.Kernel@dell.com>
> Subject: RE: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>
>
> [EXTERNAL EMAIL]
>
>
>
> On May 11, 2024 9:22:23 a.m. MDT, "Shen, Yijun" <Yijun.Shen@dell.com>
> wrote:
> >
> >
> >
> >Internal Use - Confidential
> >> -----Original Message-----
> >> From: Lyndon Sanche <lsanche@lyndeno.ca>
> >> Sent: Saturday, May 11, 2024 9:49 AM
> >> To: Shen, Yijun <Yijun_Shen@Dell.com>
> >> Cc: Mario Limonciello <mario.limonciello@amd.com>; Pali Rohár
> >> <pali@kernel.org>; Armin Wolf <W_Armin@gmx.de>;
> >> srinivas.pandruvada@linux.intel.com; Ilpo Järvinen
> >> <ilpo.jarvinen@linux.intel.com>; kernel test robot <lkp@intel.com>;
> >> Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
> >> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner
> >> Kallweit <hkallweit1@gmail.com>; Vegard Nossum
> >> <vegard.nossum@oracle.com>; platform-driver-x86@vger.kernel.org;
> LKML
> >> <linux-kernel@vger.kernel.org>; Dell Client Kernel
> >> <Dell.Client.Kernel@dell.com>
> >> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement
> >> platform_profile
> >>
> >>
> >> [EXTERNAL EMAIL]
> >>
> >>
> >>
> >> On Thu, May 9 2024 at 09:10:51 AM -06:00:00, Lyndon Sanche
> >> <lsanche@lyndeno.ca> wrote:
> >> > On Wed, May 8, 2024, at 8:24 AM, Shen, Yijun wrote:
> >> >>  Hi Lyndon,
> >> >>
> >> >>   Thanks for working on this patch.
> >> >>
> >> >>
> >> >>   Dell side has an initial testing with this patch on some
> >> >> laptops, it  looks good. While changing the platform profile:
> >> >>  1. The corresponding USTT option in BIOS will be changed.
> >> >>  2. thermald will not be impacted. The related PSVT and ITMT will
> >> >> be loaded.
> >> >>   Some Dell DTs does not have the USTT, Dell'll have a check if
> >> >> nothing  is broken.
> >> >>
> >> >>    Additional, with this patch, follow behavior is found:
> >> >>   1. For example, the platform profile is quiet.
> >> >>   2. Reboot the system and change the USTT to performance.
> >> >>   3. Boot to desktop, the platform profile is "quiet", the USTT
> >> >> will be  changed back to "quiet".
> >> >>   This looks like not a proper user experience. The platform
> >> >> profile should honor the BIOS setting, aka, the platform profile
> >> >> should be switched to "performance".
> >> >
> >> > Hello:
> >> >
> >> > Thank you for your email. This is definitely undesirable behaviour,
> >> > I will have a look at the code to see why this is happening. Does
> >> > it always revert to quiet on boot, or always the mode that you had
> >> > switched to prior to reboot?
> >> >
> >> > Do you happen to have power-profiles-daemon or something similar
> >> > running? My understanding is it remembers profiles across reboots,
> >> > this could potentially also revert the profile back to what it was.
> >> > See this release for details:
> >> > https://urldefense.com/v3/__https://gitlab.freedesktop.org/upower/p
> >> > owe
> >> > r-profiles-daemon/-/releases/0.9.0__;!!LpKI!jUAEHb-9foumkcmPlEKD6tn
> >> > QrZ sqjB1sXdPDsYvH2fJ-
> gPV6G35MUtDW4q3xhlJ4IeLcIgmVpb3ztXqaOg8$
> >> > [gitlab[.]freedesktop[.]org]
> >> >
> >> > I will assume there is a bug in my code at this point. I will test
> >> > with and without ppd running on my system to see if it changes
> >> > across reboots.
> >> >
> >> > Are USTT settings exposed in your BIOS configuration menu? On my
> >> > laptop they are not and I have to use smbios-thermal-ctl.
> >> >
> >> > Thank you,
> >> >
> >> > Lyndon
> >>
> >> Hi Yijun:
> >>
> >> I tested this on my computer (XPS 9560). I do not have access to the
> >> USTT settings in the BIOS screen so to substitute that, I booted
> >> without the patch and set the USTT manually using smbios-thermal-ctl.
> >> Here are my findings:
> >>
> >> Scenario #1: Without power-profiles-daemon (ppd) running
> >>
> >> 1. Boot with patch, set platform_profile to quiet 2. Boot without
> >> patch applied (no platform_profile)
> >>  - smbios-thermal-ctl confirms USTT is set to quiet
> >>  - use smbios-thermal-ctl to set USTT to performance
> >>  - confirm set to performance
> >> 3. Boot with patch again
> >>  - platform_profile is set to performance
> >>
> >> Scenario #2: With ppd running
> >> 1. Boot with patch, set platform_profile to performance with ppd
> >>  - Confirm platform_profile is performance 2. Boot without patch
> >> applied (no
> >> platform_profile)
> >>  - smbios-thermal-ctl confirms USTT is set to performance
> >>  - ppd reverts to balanced (only controlling intel_pstate in this
> >> case)
> >>  - use smbios-thermal-ctl to set USTT to quiet
> >>  - confirm set to quiet
> >> 3. Boot with patch again
> >>  - platform_profile and ppd is set to performance
> >>
> >> In my case, the setting in the smbios is honored if it was switched
> >> with another method. When using a userspace program that manipulates
> >> the platform_profile, the program seems to remember the previous
> >> state and switch to that.
> >>
> >> So I do not think there is a bug in this patch related to this issue,
> >> at least in my case. Please let me know if you have any questions.
> >>
> >> Thanks,
> >>
> >> Lyndon
> >>
> >>
> >>
> >Hi Lyndon,
> >
> > I've made a video recorder of the issue:
> >
> https://urldefense.com/v3/__https://dell.box.com/s/3f3znz1z8c6htbcll9juj6ty
> yu0zvvut__;!!LpKI!nHHxFbxzG-rJX_KZsebMC7ZcJU0WhNhkpXn-pk6nu-sUF38-
> RXz6x3YkALgzS4jnUP9TIWIu4mX_6cSDbwQ$ [dell[.]box[.]com] My test
> environment is that I freshly installed the Fedora 40 and will not do any online
> updates. Then install the kernel with the v5 patch applied.
> >
> > XPS 9560 is a pretty old system which is RTS with 2017. No USTT setting in
> the BIOS is expected.
> > I've a check that the Dell system, at least shipped from 2022, the USTT
> setting will be valid in the BIOS. The system used in above link, it is Latitude
> 7350 which is shipped by 2024 April.
> >
> > I think the key point to duplicate of this issue that, the USTT needs to be
> changed under BIOS but not under the Linux OS.
> >
> >Thanks
> >
> >
>
>
> Thanks for the video.
>
> Fedora 40 has power-profiles-daemon enabled by default AFAIK. This would
> be changing the platform profile at load to match the last known state.
>
> Are you able to rerun this test with PPD disabled? Just in case it is a difference
> between setting it in BIOS and smbios-thermal-ctl.
>
> Thanks,
>
> Lyndon

 If disable the PPD, the issue is gone.

Thanks


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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:16   ` Limonciello, Mario
  2024-05-11 15:59     ` Lyndon Sanche
@ 2024-05-12  0:14     ` Lyndon Sanche
  1 sibling, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-12  0:14 UTC (permalink / raw)
  To: Limonciello, Mario
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp, hdegoede,
	Yijun.Shen, Matthew Garrett, Heiner Kallweit, Randy Dunlap,
	Jonathan Corbet, Vegard Nossum, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



>> 
>>   }
>>   \x7f  /* dell-rbtn.c driver export functions which will not work 
>> correctly (and could
>> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c 
>> b/drivers/platform/x86/dell/dell-smbios-base.c
>> index 6ae09d7f76fb..387fa5618f7a 100644
>> --- a/drivers/platform/x86/dell/dell-smbios-base.c
>> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
>> @@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
>>   	/* handled by kernel: dell-laptop */
>>   	{0x0000, CLASS_INFO, SELECT_RFKILL},
>>   	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
>> +	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>>   };
> 
> So when Alex checked on v5 that this doesn't load on workstations, it 
> has made me realize that doing this will block the interface totally 
> even on workstations.
> 
> So I think there are a few ways to go to handle this:
> 
> 1) Rename dell-laptop to dell-client or dell-pc and let dell-laptop 
> load on more form factors.  This would require some internal handling 
> in the module for which features make sense for different form 
> factors.
> 
> 2) Add a new module just for the thermal handling and put all this 
> code into it instead.
> 
> I don't have a strong opinion, but I do think one of them should be 
> done to ensure there aren't problems on workstations losing access to 
> thermal control.

My apologies, I accidentally sent my response in HTML format. Please 
see plain-text below:

Thinking about it more, we can leave dell-laptop as-is and create a 
common dell-pc module that does not check for specific form-factors, 
assuming that is possible. Thermal management can be the first function 
to go in there.

We will still block the calls from userspace regardless of which 
modules are loaded. If dell-pc fails because thermal management is not 
supported, we aren't losing anything by blocking that call anyway.

Thoughts?



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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
       [not found]       ` <48JCDS.E4RT1F9DTKFU1@lyndeno.ca>
@ 2024-05-12  1:43         ` Limonciello, Mario
  2024-05-12 15:25           ` Hans de Goede
  0 siblings, 1 reply; 72+ messages in thread
From: Limonciello, Mario @ 2024-05-12  1:43 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp, hdegoede,
	Yijun.Shen, Matthew Garrett, Heiner Kallweit, Randy Dunlap,
	Jonathan Corbet, Vegard Nossum, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel



On 5/11/2024 7:12 PM, Lyndon Sanche wrote:
> 
> 
> On Sat, May 11 2024 at 09:59:17 AM -06:00:00, Lyndon Sanche 
> <lsanche@lyndeno.ca> wrote:
>> On May 11, 2024 9:16:56 a.m. MDT, "Limonciello, Mario" 
>> <mario.limonciello@amd.com <mailto:mario.limonciello@amd.com>> wrote:
>>
>>     On 5/10/2024 9:36 PM, Lyndon Sanche wrote:
>>
>>         index 6ae09d7f76fb..387fa5618f7a 100644 ---
>>         a/drivers/platform/x86/dell/dell-smbios-base.c +++
>>         b/drivers/platform/x86/dell/dell-smbios-base.c @@ -71,6 +71,7
>>         @@ static struct smbios_call call_blacklist[] = { /* handled
>>         by kernel: dell-laptop */ {0x0000, CLASS_INFO, SELECT_RFKILL},
>>         {0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT}, +
>>         {0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT}, }; 
>>
>>     So when Alex checked on v5 that this doesn't load on workstations,
>>     it has made me realize that doing this will block the interface
>>     totally even on workstations. So I think there are a few ways to
>>     go to handle this: 1) Rename dell-laptop to dell-client or dell-pc
>>     and let dell-laptop load on more form factors. This would require
>>     some internal handling in the module for which features make sense
>>     for different form factors. 2) Add a new module just for the
>>     thermal handling and put all this code into it instead. I don't
>>     have a strong opinion, but I do think one of them should be done
>>     to ensure there aren't problems on workstations losing access to
>>     thermal control. 
>>
>> A dell-client/laptop separation makes more sense IMO. I don't think 
>> keyboard control would belong in a the dell-client module either. 
>> Separating just thermal control would be easier, but not as clean I 
>> think. Thanks, Lyndon
> 
> Thinking about it more, we can leave dell-laptop as-is and create a 
> common dell-pc module that does not check for specific form-factors, 
> assuming that is possible. Thermal management can be the first function 
> to go in there.
> 
> We will still block the calls from userspace regardless of which modules 
> are loaded. If dell-pc fails because thermal management is not 
> supported, we aren't losing anything by blocking that call anyway.
> 
> Thoughts?

Sounds good by me.  So basically laptops will load both dell-pc and 
dell-laptop and workstations would load dell-pc.

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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-05-12  1:43         ` Limonciello, Mario
@ 2024-05-12 15:25           ` Hans de Goede
  0 siblings, 0 replies; 72+ messages in thread
From: Hans de Goede @ 2024-05-12 15:25 UTC (permalink / raw)
  To: Limonciello, Mario, Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp,
	Yijun.Shen, Matthew Garrett, Heiner Kallweit, Randy Dunlap,
	Jonathan Corbet, Vegard Nossum, platform-driver-x86,
	linux-kernel, Dell.Client.Kernel

Hi,

On 5/12/24 3:43 AM, Limonciello, Mario wrote:
> 
> 
> On 5/11/2024 7:12 PM, Lyndon Sanche wrote:
>>
>>
>> On Sat, May 11 2024 at 09:59:17 AM -06:00:00, Lyndon Sanche <lsanche@lyndeno.ca> wrote:
>>> On May 11, 2024 9:16:56 a.m. MDT, "Limonciello, Mario" <mario.limonciello@amd.com <mailto:mario.limonciello@amd.com>> wrote:
>>>
>>>     On 5/10/2024 9:36 PM, Lyndon Sanche wrote:
>>>
>>>         index 6ae09d7f76fb..387fa5618f7a 100644 ---
>>>         a/drivers/platform/x86/dell/dell-smbios-base.c +++
>>>         b/drivers/platform/x86/dell/dell-smbios-base.c @@ -71,6 +71,7
>>>         @@ static struct smbios_call call_blacklist[] = { /* handled
>>>         by kernel: dell-laptop */ {0x0000, CLASS_INFO, SELECT_RFKILL},
>>>         {0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT}, +
>>>         {0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT}, };
>>>     So when Alex checked on v5 that this doesn't load on workstations,
>>>     it has made me realize that doing this will block the interface
>>>     totally even on workstations. So I think there are a few ways to
>>>     go to handle this: 1) Rename dell-laptop to dell-client or dell-pc
>>>     and let dell-laptop load on more form factors. This would require
>>>     some internal handling in the module for which features make sense
>>>     for different form factors. 2) Add a new module just for the
>>>     thermal handling and put all this code into it instead. I don't
>>>     have a strong opinion, but I do think one of them should be done
>>>     to ensure there aren't problems on workstations losing access to
>>>     thermal control.
>>> A dell-client/laptop separation makes more sense IMO. I don't think keyboard control would belong in a the dell-client module either. Separating just thermal control would be easier, but not as clean I think. Thanks, Lyndon
>>
>> Thinking about it more, we can leave dell-laptop as-is and create a common dell-pc module that does not check for specific form-factors, assuming that is possible. Thermal management can be the first function to go in there.
>>
>> We will still block the calls from userspace regardless of which modules are loaded. If dell-pc fails because thermal management is not supported, we aren't losing anything by blocking that call anyway.
>>
>> Thoughts?
> 
> Sounds good by me.  So basically laptops will load both dell-pc and dell-laptop and workstations would load dell-pc.

Ack this sounds good to me too.

Regards,

Hans




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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11 15:56           ` Shen, Yijun
@ 2024-05-12 17:53             ` Armin Wolf
  2024-05-12 17:58               ` Limonciello, Mario
  0 siblings, 1 reply; 72+ messages in thread
From: Armin Wolf @ 2024-05-12 17:53 UTC (permalink / raw)
  To: Shen, Yijun, Limonciello, Mario, Lyndon Sanche
  Cc: pali, srinivas.pandruvada, ilpo.jarvinen, lkp, Hans de Goede,
	Matthew Garrett, Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell Client Kernel

Am 11.05.24 um 17:56 schrieb Shen, Yijun:

> Internal Use - Confidential
>> -----Original Message-----
>> From: Limonciello, Mario <mario.limonciello@amd.com>
>> Sent: Saturday, May 11, 2024 11:13 PM
>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>> <lsanche@lyndeno.ca>
>> Cc: pali@kernel.org; W_Armin@gmx.de;
>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; Dell Client
>> Kernel <Dell.Client.Kernel@dell.com>
>> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
>>
>>
>> [EXTERNAL EMAIL]
>>
>>
>>
>> On 5/11/2024 10:05 AM, Shen, Yijun wrote:
>>> Internal Use - Confidential
>>>> -----Original Message-----
>>>> From: Mario Limonciello <mario.limonciello@amd.com>
>>>> Sent: Wednesday, May 8, 2024 11:53 PM
>>>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>>>> <lsanche@lyndeno.ca>
>>>> Cc: pali@kernel.org; W_Armin@gmx.de;
>>>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>>>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew
>> Garrett
>>>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner
>>>> Kallweit <hkallweit1@gmail.com>; Vegard Nossum
>>>> <vegard.nossum@oracle.com>; platform-driver-x86@vger.kernel.org;
>>>> linux-kernel@vger.kernel.org; Dell Client Kernel
>>>> <Dell.Client.Kernel@dell.com>
>>>> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
>>>> platform_profile
>>>>
>>>>
>>>> [EXTERNAL EMAIL]
>>>>
>>>> On 5/8/2024 09:24, Shen, Yijun wrote:
>>>>> Hi Lyndon,
>>>>>
>>>>>     Thanks for working on this patch.
>>>>>
>>>>>     Dell side has an initial testing with this patch on some laptops,
>>>>> it looks
>>>> good. While changing the platform profile:
>>>>> 1. The corresponding USTT option in BIOS will be changed.
>>>>> 2. thermald will not be impacted. The related PSVT and ITMT will be
>> loaded.
>>>>>     Some Dell DTs does not have the USTT, Dell'll have a check if
>>>>> nothing is
>>>> broken.
>>>>
>>>> Hi Alex!
>>>>
>>>> Have you had a check both on both your AMD laptops and workstations
>>>> too, or just the Intel ones?  I think it would be good to make sure
>>>> it's getting the correct experience in both cases.
>>>>
>>> Hi Mario,
>>>
>>>    I've a check for this, for both laptop and workstation, the dell_laptop
>> module will not be loaded. So, AMD platform will not be impacted by this
>> patch series.
>>> Follow is one example output with workstation.
>>>    #lsmod | grep dell
>>>      dell_wmi               28672  0
>>>      dell_smbios            32768  1 dell_wmi
>>>      dcdbas                 20480  1 dell_smbios
>>>      dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
>>>      sparse_keymap          12288  1 dell_wmi
>>>      ledtrig_audio          12288  3 snd_ctl_led,snd_hda_codec_generic,dell_wmi
>>>      video                  73728  2 dell_wmi,nvidia_modeset
>>>      wmi                    40960  5
>> video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor
>> Ah; right that makes sense.  In that case, is dell-laptop even the right place for
>> this patch series?  I would think the same policies for the platform profile
>> should be able to apply to desktop/workstation.
>>
>> The v6 of this series would block smbios-thermal-ctl from working on a
>> workstation too.
>>
>>>>>      Additional, with this patch, follow behavior is found:
>>>>>     1. For example, the platform profile is quiet.
>>>>>     2. Reboot the system and change the USTT to performance.
>>>>>     3. Boot to desktop, the platform profile is "quiet", the USTT
>>>>> will be
>>>> changed back to "quiet".
>>>>>     This looks like not a proper user experience. The platform
>>>>> profile should
>>>> honor the BIOS setting, aka, the platform profile should be switched
>>>> to "performance".
>>>> I agree, this sounds like the initial profile needs to be read from
>>>> the BIOS settings too.
>>>>
>>>> Furthermore I wanted to ask is there also a WMI setting that
>>>> corresponds to this that dell-wmi-sysman offers?
>>>    Yes, Mario, you're right. This thermal setting could also be toggled by dell-
>> wmi-sysman.
>>> But, for the Dell consumer AMD laptops, like Alienware, the BIOS is another
>> variant which is different with the workstation one.
>>> With this variant BIOS, there is no USTT and also no dell_wmi/dell-wmi-
>> sysman.
>>>> I'm wondering if both should be probed in case the SMBIOS one goes
>> away one day.
>>>    Yep, I think this is a good suggestion.
>>>
>> Great! Although something I wonder is if the policy when changed with dell-
>> wmi-sysman is immediate or requires a reboot.  A lot of the settings in there
>> aren't effective until after a reboot.
>>
>> If this is one of them then it might not be a good idea to make it work for
>> both.
> Hi Mario,
>
>   Just have a check, the check steps are:
> 1. stop the thermald
> 2. run the stress test
> 3. Toggle the thermal setting between UltraPerformance and Quiet via dell-wmi-sysman
> 4. Check the CPU FAN speed
>   The system reboot is not needed, the CPU fan speed changes immediately.
>   A screen recorder here: https://dell.box.com/s/p2bhd2b6cv8z5buk9eao3bosgrrp1lf9
>
> Thanks
>
Hi,

i believe it should be the responsibility of the manufacturer (in this case Dell) that
the thermal state remains consistent across both interfaces.

I think that the official Windows utility only checks the thermal state reported by
the USTT interface, so we should match this behavior.

Thanks,
Armin Wolf


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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-12 17:53             ` Armin Wolf
@ 2024-05-12 17:58               ` Limonciello, Mario
  2024-05-12 18:47                 ` Armin Wolf
  0 siblings, 1 reply; 72+ messages in thread
From: Limonciello, Mario @ 2024-05-12 17:58 UTC (permalink / raw)
  To: Armin Wolf, Shen, Yijun, Lyndon Sanche
  Cc: pali, srinivas.pandruvada, ilpo.jarvinen, lkp, Hans de Goede,
	Matthew Garrett, Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell Client Kernel



On 5/12/2024 12:53 PM, Armin Wolf wrote:
> Am 11.05.24 um 17:56 schrieb Shen, Yijun:
> 
>> Internal Use - Confidential
>>> -----Original Message-----
>>> From: Limonciello, Mario <mario.limonciello@amd.com>
>>> Sent: Saturday, May 11, 2024 11:13 PM
>>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>>> <lsanche@lyndeno.ca>
>>> Cc: pali@kernel.org; W_Armin@gmx.de;
>>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
>>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner Kallweit
>>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>>> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org; 
>>> Dell Client
>>> Kernel <Dell.Client.Kernel@dell.com>
>>> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement 
>>> platform_profile
>>>
>>>
>>> [EXTERNAL EMAIL]
>>>
>>>
>>>
>>> On 5/11/2024 10:05 AM, Shen, Yijun wrote:
>>>> Internal Use - Confidential
>>>>> -----Original Message-----
>>>>> From: Mario Limonciello <mario.limonciello@amd.com>
>>>>> Sent: Wednesday, May 8, 2024 11:53 PM
>>>>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>>>>> <lsanche@lyndeno.ca>
>>>>> Cc: pali@kernel.org; W_Armin@gmx.de;
>>>>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>>>>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew
>>> Garrett
>>>>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner
>>>>> Kallweit <hkallweit1@gmail.com>; Vegard Nossum
>>>>> <vegard.nossum@oracle.com>; platform-driver-x86@vger.kernel.org;
>>>>> linux-kernel@vger.kernel.org; Dell Client Kernel
>>>>> <Dell.Client.Kernel@dell.com>
>>>>> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
>>>>> platform_profile
>>>>>
>>>>>
>>>>> [EXTERNAL EMAIL]
>>>>>
>>>>> On 5/8/2024 09:24, Shen, Yijun wrote:
>>>>>> Hi Lyndon,
>>>>>>
>>>>>>     Thanks for working on this patch.
>>>>>>
>>>>>>     Dell side has an initial testing with this patch on some laptops,
>>>>>> it looks
>>>>> good. While changing the platform profile:
>>>>>> 1. The corresponding USTT option in BIOS will be changed.
>>>>>> 2. thermald will not be impacted. The related PSVT and ITMT will be
>>> loaded.
>>>>>>     Some Dell DTs does not have the USTT, Dell'll have a check if
>>>>>> nothing is
>>>>> broken.
>>>>>
>>>>> Hi Alex!
>>>>>
>>>>> Have you had a check both on both your AMD laptops and workstations
>>>>> too, or just the Intel ones?  I think it would be good to make sure
>>>>> it's getting the correct experience in both cases.
>>>>>
>>>> Hi Mario,
>>>>
>>>>    I've a check for this, for both laptop and workstation, the 
>>>> dell_laptop
>>> module will not be loaded. So, AMD platform will not be impacted by this
>>> patch series.
>>>> Follow is one example output with workstation.
>>>>    #lsmod | grep dell
>>>>      dell_wmi               28672  0
>>>>      dell_smbios            32768  1 dell_wmi
>>>>      dcdbas                 20480  1 dell_smbios
>>>>      dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
>>>>      sparse_keymap          12288  1 dell_wmi
>>>>      ledtrig_audio          12288  3 
>>>> snd_ctl_led,snd_hda_codec_generic,dell_wmi
>>>>      video                  73728  2 dell_wmi,nvidia_modeset
>>>>      wmi                    40960  5
>>> video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor
>>> Ah; right that makes sense.  In that case, is dell-laptop even the 
>>> right place for
>>> this patch series?  I would think the same policies for the platform 
>>> profile
>>> should be able to apply to desktop/workstation.
>>>
>>> The v6 of this series would block smbios-thermal-ctl from working on a
>>> workstation too.
>>>
>>>>>>      Additional, with this patch, follow behavior is found:
>>>>>>     1. For example, the platform profile is quiet.
>>>>>>     2. Reboot the system and change the USTT to performance.
>>>>>>     3. Boot to desktop, the platform profile is "quiet", the USTT
>>>>>> will be
>>>>> changed back to "quiet".
>>>>>>     This looks like not a proper user experience. The platform
>>>>>> profile should
>>>>> honor the BIOS setting, aka, the platform profile should be switched
>>>>> to "performance".
>>>>> I agree, this sounds like the initial profile needs to be read from
>>>>> the BIOS settings too.
>>>>>
>>>>> Furthermore I wanted to ask is there also a WMI setting that
>>>>> corresponds to this that dell-wmi-sysman offers?
>>>>    Yes, Mario, you're right. This thermal setting could also be 
>>>> toggled by dell-
>>> wmi-sysman.
>>>> But, for the Dell consumer AMD laptops, like Alienware, the BIOS is 
>>>> another
>>> variant which is different with the workstation one.
>>>> With this variant BIOS, there is no USTT and also no dell_wmi/dell-wmi-
>>> sysman.
>>>>> I'm wondering if both should be probed in case the SMBIOS one goes
>>> away one day.
>>>>    Yep, I think this is a good suggestion.
>>>>
>>> Great! Although something I wonder is if the policy when changed with 
>>> dell-
>>> wmi-sysman is immediate or requires a reboot.  A lot of the settings 
>>> in there
>>> aren't effective until after a reboot.
>>>
>>> If this is one of them then it might not be a good idea to make it 
>>> work for
>>> both.
>> Hi Mario,
>>
>>   Just have a check, the check steps are:
>> 1. stop the thermald
>> 2. run the stress test
>> 3. Toggle the thermal setting between UltraPerformance and Quiet via 
>> dell-wmi-sysman
>> 4. Check the CPU FAN speed
>>   The system reboot is not needed, the CPU fan speed changes immediately.
>>   A screen recorder here: 
>> https://dell.box.com/s/p2bhd2b6cv8z5buk9eao3bosgrrp1lf9
>>
>> Thanks
>>
> Hi,
> 
> i believe it should be the responsibility of the manufacturer (in this 
> case Dell) that
> the thermal state remains consistent across both interfaces.
> 
> I think that the official Windows utility only checks the thermal state 
> reported by
> the USTT interface, so we should match this behavior.
> 
> Thanks,
> Armin Wolf
> 

Why?  Windows also does ACPI-WMI differently than Linux.  It's not as 
easy to check both from a Windows utility due to that.

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

* Re: [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands
  2024-05-11  2:36 ` [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands Lyndon Sanche
  2024-05-11 15:13   ` Limonciello, Mario
@ 2024-05-12 18:00   ` Armin Wolf
  1 sibling, 0 replies; 72+ messages in thread
From: Armin Wolf @ 2024-05-12 18:00 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, pali, srinivas.pandruvada, ilpo.jarvinen, lkp,
	hdegoede, Yijun.Shen, Matthew Garrett, Heiner Kallweit,
	Randy Dunlap, Vegard Nossum, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Am 11.05.24 um 04:36 schrieb Lyndon Sanche:

> Add symbol to check if a specific class of smbios command is supported.
>
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
>   drivers/platform/x86/dell/dell-smbios-base.c | 6 ++++++
>   drivers/platform/x86/dell/dell-smbios.h      | 1 +
>   2 files changed, 7 insertions(+)
>
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
> index e61bfaf8b5c4..6ae09d7f76fb 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -350,6 +350,12 @@ void dell_laptop_call_notifier(unsigned long action, void *data)
>   }
>   EXPORT_SYMBOL_GPL(dell_laptop_call_notifier);
>
> +bool dell_laptop_check_supported_cmds(u16 class)
> +{

Hi,

the function dell_smbios_call_filter() says that classes above 30 are always unsupported,
so please check this here too.

Also please rename the function to something like dell_smbios_class_is_supported().

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

> +	return da_supported_commands & (1 << class);
> +}
> +EXPORT_SYMBOL_GPL(dell_laptop_check_supported_cmds);
> +
>   static void __init parse_da_table(const struct dmi_header *dm)
>   {
>   	/* Final token is a terminator, so we don't want to copy it */
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index eb341bf000c6..63116671eada 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -73,6 +73,7 @@ enum dell_laptop_notifier_actions {
>   int dell_laptop_register_notifier(struct notifier_block *nb);
>   int dell_laptop_unregister_notifier(struct notifier_block *nb);
>   void dell_laptop_call_notifier(unsigned long action, void *data);
> +bool dell_laptop_check_supported_cmds(u16 class);
>
>   /* for the supported backends */
>   #ifdef CONFIG_DELL_SMBIOS_WMI

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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-05-11  2:36 ` [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
  2024-05-11 15:16   ` Limonciello, Mario
@ 2024-05-12 18:05   ` Armin Wolf
  2024-05-15 17:06     ` Lyndon Sanche
  1 sibling, 1 reply; 72+ messages in thread
From: Armin Wolf @ 2024-05-12 18:05 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: mario.limonciello, pali, srinivas.pandruvada, ilpo.jarvinen, lkp,
	hdegoede, Yijun.Shen, Matthew Garrett, Heiner Kallweit,
	Randy Dunlap, Jonathan Corbet, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell.Client.Kernel

Am 11.05.24 um 04:36 schrieb Lyndon Sanche:

> Some Dell laptops support configuration of preset fan modes through
> smbios tables.
>
> If the platform supports these fan modes, set up platform_profile to
> change these modes. If not supported, skip enabling platform_profile.
>
> Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
> ---
>   drivers/platform/x86/dell/Kconfig            |   2 +
>   drivers/platform/x86/dell/dell-laptop.c      | 242 +++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios-base.c |   1 +
>   drivers/platform/x86/dell/dell-smbios.h      |   1 +
>   4 files changed, 246 insertions(+)
>
> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
> index bd9f445974cc..26679f22733c 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -47,6 +47,7 @@ config DCDBAS
>   config DELL_LAPTOP
>   	tristate "Dell Laptop Extras"
>   	default m
> +	depends on ACPI
>   	depends on DMI
>   	depends on BACKLIGHT_CLASS_DEVICE
>   	depends on ACPI_VIDEO || ACPI_VIDEO = n
> @@ -57,6 +58,7 @@ config DELL_LAPTOP
>   	select POWER_SUPPLY
>   	select LEDS_CLASS
>   	select NEW_LEDS
> +	select ACPI_PLATFORM_PROFILE
>   	help
>   	This driver adds support for rfkill and backlight control to Dell
>   	laptops (except for some models covered by the Compal driver).
> diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
> index 42f7de2b4522..07f54f1cbac5 100644
> --- a/drivers/platform/x86/dell/dell-laptop.c
> +++ b/drivers/platform/x86/dell/dell-laptop.c
> @@ -27,6 +27,9 @@
>   #include <linux/i8042.h>
>   #include <linux/debugfs.h>
>   #include <linux/seq_file.h>
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/platform_profile.h>
>   #include <acpi/video.h>
>   #include "dell-rbtn.h"
>   #include "dell-smbios.h"
> @@ -95,6 +98,7 @@ static struct backlight_device *dell_backlight_device;
>   static struct rfkill *wifi_rfkill;
>   static struct rfkill *bluetooth_rfkill;
>   static struct rfkill *wwan_rfkill;
> +static struct platform_profile_handler *thermal_handler;
>   static bool force_rfkill;
>   static bool micmute_led_registered;
>   static bool mute_led_registered;
> @@ -2199,6 +2203,236 @@ static int mute_led_set(struct led_classdev *led_cdev,
>   	return 0;
>   }
>
> +/* Derived from smbios-thermal-ctl
> + *
> + * cbClass 17
> + * cbSelect 19
> + * User Selectable Thermal Tables(USTT)
> + * cbArg1 determines the function to be performed
> + * cbArg1 0x0 = Get Thermal Information
> + *  cbRES1         Standard return codes (0, -1, -2)
> + *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
> + *                  its bit is set to 1
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
> + *                 Each mode corresponds to the supported thermal modes in
> + *                  byte 0. A mode is supported if its bit is set to 1.
> + *     Bit 0 AAC (Balanced)
> + *     Bit 1 AAC (Cool Bottom
> + *     Bit 2 AAC (Quiet)
> + *     Bit 3 AAC (Performance)
> + *  cbRes3, byte 0 Current Thermal Mode
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performanc
> + *  cbRes3, byte 1  AAC Configuration type
> + *          0       Global (AAC enable/disable applies to all supported USTT modes)
> + *          1       USTT mode specific
> + *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
> + *     If AAC Configuration Type is Global,
> + *          0       AAC mode disabled
> + *          1       AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
> + *          Bit 0 AAC (Balanced)
> + *          Bit 1 AAC (Cool Bottom
> + *          Bit 2 AAC (Quiet)
> + *          Bit 3 AAC (Performance)
> + *  cbRes3, byte 3  Current Fan Failure Mode
> + *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
> + *     Bit 1 Catastrophic Fan Failure (all fans have failed)
> + *
> + * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
> + *               desired AAC mode shall be applied
> + * cbArg2, byte 0  Desired Thermal Mode to set
> + *                  (only one bit may be set for this parameter)
> + *     Bit 0 Balanced
> + *     Bit 1 Cool Bottom
> + *     Bit 2 Quiet
> + *     Bit 3 Performance
> + * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
> + *     If AAC Configuration Type is Global,
> + *         0  AAC mode disabled
> + *         1  AAC mode enabled
> + *     If AAC Configuration Type is USTT mode specific
> + *     (multiple bits may be set for this parameter),
> + *         Bit 0 AAC (Balanced)
> + *         Bit 1 AAC (Cool Bottom
> + *         Bit 2 AAC (Quiet)
> + *         Bit 3 AAC (Performance)
> + */
> +
> +#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
> +#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
> +#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
> +
> +enum thermal_mode_bits {
> +	DELL_BALANCED = BIT(0),
> +	DELL_COOL_BOTTOM = BIT(1),
> +	DELL_QUIET = BIT(2),
> +	DELL_PERFORMANCE = BIT(3),
> +};
> +
> +static int thermal_get_mode(void)
> +{
> +	struct calling_interface_buffer buffer;
> +	int state;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	state = buffer.output[2];
> +	if (state & DELL_BALANCED)
> +		return DELL_BALANCED;
> +	else if (state & DELL_COOL_BOTTOM)
> +		return DELL_COOL_BOTTOM;
> +	else if (state & DELL_QUIET)
> +		return DELL_QUIET;
> +	else if (state & DELL_PERFORMANCE)
> +		return DELL_PERFORMANCE;
> +	else
> +		return -ENXIO;
> +}
> +
> +static int thermal_get_supported_modes(int *supported_bits)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
> +	return 0;
> +}
> +
> +static int thermal_get_acc_mode(int *acc_mode)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +
> +	dell_fill_request(&buffer, 0x0, 0, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	if (ret)
> +		return ret;
> +	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
> +	return 0;
> +}
> +
> +static int thermal_set_mode(enum thermal_mode_bits state)
> +{
> +	struct calling_interface_buffer buffer;
> +	int ret;
> +	int acc_mode;
> +
> +	ret = thermal_get_acc_mode(&acc_mode);
> +	if (ret)
> +		return ret;
> +
> +	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
> +	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
> +	return ret;
> +}
> +
> +static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
> +					enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_BALANCED:
> +		return thermal_set_mode(DELL_BALANCED);
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return thermal_set_mode(DELL_PERFORMANCE);
> +	case PLATFORM_PROFILE_QUIET:
> +		return thermal_set_mode(DELL_QUIET);
> +	case PLATFORM_PROFILE_COOL:
> +		return thermal_set_mode(DELL_COOL_BOTTOM);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
> +					enum platform_profile_option *profile)
> +{
> +	int ret;
> +
> +	ret = thermal_get_mode();
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (ret) {
> +	case DELL_BALANCED:
> +		*profile = PLATFORM_PROFILE_BALANCED;
> +		break;
> +	case DELL_PERFORMANCE:
> +		*profile = PLATFORM_PROFILE_PERFORMANCE;
> +		break;
> +	case DELL_COOL_BOTTOM:
> +		*profile = PLATFORM_PROFILE_COOL;
> +		break;
> +	case DELL_QUIET:
> +		*profile = PLATFORM_PROFILE_QUIET;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int thermal_init(void)
> +{
> +	int ret;
> +	int supported_modes;
> +
> +	/* If thermal commands not supported, exit without error */
> +	if (!dell_laptop_check_supported_cmds(CLASS_INFO))
> +		return 0;
> +
> +	/* If thermal modes not supported, exit without error */
> +	ret = thermal_get_supported_modes(&supported_modes);
> +	if (ret < 0)
> +		return ret;

Hi,

the function dell_smbios_error() says that when a specific functionality is
not supported, -ENXIO is returned.

Please treat this as "no thermal modes supported", since checking if CLASS_INFO
is supported is not enough (CLASS_INFO is also used by other functionality like
rfkill, so machines might support CLASS_INFO but not USTT).

Thanks,
Armin Wolf

> +	if (!supported_modes)
> +		return 0;
> +
> +	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
> +	if (!thermal_handler)
> +		return -ENOMEM;
> +	thermal_handler->profile_get = thermal_platform_profile_get;
> +	thermal_handler->profile_set = thermal_platform_profile_set;
> +
> +	if (supported_modes & DELL_QUIET)
> +		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
> +	if (supported_modes & DELL_COOL_BOTTOM)
> +		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
> +	if (supported_modes & DELL_BALANCED)
> +		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
> +	if (supported_modes & DELL_PERFORMANCE)
> +		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
> +
> +	/* Clean up if failed */
> +	ret = platform_profile_register(thermal_handler);
> +	if (ret)
> +		kfree(thermal_handler);
> +
> +	return ret;
> +}
> +
> +static void thermal_cleanup(void)
> +{
> +	if (thermal_handler) {
> +		platform_profile_remove();
> +		kfree(thermal_handler);
> +	}
> +}
> +
>   static struct led_classdev mute_led_cdev = {
>   	.name = "platform::mute",
>   	.max_brightness = 1,
> @@ -2238,6 +2472,11 @@ static int __init dell_init(void)
>   		goto fail_rfkill;
>   	}
>
> +	/* Do not fail module if thermal modes not supported, just skip */
> +	ret = thermal_init();
> +	if (ret)
> +		goto fail_thermal;
> +
>   	if (quirks && quirks->touchpad_led)
>   		touchpad_led_init(&platform_device->dev);
>
> @@ -2317,6 +2556,8 @@ static int __init dell_init(void)
>   		led_classdev_unregister(&mute_led_cdev);
>   fail_led:
>   	dell_cleanup_rfkill();
> +fail_thermal:
> +	thermal_cleanup();
>   fail_rfkill:
>   	platform_device_del(platform_device);
>   fail_platform_device2:
> @@ -2344,6 +2585,7 @@ static void __exit dell_exit(void)
>   		platform_device_unregister(platform_device);
>   		platform_driver_unregister(&platform_driver);
>   	}
> +	thermal_cleanup();
>   }
>
>   /* dell-rbtn.c driver export functions which will not work correctly (and could
> diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
> index 6ae09d7f76fb..387fa5618f7a 100644
> --- a/drivers/platform/x86/dell/dell-smbios-base.c
> +++ b/drivers/platform/x86/dell/dell-smbios-base.c
> @@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
>   	/* handled by kernel: dell-laptop */
>   	{0x0000, CLASS_INFO, SELECT_RFKILL},
>   	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
> +	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
>   };
>
>   struct token_range {
> diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
> index 63116671eada..5d7178df80c6 100644
> --- a/drivers/platform/x86/dell/dell-smbios.h
> +++ b/drivers/platform/x86/dell/dell-smbios.h
> @@ -19,6 +19,7 @@
>   /* Classes and selects used only in kernel drivers */
>   #define CLASS_KBD_BACKLIGHT 4
>   #define SELECT_KBD_BACKLIGHT 11
> +#define SELECT_THERMAL_MANAGEMENT 19
>
>   /* Tokens used in kernel drivers, any of these
>    * should be filtered from userspace access

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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-12 17:58               ` Limonciello, Mario
@ 2024-05-12 18:47                 ` Armin Wolf
  2024-05-12 22:14                   ` Limonciello, Mario
  0 siblings, 1 reply; 72+ messages in thread
From: Armin Wolf @ 2024-05-12 18:47 UTC (permalink / raw)
  To: Limonciello, Mario, Shen, Yijun, Lyndon Sanche
  Cc: pali, srinivas.pandruvada, ilpo.jarvinen, lkp, Hans de Goede,
	Matthew Garrett, Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell Client Kernel

Am 12.05.24 um 19:58 schrieb Limonciello, Mario:

>
>
> On 5/12/2024 12:53 PM, Armin Wolf wrote:
>> Am 11.05.24 um 17:56 schrieb Shen, Yijun:
>>
>>> Internal Use - Confidential
>>>> -----Original Message-----
>>>> From: Limonciello, Mario <mario.limonciello@amd.com>
>>>> Sent: Saturday, May 11, 2024 11:13 PM
>>>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>>>> <lsanche@lyndeno.ca>
>>>> Cc: pali@kernel.org; W_Armin@gmx.de;
>>>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>>>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew Garrett
>>>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner
>>>> Kallweit
>>>> <hkallweit1@gmail.com>; Vegard Nossum <vegard.nossum@oracle.com>;
>>>> platform-driver-x86@vger.kernel.org; linux-kernel@vger.kernel.org;
>>>> Dell Client
>>>> Kernel <Dell.Client.Kernel@dell.com>
>>>> Subject: Re: [PATCH v5] platform/x86: dell-laptop: Implement
>>>> platform_profile
>>>>
>>>>
>>>> [EXTERNAL EMAIL]
>>>>
>>>>
>>>>
>>>> On 5/11/2024 10:05 AM, Shen, Yijun wrote:
>>>>> Internal Use - Confidential
>>>>>> -----Original Message-----
>>>>>> From: Mario Limonciello <mario.limonciello@amd.com>
>>>>>> Sent: Wednesday, May 8, 2024 11:53 PM
>>>>>> To: Shen, Yijun <Yijun_Shen@Dell.com>; Lyndon Sanche
>>>>>> <lsanche@lyndeno.ca>
>>>>>> Cc: pali@kernel.org; W_Armin@gmx.de;
>>>>>> srinivas.pandruvada@linux.intel.com; ilpo.jarvinen@linux.intel.com;
>>>>>> lkp@intel.com; Hans de Goede <hdegoede@redhat.com>; Matthew
>>>> Garrett
>>>>>> <mjg59@srcf.ucam.org>; Jonathan Corbet <corbet@lwn.net>; Heiner
>>>>>> Kallweit <hkallweit1@gmail.com>; Vegard Nossum
>>>>>> <vegard.nossum@oracle.com>; platform-driver-x86@vger.kernel.org;
>>>>>> linux-kernel@vger.kernel.org; Dell Client Kernel
>>>>>> <Dell.Client.Kernel@dell.com>
>>>>>> Subject: Re: RE: [PATCH v5] platform/x86: dell-laptop: Implement
>>>>>> platform_profile
>>>>>>
>>>>>>
>>>>>> [EXTERNAL EMAIL]
>>>>>>
>>>>>> On 5/8/2024 09:24, Shen, Yijun wrote:
>>>>>>> Hi Lyndon,
>>>>>>>
>>>>>>>     Thanks for working on this patch.
>>>>>>>
>>>>>>>     Dell side has an initial testing with this patch on some
>>>>>>> laptops,
>>>>>>> it looks
>>>>>> good. While changing the platform profile:
>>>>>>> 1. The corresponding USTT option in BIOS will be changed.
>>>>>>> 2. thermald will not be impacted. The related PSVT and ITMT will be
>>>> loaded.
>>>>>>>     Some Dell DTs does not have the USTT, Dell'll have a check if
>>>>>>> nothing is
>>>>>> broken.
>>>>>>
>>>>>> Hi Alex!
>>>>>>
>>>>>> Have you had a check both on both your AMD laptops and workstations
>>>>>> too, or just the Intel ones?  I think it would be good to make sure
>>>>>> it's getting the correct experience in both cases.
>>>>>>
>>>>> Hi Mario,
>>>>>
>>>>>    I've a check for this, for both laptop and workstation, the
>>>>> dell_laptop
>>>> module will not be loaded. So, AMD platform will not be impacted by
>>>> this
>>>> patch series.
>>>>> Follow is one example output with workstation.
>>>>>    #lsmod | grep dell
>>>>>      dell_wmi               28672  0
>>>>>      dell_smbios            32768  1 dell_wmi
>>>>>      dcdbas                 20480  1 dell_smbios
>>>>>      dell_wmi_descriptor    20480  2 dell_wmi,dell_smbios
>>>>>      sparse_keymap          12288  1 dell_wmi
>>>>>      ledtrig_audio          12288  3
>>>>> snd_ctl_led,snd_hda_codec_generic,dell_wmi
>>>>>      video                  73728  2 dell_wmi,nvidia_modeset
>>>>>      wmi                    40960  5
>>>> video,dell_wmi,wmi_bmof,dell_smbios,dell_wmi_descriptor
>>>> Ah; right that makes sense.  In that case, is dell-laptop even the
>>>> right place for
>>>> this patch series?  I would think the same policies for the
>>>> platform profile
>>>> should be able to apply to desktop/workstation.
>>>>
>>>> The v6 of this series would block smbios-thermal-ctl from working on a
>>>> workstation too.
>>>>
>>>>>>>      Additional, with this patch, follow behavior is found:
>>>>>>>     1. For example, the platform profile is quiet.
>>>>>>>     2. Reboot the system and change the USTT to performance.
>>>>>>>     3. Boot to desktop, the platform profile is "quiet", the USTT
>>>>>>> will be
>>>>>> changed back to "quiet".
>>>>>>>     This looks like not a proper user experience. The platform
>>>>>>> profile should
>>>>>> honor the BIOS setting, aka, the platform profile should be switched
>>>>>> to "performance".
>>>>>> I agree, this sounds like the initial profile needs to be read from
>>>>>> the BIOS settings too.
>>>>>>
>>>>>> Furthermore I wanted to ask is there also a WMI setting that
>>>>>> corresponds to this that dell-wmi-sysman offers?
>>>>>    Yes, Mario, you're right. This thermal setting could also be
>>>>> toggled by dell-
>>>> wmi-sysman.
>>>>> But, for the Dell consumer AMD laptops, like Alienware, the BIOS
>>>>> is another
>>>> variant which is different with the workstation one.
>>>>> With this variant BIOS, there is no USTT and also no
>>>>> dell_wmi/dell-wmi-
>>>> sysman.
>>>>>> I'm wondering if both should be probed in case the SMBIOS one goes
>>>> away one day.
>>>>>    Yep, I think this is a good suggestion.
>>>>>
>>>> Great! Although something I wonder is if the policy when changed
>>>> with dell-
>>>> wmi-sysman is immediate or requires a reboot.  A lot of the
>>>> settings in there
>>>> aren't effective until after a reboot.
>>>>
>>>> If this is one of them then it might not be a good idea to make it
>>>> work for
>>>> both.
>>> Hi Mario,
>>>
>>>   Just have a check, the check steps are:
>>> 1. stop the thermald
>>> 2. run the stress test
>>> 3. Toggle the thermal setting between UltraPerformance and Quiet via
>>> dell-wmi-sysman
>>> 4. Check the CPU FAN speed
>>>   The system reboot is not needed, the CPU fan speed changes
>>> immediately.
>>>   A screen recorder here:
>>> https://dell.box.com/s/p2bhd2b6cv8z5buk9eao3bosgrrp1lf9
>>>
>>> Thanks
>>>
>> Hi,
>>
>> i believe it should be the responsibility of the manufacturer (in
>> this case Dell) that
>> the thermal state remains consistent across both interfaces.
>>
>> I think that the official Windows utility only checks the thermal
>> state reported by
>> the USTT interface, so we should match this behavior.
>>
>> Thanks,
>> Armin Wolf
>>
>
> Why?  Windows also does ACPI-WMI differently than Linux.  It's not as
> easy to check both from a Windows utility due to that.

Actually, it is quite easy to check both interfaces from a Windows utility. Both ACPI-WMI objects can be accessed by
Windows applications, the utility just has to interact with an additional WMI object, but they decided to not do it.

Also the original smbios-thermal-ctl utility was created by Dell itself (i think?), so they likely would have implemented this
if it really was necessary.

As Dell likely only tests their machines with Windows (if at all), i propose that we try to match the Windows behavior.

Thanks,
Armin Wolf


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

* Re: [PATCH v5] platform/x86: dell-laptop: Implement platform_profile
  2024-05-12 18:47                 ` Armin Wolf
@ 2024-05-12 22:14                   ` Limonciello, Mario
  0 siblings, 0 replies; 72+ messages in thread
From: Limonciello, Mario @ 2024-05-12 22:14 UTC (permalink / raw)
  To: Armin Wolf, Shen, Yijun, Lyndon Sanche
  Cc: pali, srinivas.pandruvada, ilpo.jarvinen, lkp, Hans de Goede,
	Matthew Garrett, Jonathan Corbet, Heiner Kallweit, Vegard Nossum,
	platform-driver-x86, linux-kernel, Dell Client Kernel

On 5/12/2024 1:47 PM, Armin Wolf wrote:
>> Why?  Windows also does ACPI-WMI differently than Linux.  It's not as
>> easy to check both from a Windows utility due to that.
> 
> Actually, it is quite easy to check both interfaces from a Windows 
> utility. Both ACPI-WMI objects can be accessed by
> Windows applications, the utility just has to interact with an 
> additional WMI object, but they decided to not do it.
> 

Ah I didn't realize that they're actually instanciable from the WMI 
repository in an application, but that makes perfect sense with how easy 
it is to do from PowerShell.

> Also the original smbios-thermal-ctl utility was created by Dell itself 
> (i think?), so they likely would have implemented this
> if it really was necessary.
> 

It was created at a time that the ACPI WMI BIOS attributes interface 
didn't exist.  I've understood that the general direction is to use the 
WMI BIOS attributes interface in the future.

That's why I was suggesting using both, if such a transition happens 
then this driver would be ready for it.

> As Dell likely only tests their machines with Windows (if at all), i 
> propose that we try to match the Windows behavior.

I don't have a strong horse in this game, but I see what you mean in 
terms of general compatibility.

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

* Re: [PATCH v2] platform/x86: dell-laptop: Implement platform_profile
  2024-04-26  2:04 ` [PATCH v2] " Lyndon Sanche
  2024-04-26  9:23   ` Ilpo Järvinen
@ 2024-05-13 20:09   ` kernel test robot
  1 sibling, 0 replies; 72+ messages in thread
From: kernel test robot @ 2024-05-13 20:09 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: oe-kbuild-all, mario.limonciello, pali, W_Armin,
	srinivas.pandruvada, Matthew Garrett, Hans de Goede,
	Ilpo Järvinen, platform-driver-x86, linux-kernel,
	Dell.Client.Kernel

Hi Lyndon,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.9 next-20240513]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lyndon-Sanche/platform-x86-dell-laptop-Implement-platform_profile/20240511-144534
base:   linus/master
patch link:    https://lore.kernel.org/r/20240426020448.10862-1-lsanche%40lyndeno.ca
patch subject: [PATCH v2] platform/x86: dell-laptop: Implement platform_profile
config: i386-randconfig-005-20240513 (https://download.01.org/0day-ci/archive/20240514/202405140348.Wz7gOmdP-lkp@intel.com/config)
compiler: gcc-8 (Ubuntu 8.4.0-3ubuntu2) 8.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240514/202405140348.Wz7gOmdP-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405140348.Wz7gOmdP-lkp@intel.com/

All errors (new ones prefixed by >>):

   ld: drivers/platform/x86/dell/dell-laptop.o: in function `thermal_init':
>> drivers/platform/x86/dell/dell-laptop.c:2404:(.text+0x21a3): undefined reference to `platform_profile_register'
   ld: drivers/platform/x86/dell/dell-laptop.o: in function `thermal_cleanup':
>> drivers/platform/x86/dell/dell-laptop.c:2412:(.text+0x21cc): undefined reference to `platform_profile_remove'
>> ld: drivers/platform/x86/dell/dell-laptop.c:2412:(.init.text+0xb44): undefined reference to `platform_profile_remove'
>> ld: drivers/platform/x86/dell/dell-laptop.c:2412:(.exit.text+0x7c): undefined reference to `platform_profile_remove'


vim +2404 drivers/platform/x86/dell/dell-laptop.c

  2377	
  2378	int thermal_init(void)
  2379	{
  2380		int ret;
  2381		int supported_modes;
  2382	
  2383		ret = thermal_get_supported_modes(&supported_modes);
  2384	
  2385		if (ret || !supported_modes)
  2386			return 0;
  2387	
  2388		thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
  2389		if (!thermal_handler)
  2390			return -ENOMEM;
  2391		thermal_handler->profile_get = thermal_platform_profile_get;
  2392		thermal_handler->profile_set = thermal_platform_profile_set;
  2393	
  2394		if ((supported_modes >> DELL_QUIET) & 1)
  2395			set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
  2396		if ((supported_modes >> DELL_COOL_BOTTOM) & 1)
  2397			set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
  2398		if ((supported_modes >> DELL_BALANCED) & 1)
  2399			set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
  2400		if ((supported_modes >> DELL_PERFORMANCE) & 1)
  2401			set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
  2402	
  2403		// Clean up but do not fail
> 2404		if (platform_profile_register(thermal_handler))
  2405			kfree(thermal_handler);
  2406	
  2407		return 0;
  2408	}
  2409	
  2410	void thermal_cleanup(void)
  2411	{
> 2412		platform_profile_remove();
  2413		kfree(thermal_handler);
  2414	}
  2415	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile
  2024-05-12 18:05   ` Armin Wolf
@ 2024-05-15 17:06     ` Lyndon Sanche
  0 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-15 17:06 UTC (permalink / raw)
  To: Armin Wolf
  Cc: Mario Limonciello, Pali Rohár, srinivas.pandruvada,
	Ilpo Järvinen, kernel test robot, Hans de Goede, Yijun Shen,
	Matthew Garrett, Heiner Kallweit, Randy Dunlap, Jonathan Corbet,
	Vegard Nossum, platform-driver-x86, LKML, Dell.Client.Kernel



On Sun, May 12, 2024, at 12:05 PM, Armin Wolf wrote:
> Am 11.05.24 um 04:36 schrieb Lyndon Sanche:
>

>> +static int thermal_init(void)
>> +{
>> +	int ret;
>> +	int supported_modes;
>> +
>> +	/* If thermal commands not supported, exit without error */
>> +	if (!dell_laptop_check_supported_cmds(CLASS_INFO))
>> +		return 0;
>> +
>> +	/* If thermal modes not supported, exit without error */
>> +	ret = thermal_get_supported_modes(&supported_modes);
>> +	if (ret < 0)
>> +		return ret;
>
> Hi,
>
> the function dell_smbios_error() says that when a specific functionality is
> not supported, -ENXIO is returned.
>
> Please treat this as "no thermal modes supported", since checking if CLASS_INFO
> is supported is not enough (CLASS_INFO is also used by other functionality like
> rfkill, so machines might support CLASS_INFO but not USTT).
>
> Thanks,
> Armin Wolf
>

Armin:

Thank you for this. I will include this in the next revision.

Thanks,

Lyndon

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

* [PATCH v7 0/3] platform/x86: dell: Implement platform_profile
  2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
                   ` (10 preceding siblings ...)
  2024-05-11  2:36 ` [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
@ 2024-05-17 22:42 ` Lyndon Sanche
  2024-05-17 22:42   ` [PATCH v7 1/3] platform/x86: dell-smbios: Add helper for checking supported class Lyndon Sanche
                     ` (3 more replies)
  11 siblings, 4 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-17 22:42 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Vegard Nossum, Randy Dunlap, Jonathan Corbet, Heiner Kallweit,
	linux-kernel, platform-driver-x86, Dell.Client.Kernel

v7:
 - Move platform_profile into new dell-pc module
 - Add myself as maintainer of dell-pc
 - Move smbios call and fill functions to dell-smbios-base
 - Check for classes above 30 and return as not supported
 - Rename dell_laptop_check_supported_cmds to
	 dell_smbios_class_is_supported
 - Check for ENXIO and treat as no thermal modes supported
v6:
 - Add ACPI dependency for dell-laptop
 - Add and use helper symbol for checking supported commands
v5:
 - Fix indent in smbios-thermal-ctl comment
 - Remove linux/wmi.h include
 - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
v4:
 - Make thermal_init and thermal_cleanup static
 - Rearrange order of added includes, did not edit current includes
 - Include bits.h
 - Switch comment style
 - Return error if platform_profile registering failed
 - Add thermal calls to call_blacklist
 - Align defines with tabs
 - Correct separation of function and error handling
 - Propagate error codes up
v3:
 - Convert smbios-thermal-ctl docs to multiline comment and wrap
 - Change thermal_mode_bits enum to directly be BIT() values
	- Convert related code to use this
 - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
	- Correct offset for getting current ACC mode, setting offset
		unchanged
 - Check if thermal_handler is allocated before freeing and
	 unregistering platform_profile
v2:
 - Wrap smbios-thermal-ctl comment
 - Return proper error code when invalid state returned
 - Simplify platform_profile_get returns
 - Propogate ENOMEM error

Lyndon Sanche (3):
  platform/x86: dell-smbios: Add helper for checking supported class
  platform/x86: dell-smbios: Move request functions for reuse
  platform/x86: dell-pc: Implement platform_profile

 MAINTAINERS                                  |   6 +
 drivers/platform/x86/dell/Kconfig            |  13 +
 drivers/platform/x86/dell/Makefile           |   1 +
 drivers/platform/x86/dell/dell-laptop.c      |  23 --
 drivers/platform/x86/dell/dell-pc.c          | 310 +++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios-base.c |  35 +++
 drivers/platform/x86/dell/dell-smbios.h      |   7 +
 7 files changed, 372 insertions(+), 23 deletions(-)
 create mode 100644 drivers/platform/x86/dell/dell-pc.c

-- 
2.42.0


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

* [PATCH v7 1/3] platform/x86: dell-smbios: Add helper for checking supported class
  2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
@ 2024-05-17 22:42   ` Lyndon Sanche
  2024-05-17 22:42   ` [PATCH v7 2/3] platform/x86: dell-smbios: Move request functions for reuse Lyndon Sanche
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-17 22:42 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Jonathan Corbet, Heiner Kallweit, Vegard Nossum, linux-kernel,
	platform-driver-x86, Dell.Client.Kernel

Add helper that returns true if smbios command class is supported.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 drivers/platform/x86/dell/dell-smbios-base.c | 9 +++++++++
 drivers/platform/x86/dell/dell-smbios.h      | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index e61bfaf8b5c4..fbdd12a7cb8d 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -350,6 +350,15 @@ void dell_laptop_call_notifier(unsigned long action, void *data)
 }
 EXPORT_SYMBOL_GPL(dell_laptop_call_notifier);
 
+bool dell_smbios_class_is_supported(u16 class)
+{
+	/* Classes over 30 always unsupported */
+	if (class > 30)
+		return false;
+	return da_supported_commands & (1 << class);
+}
+EXPORT_SYMBOL_GPL(dell_smbios_class_is_supported);
+
 static void __init parse_da_table(const struct dmi_header *dm)
 {
 	/* Final token is a terminator, so we don't want to copy it */
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index eb341bf000c6..756c354b1eef 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -73,6 +73,7 @@ enum dell_laptop_notifier_actions {
 int dell_laptop_register_notifier(struct notifier_block *nb);
 int dell_laptop_unregister_notifier(struct notifier_block *nb);
 void dell_laptop_call_notifier(unsigned long action, void *data);
+bool dell_smbios_class_is_supported(u16 class);
 
 /* for the supported backends */
 #ifdef CONFIG_DELL_SMBIOS_WMI
-- 
2.42.0


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

* [PATCH v7 2/3] platform/x86: dell-smbios: Move request functions for reuse
  2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
  2024-05-17 22:42   ` [PATCH v7 1/3] platform/x86: dell-smbios: Add helper for checking supported class Lyndon Sanche
@ 2024-05-17 22:42   ` Lyndon Sanche
  2024-05-17 22:42   ` [PATCH v7 3/3] platform/x86: dell-pc: Implement platform_profile Lyndon Sanche
  2024-05-21 20:50   ` [PATCH v7 0/3] platform/x86: dell: " Mario Limonciello
  3 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-17 22:42 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Jonathan Corbet, Heiner Kallweit, Vegard Nossum, linux-kernel,
	platform-driver-x86, Dell.Client.Kernel

Move the dell_send_request and dell_fill_request symbols into smbios-base
so that they can be used in multiple modules.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 drivers/platform/x86/dell/dell-laptop.c      | 23 ------------------
 drivers/platform/x86/dell/dell-smbios-base.c | 25 ++++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios.h      |  5 ++++
 3 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c
index 42f7de2b4522..6552dfe491c6 100644
--- a/drivers/platform/x86/dell/dell-laptop.c
+++ b/drivers/platform/x86/dell/dell-laptop.c
@@ -353,29 +353,6 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
 	{ }
 };
 
-static void dell_fill_request(struct calling_interface_buffer *buffer,
-			       u32 arg0, u32 arg1, u32 arg2, u32 arg3)
-{
-	memset(buffer, 0, sizeof(struct calling_interface_buffer));
-	buffer->input[0] = arg0;
-	buffer->input[1] = arg1;
-	buffer->input[2] = arg2;
-	buffer->input[3] = arg3;
-}
-
-static int dell_send_request(struct calling_interface_buffer *buffer,
-			     u16 class, u16 select)
-{
-	int ret;
-
-	buffer->cmd_class = class;
-	buffer->cmd_select = select;
-	ret = dell_smbios_call(buffer);
-	if (ret != 0)
-		return ret;
-	return dell_smbios_error(buffer->output[0]);
-}
-
 /*
  * Derived from information in smbios-wireless-ctl:
  *
diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index fbdd12a7cb8d..515c454acfe6 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -314,6 +314,31 @@ int dell_smbios_call(struct calling_interface_buffer *buffer)
 }
 EXPORT_SYMBOL_GPL(dell_smbios_call);
 
+void dell_fill_request(struct calling_interface_buffer *buffer,
+			       u32 arg0, u32 arg1, u32 arg2, u32 arg3)
+{
+	memset(buffer, 0, sizeof(struct calling_interface_buffer));
+	buffer->input[0] = arg0;
+	buffer->input[1] = arg1;
+	buffer->input[2] = arg2;
+	buffer->input[3] = arg3;
+}
+EXPORT_SYMBOL_GPL(dell_fill_request);
+
+int dell_send_request(struct calling_interface_buffer *buffer,
+			     u16 class, u16 select)
+{
+	int ret;
+
+	buffer->cmd_class = class;
+	buffer->cmd_select = select;
+	ret = dell_smbios_call(buffer);
+	if (ret != 0)
+		return ret;
+	return dell_smbios_error(buffer->output[0]);
+}
+EXPORT_SYMBOL_GPL(dell_send_request);
+
 struct calling_interface_token *dell_smbios_find_token(int tokenid)
 {
 	int i;
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index 756c354b1eef..1d6463cca12a 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -64,6 +64,11 @@ int dell_smbios_call_filter(struct device *d,
 	struct calling_interface_buffer *buffer);
 int dell_smbios_call(struct calling_interface_buffer *buffer);
 
+void dell_fill_request(struct calling_interface_buffer *buffer,
+			       u32 arg0, u32 arg1, u32 arg2, u32 arg3);
+int dell_send_request(struct calling_interface_buffer *buffer,
+			     u16 class, u16 select);
+
 struct calling_interface_token *dell_smbios_find_token(int tokenid);
 
 enum dell_laptop_notifier_actions {
-- 
2.42.0


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

* [PATCH v7 3/3] platform/x86: dell-pc: Implement platform_profile
  2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
  2024-05-17 22:42   ` [PATCH v7 1/3] platform/x86: dell-smbios: Add helper for checking supported class Lyndon Sanche
  2024-05-17 22:42   ` [PATCH v7 2/3] platform/x86: dell-smbios: Move request functions for reuse Lyndon Sanche
@ 2024-05-17 22:42   ` Lyndon Sanche
  2024-05-21 20:50   ` [PATCH v7 0/3] platform/x86: dell: " Mario Limonciello
  3 siblings, 0 replies; 72+ messages in thread
From: Lyndon Sanche @ 2024-05-17 22:42 UTC (permalink / raw)
  To: lsanche
  Cc: mario.limonciello, pali, W_Armin, srinivas.pandruvada,
	ilpo.jarvinen, lkp, hdegoede, Yijun.Shen, Matthew Garrett,
	Vegard Nossum, Jonathan Corbet, Heiner Kallweit, linux-kernel,
	platform-driver-x86, Dell.Client.Kernel

Some Dell laptops support configuration of preset fan modes through
smbios tables.

If the platform supports these fan modes, set up platform_profile to
change these modes. If not supported, skip enabling platform_profile.

Signed-off-by: Lyndon Sanche <lsanche@lyndeno.ca>
---
 MAINTAINERS                                  |   6 +
 drivers/platform/x86/dell/Kconfig            |  13 +
 drivers/platform/x86/dell/Makefile           |   1 +
 drivers/platform/x86/dell/dell-pc.c          | 310 +++++++++++++++++++
 drivers/platform/x86/dell/dell-smbios-base.c |   1 +
 drivers/platform/x86/dell/dell-smbios.h      |   1 +
 6 files changed, 332 insertions(+)
 create mode 100644 drivers/platform/x86/dell/dell-pc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ebf03f5f0619..69c582b72a08 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5961,6 +5961,12 @@ F:	Documentation/ABI/obsolete/procfs-i8k
 F:	drivers/hwmon/dell-smm-hwmon.c
 F:	include/uapi/linux/i8k.h
 
+DELL PC DRIVER
+M:	Lyndon Sanche <lsanche@lyndeno.ca>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/dell/dell-pc.c
+
 DELL REMOTE BIOS UPDATE DRIVER
 M:	Stuart Hayes <stuart.w.hayes@gmail.com>
 L:	platform-driver-x86@vger.kernel.org
diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
index bd9f445974cc..0732850a3dd6 100644
--- a/drivers/platform/x86/dell/Kconfig
+++ b/drivers/platform/x86/dell/Kconfig
@@ -91,6 +91,19 @@ config DELL_RBTN
 	  To compile this driver as a module, choose M here: the module will
 	  be called dell-rbtn.
 
+config DELL_PC
+	tristate "Dell PC Extras"
+	default m
+	depends on ACPI
+	depends on DMI
+	depends on DELL_SMBIOS
+	select ACPI_PLATFORM_PROFILE
+	help
+	This driver adds support for controlling the fan modes via platform_profile
+	on supported Dell systems regardless of formfactor.
+	Module will simply do nothing if thermal management commands are not
+	supported.
+
 #
 # The DELL_SMBIOS driver depends on ACPI_WMI and/or DCDBAS if those
 # backends are selected. The "depends" line prevents a configuration
diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
index 1b8942426622..9b0094fafcce 100644
--- a/drivers/platform/x86/dell/Makefile
+++ b/drivers/platform/x86/dell/Makefile
@@ -9,6 +9,7 @@ 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
diff --git a/drivers/platform/x86/dell/dell-pc.c b/drivers/platform/x86/dell/dell-pc.c
new file mode 100644
index 000000000000..3dd762e39f45
--- /dev/null
+++ b/drivers/platform/x86/dell/dell-pc.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Driver for Dell laptop extras
+ *
+ *  Copyright (c) Lyndon Sanche <lsanche@lyndeno.ca>
+ *
+ *  Based on documentation in the libsmbios package:
+ *  Copyright (C) 2005-2014 Dell Inc.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/dmi.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/platform_profile.h>
+#include <linux/slab.h>
+#include "dell-smbios.h"
+
+
+static const struct dmi_system_id dell_device_table[] __initconst = {
+	{
+		.ident = "Dell Inc.",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		},
+	},
+	{
+		.ident = "Dell Computer Corporation",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+		},
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(dmi, dell_device_table);
+
+/* Derived from smbios-thermal-ctl
+ *
+ * cbClass 17
+ * cbSelect 19
+ * User Selectable Thermal Tables(USTT)
+ * cbArg1 determines the function to be performed
+ * cbArg1 0x0 = Get Thermal Information
+ *  cbRES1         Standard return codes (0, -1, -2)
+ *  cbRES2, byte 0  Bitmap of supported thermal modes. A mode is supported if
+ *                  its bit is set to 1
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ *  cbRES2, byte 1 Bitmap of supported Active Acoustic Controller (AAC) modes.
+ *                 Each mode corresponds to the supported thermal modes in
+ *                  byte 0. A mode is supported if its bit is set to 1.
+ *     Bit 0 AAC (Balanced)
+ *     Bit 1 AAC (Cool Bottom
+ *     Bit 2 AAC (Quiet)
+ *     Bit 3 AAC (Performance)
+ *  cbRes3, byte 0 Current Thermal Mode
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performanc
+ *  cbRes3, byte 1  AAC Configuration type
+ *          0       Global (AAC enable/disable applies to all supported USTT modes)
+ *          1       USTT mode specific
+ *  cbRes3, byte 2  Current Active Acoustic Controller (AAC) Mode
+ *     If AAC Configuration Type is Global,
+ *          0       AAC mode disabled
+ *          1       AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific (multiple bits may be set),
+ *          Bit 0 AAC (Balanced)
+ *          Bit 1 AAC (Cool Bottom
+ *          Bit 2 AAC (Quiet)
+ *          Bit 3 AAC (Performance)
+ *  cbRes3, byte 3  Current Fan Failure Mode
+ *     Bit 0 Minimal Fan Failure (at least one fan has failed, one fan working)
+ *     Bit 1 Catastrophic Fan Failure (all fans have failed)
+ *
+ * cbArg1 0x1   (Set Thermal Information), both desired thermal mode and
+ *               desired AAC mode shall be applied
+ * cbArg2, byte 0  Desired Thermal Mode to set
+ *                  (only one bit may be set for this parameter)
+ *     Bit 0 Balanced
+ *     Bit 1 Cool Bottom
+ *     Bit 2 Quiet
+ *     Bit 3 Performance
+ * cbArg2, byte 1  Desired Active Acoustic Controller (AAC) Mode to set
+ *     If AAC Configuration Type is Global,
+ *         0  AAC mode disabled
+ *         1  AAC mode enabled
+ *     If AAC Configuration Type is USTT mode specific
+ *     (multiple bits may be set for this parameter),
+ *         Bit 0 AAC (Balanced)
+ *         Bit 1 AAC (Cool Bottom
+ *         Bit 2 AAC (Quiet)
+ *         Bit 3 AAC (Performance)
+ */
+
+#define DELL_ACC_GET_FIELD		GENMASK(19, 16)
+#define DELL_ACC_SET_FIELD		GENMASK(11, 8)
+#define DELL_THERMAL_SUPPORTED	GENMASK(3, 0)
+
+static struct platform_profile_handler *thermal_handler;
+
+enum thermal_mode_bits {
+	DELL_BALANCED = BIT(0),
+	DELL_COOL_BOTTOM = BIT(1),
+	DELL_QUIET = BIT(2),
+	DELL_PERFORMANCE = BIT(3),
+};
+
+static int thermal_get_mode(void)
+{
+	struct calling_interface_buffer buffer;
+	int state;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	state = buffer.output[2];
+	if (state & DELL_BALANCED)
+		return DELL_BALANCED;
+	else if (state & DELL_COOL_BOTTOM)
+		return DELL_COOL_BOTTOM;
+	else if (state & DELL_QUIET)
+		return DELL_QUIET;
+	else if (state & DELL_PERFORMANCE)
+		return DELL_PERFORMANCE;
+	else
+		return -ENXIO;
+}
+
+static int thermal_get_supported_modes(int *supported_bits)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret) {
+		/* Thermal function not supported */
+		if (ret == -ENXIO) {
+			*supported_bits = 0;
+			return 0;
+		} else {
+			return ret;
+		}
+	}
+	*supported_bits = FIELD_GET(DELL_THERMAL_SUPPORTED, buffer.output[1]);
+	return 0;
+}
+
+static int thermal_get_acc_mode(int *acc_mode)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+
+	dell_fill_request(&buffer, 0x0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	if (ret)
+		return ret;
+	*acc_mode = FIELD_GET(DELL_ACC_GET_FIELD, buffer.output[3]);
+	return 0;
+}
+
+static int thermal_set_mode(enum thermal_mode_bits state)
+{
+	struct calling_interface_buffer buffer;
+	int ret;
+	int acc_mode;
+
+	ret = thermal_get_acc_mode(&acc_mode);
+	if (ret)
+		return ret;
+
+	dell_fill_request(&buffer, 0x1, FIELD_PREP(DELL_ACC_SET_FIELD, acc_mode) | state, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_THERMAL_MANAGEMENT);
+	return ret;
+}
+
+static int thermal_platform_profile_set(struct platform_profile_handler *pprof,
+					enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_BALANCED:
+		return thermal_set_mode(DELL_BALANCED);
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return thermal_set_mode(DELL_PERFORMANCE);
+	case PLATFORM_PROFILE_QUIET:
+		return thermal_set_mode(DELL_QUIET);
+	case PLATFORM_PROFILE_COOL:
+		return thermal_set_mode(DELL_COOL_BOTTOM);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int thermal_platform_profile_get(struct platform_profile_handler *pprof,
+					enum platform_profile_option *profile)
+{
+	int ret;
+
+	ret = thermal_get_mode();
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case DELL_BALANCED:
+		*profile = PLATFORM_PROFILE_BALANCED;
+		break;
+	case DELL_PERFORMANCE:
+		*profile = PLATFORM_PROFILE_PERFORMANCE;
+		break;
+	case DELL_COOL_BOTTOM:
+		*profile = PLATFORM_PROFILE_COOL;
+		break;
+	case DELL_QUIET:
+		*profile = PLATFORM_PROFILE_QUIET;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int thermal_init(void)
+{
+	int ret;
+	int supported_modes;
+
+	/* If thermal commands not supported, exit without error */
+	if (!dell_smbios_class_is_supported(CLASS_INFO))
+		return 0;
+
+	/* If thermal modes not supported, exit without error */
+	ret = thermal_get_supported_modes(&supported_modes);
+	if (ret < 0)
+		return ret;
+	if (!supported_modes)
+		return 0;
+
+	thermal_handler = kzalloc(sizeof(*thermal_handler), GFP_KERNEL);
+	if (!thermal_handler)
+		return -ENOMEM;
+	thermal_handler->profile_get = thermal_platform_profile_get;
+	thermal_handler->profile_set = thermal_platform_profile_set;
+
+	if (supported_modes & DELL_QUIET)
+		set_bit(PLATFORM_PROFILE_QUIET, thermal_handler->choices);
+	if (supported_modes & DELL_COOL_BOTTOM)
+		set_bit(PLATFORM_PROFILE_COOL, thermal_handler->choices);
+	if (supported_modes & DELL_BALANCED)
+		set_bit(PLATFORM_PROFILE_BALANCED, thermal_handler->choices);
+	if (supported_modes & DELL_PERFORMANCE)
+		set_bit(PLATFORM_PROFILE_PERFORMANCE, thermal_handler->choices);
+
+	/* Clean up if failed */
+	ret = platform_profile_register(thermal_handler);
+	if (ret)
+		kfree(thermal_handler);
+
+	return ret;
+}
+
+static void thermal_cleanup(void)
+{
+	if (thermal_handler) {
+		platform_profile_remove();
+		kfree(thermal_handler);
+	}
+}
+
+static int __init dell_init(void)
+{
+	int ret;
+
+	if (!dmi_check_system(dell_device_table))
+		return -ENODEV;
+
+	/* Do not fail module if thermal modes not supported, just skip */
+	ret = thermal_init();
+	if (ret)
+		goto fail_thermal;
+
+	return 0;
+
+fail_thermal:
+	thermal_cleanup();
+	return ret;
+}
+
+static void __exit dell_exit(void)
+{
+	thermal_cleanup();
+}
+
+module_init(dell_init);
+module_exit(dell_exit);
+
+MODULE_AUTHOR("Lyndon Sanche <lsanche@lyndeno.ca>");
+MODULE_DESCRIPTION("Dell PC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
index 515c454acfe6..d61b33d5af95 100644
--- a/drivers/platform/x86/dell/dell-smbios-base.c
+++ b/drivers/platform/x86/dell/dell-smbios-base.c
@@ -71,6 +71,7 @@ static struct smbios_call call_blacklist[] = {
 	/* handled by kernel: dell-laptop */
 	{0x0000, CLASS_INFO, SELECT_RFKILL},
 	{0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
+	{0x0000, CLASS_INFO, SELECT_THERMAL_MANAGEMENT},
 };
 
 struct token_range {
diff --git a/drivers/platform/x86/dell/dell-smbios.h b/drivers/platform/x86/dell/dell-smbios.h
index 1d6463cca12a..ea0cc38642a2 100644
--- a/drivers/platform/x86/dell/dell-smbios.h
+++ b/drivers/platform/x86/dell/dell-smbios.h
@@ -19,6 +19,7 @@
 /* Classes and selects used only in kernel drivers */
 #define CLASS_KBD_BACKLIGHT 4
 #define SELECT_KBD_BACKLIGHT 11
+#define SELECT_THERMAL_MANAGEMENT 19
 
 /* Tokens used in kernel drivers, any of these
  * should be filtered from userspace access
-- 
2.42.0


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

* Re: [PATCH v7 0/3] platform/x86: dell: Implement platform_profile
  2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
                     ` (2 preceding siblings ...)
  2024-05-17 22:42   ` [PATCH v7 3/3] platform/x86: dell-pc: Implement platform_profile Lyndon Sanche
@ 2024-05-21 20:50   ` Mario Limonciello
  3 siblings, 0 replies; 72+ messages in thread
From: Mario Limonciello @ 2024-05-21 20:50 UTC (permalink / raw)
  To: Lyndon Sanche
  Cc: pali, W_Armin, srinivas.pandruvada, ilpo.jarvinen, lkp, hdegoede,
	Yijun.Shen, Matthew Garrett, Vegard Nossum, Randy Dunlap,
	Jonathan Corbet, Heiner Kallweit, linux-kernel,
	platform-driver-x86, Dell.Client.Kernel

On 5/17/2024 17:42, Lyndon Sanche wrote:
> v7:
>   - Move platform_profile into new dell-pc module
>   - Add myself as maintainer of dell-pc
>   - Move smbios call and fill functions to dell-smbios-base
>   - Check for classes above 30 and return as not supported
>   - Rename dell_laptop_check_supported_cmds to
> 	 dell_smbios_class_is_supported
>   - Check for ENXIO and treat as no thermal modes supported
> v6:
>   - Add ACPI dependency for dell-laptop
>   - Add and use helper symbol for checking supported commands
> v5:
>   - Fix indent in smbios-thermal-ctl comment
>   - Remove linux/wmi.h include
>   - Add 'select ACPI_PLATFORM_PROFILE' to Dell KConfig
> v4:
>   - Make thermal_init and thermal_cleanup static
>   - Rearrange order of added includes, did not edit current includes
>   - Include bits.h
>   - Switch comment style
>   - Return error if platform_profile registering failed
>   - Add thermal calls to call_blacklist
>   - Align defines with tabs
>   - Correct separation of function and error handling
>   - Propagate error codes up
> v3:
>   - Convert smbios-thermal-ctl docs to multiline comment and wrap
>   - Change thermal_mode_bits enum to directly be BIT() values
> 	- Convert related code to use this
>   - Use FIELD_GET/PREP and GENNMASK for getting/setting thermal modes
> 	- Correct offset for getting current ACC mode, setting offset
> 		unchanged
>   - Check if thermal_handler is allocated before freeing and
> 	 unregistering platform_profile
> v2:
>   - Wrap smbios-thermal-ctl comment
>   - Return proper error code when invalid state returned
>   - Simplify platform_profile_get returns
>   - Propogate ENOMEM error
> 
> Lyndon Sanche (3):
>    platform/x86: dell-smbios: Add helper for checking supported class
>    platform/x86: dell-smbios: Move request functions for reuse
>    platform/x86: dell-pc: Implement platform_profile
> 
>   MAINTAINERS                                  |   6 +
>   drivers/platform/x86/dell/Kconfig            |  13 +
>   drivers/platform/x86/dell/Makefile           |   1 +
>   drivers/platform/x86/dell/dell-laptop.c      |  23 --
>   drivers/platform/x86/dell/dell-pc.c          | 310 +++++++++++++++++++
>   drivers/platform/x86/dell/dell-smbios-base.c |  35 +++
>   drivers/platform/x86/dell/dell-smbios.h      |   7 +
>   7 files changed, 372 insertions(+), 23 deletions(-)
>   create mode 100644 drivers/platform/x86/dell/dell-pc.c
> 

Series looks good to me, thanks.

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>

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

end of thread, other threads:[~2024-05-21 20:50 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-25 17:27 [PATCH] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
2024-04-25 20:07 ` Mario Limonciello
2024-04-25 20:24   ` Lyndon Sanche
2024-04-25 20:28     ` Mario Limonciello
2024-04-25 21:51       ` Srinivas Pandruvada
2024-04-26  0:38         ` Lyndon Sanche
2024-04-26 16:14     ` srinivas pandruvada
2024-04-26 18:23       ` Lyndon Sanche
2024-04-26 18:24         ` srinivas pandruvada
2024-04-25 20:12 ` Pali Rohár
2024-04-25 20:27   ` Lyndon Sanche
2024-04-25 20:31     ` Pali Rohár
2024-04-25 21:07 ` Armin Wolf
2024-04-26  0:54   ` Lyndon Sanche
2024-04-26  2:04 ` [PATCH v2] " Lyndon Sanche
2024-04-26  9:23   ` Ilpo Järvinen
2024-04-26 18:05     ` Lyndon Sanche
2024-05-13 20:09   ` kernel test robot
2024-04-26  6:57 ` [PATCH] " Ilpo Järvinen
2024-04-29 16:48 ` [PATCH v3] " Lyndon Sanche
2024-04-29 17:45   ` Mario Limonciello
2024-04-29 17:51     ` Mario Limonciello
2024-04-29 21:25       ` Lyndon Sanche
2024-04-29 21:21     ` Lyndon Sanche
2024-04-30 10:31   ` Ilpo Järvinen
2024-04-30 18:38     ` Lyndon Sanche
2024-04-30 15:36   ` kernel test robot
2024-05-01  8:16   ` kernel test robot
2024-05-01 16:35   ` kernel test robot
2024-05-01 17:07   ` kernel test robot
2024-05-01  1:14 ` [PATCH v4] " Lyndon Sanche
2024-05-01  1:36   ` Pali Rohár
2024-05-01  1:42     ` Lyndon Sanche
2024-05-01 21:58 ` [PATCH v5] " Lyndon Sanche
2024-05-03 10:19   ` kernel test robot
2024-05-04  1:03     ` Lyndon Sanche
2024-05-06 10:18       ` Hans de Goede
2024-05-07 16:00         ` Lyndon Sanche
2024-05-03 21:19   ` Armin Wolf
2024-05-04  0:59     ` Lyndon Sanche
2024-05-08 14:24   ` Shen, Yijun
2024-05-08 15:53     ` Mario Limonciello
2024-05-11 15:05       ` Shen, Yijun
2024-05-11 15:12         ` Limonciello, Mario
2024-05-11 15:56           ` Shen, Yijun
2024-05-12 17:53             ` Armin Wolf
2024-05-12 17:58               ` Limonciello, Mario
2024-05-12 18:47                 ` Armin Wolf
2024-05-12 22:14                   ` Limonciello, Mario
2024-05-11 16:02         ` Lyndon Sanche
2024-05-09 15:10     ` Lyndon Sanche
2024-05-11  1:49       ` Lyndon Sanche
2024-05-11 15:22         ` Shen, Yijun
2024-05-11 15:54           ` Lyndon Sanche
2024-05-11 16:12             ` Shen, Yijun
2024-05-11  2:36 ` [PATCH v6 0/2] " Lyndon Sanche
2024-05-11  2:36 ` [PATCH v6 1/2] platform/x86: dell-smbios: Add helper for checking supported commands Lyndon Sanche
2024-05-11 15:13   ` Limonciello, Mario
2024-05-12 18:00   ` Armin Wolf
2024-05-11  2:36 ` [PATCH v6 2/2] platform/x86: dell-laptop: Implement platform_profile Lyndon Sanche
2024-05-11 15:16   ` Limonciello, Mario
2024-05-11 15:59     ` Lyndon Sanche
     [not found]       ` <48JCDS.E4RT1F9DTKFU1@lyndeno.ca>
2024-05-12  1:43         ` Limonciello, Mario
2024-05-12 15:25           ` Hans de Goede
2024-05-12  0:14     ` Lyndon Sanche
2024-05-12 18:05   ` Armin Wolf
2024-05-15 17:06     ` Lyndon Sanche
2024-05-17 22:42 ` [PATCH v7 0/3] platform/x86: dell: " Lyndon Sanche
2024-05-17 22:42   ` [PATCH v7 1/3] platform/x86: dell-smbios: Add helper for checking supported class Lyndon Sanche
2024-05-17 22:42   ` [PATCH v7 2/3] platform/x86: dell-smbios: Move request functions for reuse Lyndon Sanche
2024-05-17 22:42   ` [PATCH v7 3/3] platform/x86: dell-pc: Implement platform_profile Lyndon Sanche
2024-05-21 20:50   ` [PATCH v7 0/3] platform/x86: dell: " Mario Limonciello

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).