lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAJZ5v0iRzTuZ9x=biw1UtcrOdTwFhbH1kakHz6SKtksQfn-jOw@mail.gmail.com>
Date: Tue, 25 Feb 2025 21:50:17 +0100
From: "Rafael J. Wysocki" <rafael@...nel.org>
To: Joshua Grisham <josh@...huagrisham.com>
Cc: rafael@...nel.org, lenb@...nel.org, W_Armin@....de, 
	linux-acpi@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v4] ACPI: fan: Add fan speed reporting for fans with only _FST

On Sat, Feb 22, 2025 at 10:44 AM Joshua Grisham <josh@...huagrisham.com> wrote:
>
> Add support for ACPI fans with _FST to report their speed even if they do
> not support fan control.
>
> As suggested by Armin Wolf [1] and per the Windows Thermal Management
> Design Guide [2], Samsung Galaxy Book series devices (and possibly many
> more devices where the Windows guide was strictly followed) only implement
> the _FST method and do not support ACPI-based fan control.
>
> Currently, these fans are not supported by the kernel driver but this patch
> will make some very small adjustments to allow them to be supported.
>
> This patch is tested and working for me on a Samsung Galaxy Book2 Pro whose
> DSDT (and several other Samsung Galaxy Book series notebooks which
> currently have the same issue) can be found at [3].
>
> [1]: https://lore.kernel.org/platform-driver-x86/53c5075b-1967-45d0-937f-463912dd966d@gmx.de
> [2]: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/design-guide
> [3]: https://github.com/joshuagrisham/samsung-galaxybook-extras/tree/8e3087a06b8bdcdfdd081367af4b744a56cc4ee9/dsdt
>
> Signed-off-by: Joshua Grisham <josh@...huagrisham.com>
> Reviewed-by: Armin Wolf <W_Armin@....de>
>
> ---
>
> v1->v2:
> - Still allow acpi4_only_fst fans to update power state on
>   suspend/resume
> - Fix if / else if logic error
> - Also hide hwmon_power_input for acpi4_only_fst fans
>
> v2->v3:
> - Still allow acpi4_only_fst fans to set initial power state on probe
>
> v3->v4:
> - Small tweaks to naming (acpi4_only_fst became has_fst) and logic flow
>   based on feedback from Rafael
> - Built against next and tested working on Samsung Galaxy Book2 Pro
> ---
>  drivers/acpi/fan.h       |  1 +
>  drivers/acpi/fan_attr.c  | 37 ++++++++++++++++++++++---------------
>  drivers/acpi/fan_core.c  | 25 ++++++++++++++++++-------
>  drivers/acpi/fan_hwmon.c |  8 ++++++++
>  4 files changed, 49 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h
> index 488b51e2c..15eba1c70 100644
> --- a/drivers/acpi/fan.h
> +++ b/drivers/acpi/fan.h
> @@ -49,6 +49,7 @@ struct acpi_fan_fst {
>
>  struct acpi_fan {
>         bool acpi4;
> +       bool has_fst;
>         struct acpi_fan_fif fif;
>         struct acpi_fan_fps *fps;
>         int fps_count;
> diff --git a/drivers/acpi/fan_attr.c b/drivers/acpi/fan_attr.c
> index f4f6e2381..22d29ac24 100644
> --- a/drivers/acpi/fan_attr.c
> +++ b/drivers/acpi/fan_attr.c
> @@ -75,15 +75,6 @@ int acpi_fan_create_attributes(struct acpi_device *device)
>         struct acpi_fan *fan = acpi_driver_data(device);
>         int i, status;
>
> -       sysfs_attr_init(&fan->fine_grain_control.attr);
> -       fan->fine_grain_control.show = show_fine_grain_control;
> -       fan->fine_grain_control.store = NULL;
> -       fan->fine_grain_control.attr.name = "fine_grain_control";
> -       fan->fine_grain_control.attr.mode = 0444;
> -       status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
> -       if (status)
> -               return status;
> -
>         /* _FST is present if we are here */
>         sysfs_attr_init(&fan->fst_speed.attr);
>         fan->fst_speed.show = show_fan_speed;
> @@ -92,7 +83,19 @@ int acpi_fan_create_attributes(struct acpi_device *device)
>         fan->fst_speed.attr.mode = 0444;
>         status = sysfs_create_file(&device->dev.kobj, &fan->fst_speed.attr);
>         if (status)
> -               goto rem_fine_grain_attr;
> +               return status;
> +
> +       if (!fan->acpi4)
> +               return 0;
> +
> +       sysfs_attr_init(&fan->fine_grain_control.attr);
> +       fan->fine_grain_control.show = show_fine_grain_control;
> +       fan->fine_grain_control.store = NULL;
> +       fan->fine_grain_control.attr.name = "fine_grain_control";
> +       fan->fine_grain_control.attr.mode = 0444;
> +       status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
> +       if (status)
> +               goto rem_fst_attr;
>
>         for (i = 0; i < fan->fps_count; ++i) {
>                 struct acpi_fan_fps *fps = &fan->fps[i];
> @@ -109,18 +112,18 @@ int acpi_fan_create_attributes(struct acpi_device *device)
>
>                         for (j = 0; j < i; ++j)
>                                 sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
> -                       goto rem_fst_attr;
> +                       goto rem_fine_grain_attr;
>                 }
>         }
>
>         return 0;
>
> -rem_fst_attr:
> -       sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
> -
>  rem_fine_grain_attr:
>         sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
>
> +rem_fst_attr:
> +       sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
> +
>         return status;
>  }
>
> @@ -129,9 +132,13 @@ void acpi_fan_delete_attributes(struct acpi_device *device)
>         struct acpi_fan *fan = acpi_driver_data(device);
>         int i;
>
> +       sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
> +
> +       if (!fan->acpi4)
> +               return;
> +
>         for (i = 0; i < fan->fps_count; ++i)
>                 sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
>
> -       sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
>         sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
>  }
> diff --git a/drivers/acpi/fan_core.c b/drivers/acpi/fan_core.c
> index 10016f52f..8ad12ad3a 100644
> --- a/drivers/acpi/fan_core.c
> +++ b/drivers/acpi/fan_core.c
> @@ -203,12 +203,16 @@ static const struct thermal_cooling_device_ops fan_cooling_ops = {
>   * --------------------------------------------------------------------------
>  */
>
> +static bool acpi_fan_has_fst(struct acpi_device *device)
> +{
> +       return acpi_has_method(device->handle, "_FST");
> +}
> +
>  static bool acpi_fan_is_acpi4(struct acpi_device *device)
>  {
>         return acpi_has_method(device->handle, "_FIF") &&
>                acpi_has_method(device->handle, "_FPS") &&
> -              acpi_has_method(device->handle, "_FSL") &&
> -              acpi_has_method(device->handle, "_FST");
> +              acpi_has_method(device->handle, "_FSL");
>  }
>
>  static int acpi_fan_get_fif(struct acpi_device *device)
> @@ -327,7 +331,12 @@ static int acpi_fan_probe(struct platform_device *pdev)
>         device->driver_data = fan;
>         platform_set_drvdata(pdev, fan);
>
> -       if (acpi_fan_is_acpi4(device)) {
> +       if (acpi_fan_has_fst(device)) {
> +               fan->has_fst = true;
> +               fan->acpi4 = acpi_fan_is_acpi4(device);
> +       }
> +
> +       if (fan->acpi4) {
>                 result = acpi_fan_get_fif(device);
>                 if (result)
>                         return result;
> @@ -335,7 +344,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
>                 result = acpi_fan_get_fps(device);
>                 if (result)
>                         return result;
> +       }
>
> +       if (fan->has_fst) {
>                 result = devm_acpi_fan_create_hwmon(device);
>                 if (result)
>                         return result;
> @@ -343,9 +354,9 @@ static int acpi_fan_probe(struct platform_device *pdev)
>                 result = acpi_fan_create_attributes(device);
>                 if (result)
>                         return result;
> +       }
>
> -               fan->acpi4 = true;
> -       } else {
> +       if (!fan->acpi4) {
>                 result = acpi_device_update_power(device, NULL);
>                 if (result) {
>                         dev_err(&device->dev, "Failed to set initial power state\n");
> @@ -391,7 +402,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
>  err_unregister:
>         thermal_cooling_device_unregister(cdev);
>  err_end:
> -       if (fan->acpi4)
> +       if (fan->has_fst)
>                 acpi_fan_delete_attributes(device);
>
>         return result;
> @@ -401,7 +412,7 @@ static void acpi_fan_remove(struct platform_device *pdev)
>  {
>         struct acpi_fan *fan = platform_get_drvdata(pdev);
>
> -       if (fan->acpi4) {
> +       if (fan->has_fst) {
>                 struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
>
>                 acpi_fan_delete_attributes(device);
> diff --git a/drivers/acpi/fan_hwmon.c b/drivers/acpi/fan_hwmon.c
> index bd0d31a39..e8d906051 100644
> --- a/drivers/acpi/fan_hwmon.c
> +++ b/drivers/acpi/fan_hwmon.c
> @@ -43,6 +43,10 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_
>                 case hwmon_fan_input:
>                         return 0444;
>                 case hwmon_fan_target:
> +                       /* Only acpi4 fans support fan control. */
> +                       if (!fan->acpi4)
> +                               return 0;
> +
>                         /*
>                          * When in fine grain control mode, not every fan control value
>                          * has an associated fan performance state.
> @@ -57,6 +61,10 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_
>         case hwmon_power:
>                 switch (attr) {
>                 case hwmon_power_input:
> +                       /* Only acpi4 fans support fan control. */
> +                       if (!fan->acpi4)
> +                               return 0;
> +
>                         /*
>                          * When in fine grain control mode, not every fan control value
>                          * has an associated fan performance state.
> --

Applied as 6.15 material, thanks!

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ