diff mbox series

[1/6,SRU,OEM-6.0] ACPI: video: Add acpi_video_backlight_use_native() helper

Message ID 20230427074116.188543-2-acelan.kao@canonical.com
State New
Headers show
Series both dell_backlight and nvidia_0 backlight interface appear, and can't adjust the display brightness | expand

Commit Message

AceLan Kao April 27, 2023, 7:41 a.m. UTC
From: Hans de Goede <hdegoede@redhat.com>

BugLink: https://launchpad.net/bugs/2017774

ATM on x86 laptops where we want userspace to use the acpi_video backlight
device we often register both the GPU's native backlight device and
acpi_video's firmware acpi_video# backlight device. This relies on
userspace preferring firmware type backlight devices over native ones, but
registering 2 backlight devices for a single display really is undesirable.

On x86 laptops where the native GPU backlight device should be used,
the registering of other backlight devices is avoided by their drivers
using acpi_video_get_backlight_type() and only registering their backlight
if the return value matches their type.

acpi_video_get_backlight_type() uses
backlight_device_get_by_type(BACKLIGHT_RAW) to determine if a native
driver is available and will never return native if this returns
false. This means that the GPU's native backlight registering code
cannot just call acpi_video_get_backlight_type() to determine if it
should register its backlight, since acpi_video_get_backlight_type() will
never return native until the native backlight has already registered.

To fix this add a new internal native function parameter to
acpi_video_get_backlight_type(), which when set to true will make
acpi_video_get_backlight_type() behave as if a native backlight has
already been registered.

And add a new acpi_video_backlight_use_native() helper, which sets this
to true, for use in native GPU backlight code.

Changes in v2:
- Replace adding a native parameter to acpi_video_get_backlight_type() with
  adding a new acpi_video_backlight_use_native() helper.

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 2600bfa3df9944562d43d1f17016832a6ffa3b38)
Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
---
 drivers/acpi/video_detect.c | 24 ++++++++++++++++++++----
 include/acpi/video.h        |  5 +++++
 2 files changed, 25 insertions(+), 4 deletions(-)

Comments

Andrei Gherzan April 28, 2023, 9:48 a.m. UTC | #1
On 23/04/27 03:41PM, AceLan Kao wrote:
> From: Hans de Goede <hdegoede@redhat.com>
> 
> BugLink: https://launchpad.net/bugs/2017774
> 
> ATM on x86 laptops where we want userspace to use the acpi_video backlight
> device we often register both the GPU's native backlight device and
> acpi_video's firmware acpi_video# backlight device. This relies on
> userspace preferring firmware type backlight devices over native ones, but
> registering 2 backlight devices for a single display really is undesirable.
> 
> On x86 laptops where the native GPU backlight device should be used,
> the registering of other backlight devices is avoided by their drivers
> using acpi_video_get_backlight_type() and only registering their backlight
> if the return value matches their type.
> 
> acpi_video_get_backlight_type() uses
> backlight_device_get_by_type(BACKLIGHT_RAW) to determine if a native
> driver is available and will never return native if this returns
> false. This means that the GPU's native backlight registering code
> cannot just call acpi_video_get_backlight_type() to determine if it
> should register its backlight, since acpi_video_get_backlight_type() will
> never return native until the native backlight has already registered.
> 
> To fix this add a new internal native function parameter to
> acpi_video_get_backlight_type(), which when set to true will make
> acpi_video_get_backlight_type() behave as if a native backlight has
> already been registered.
> 
> And add a new acpi_video_backlight_use_native() helper, which sets this
> to true, for use in native GPU backlight code.
> 
> Changes in v2:
> - Replace adding a native parameter to acpi_video_get_backlight_type() with
>   adding a new acpi_video_backlight_use_native() helper.
> 
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> (cherry picked from commit 2600bfa3df9944562d43d1f17016832a6ffa3b38)

There is a Chromebook follow up fix for this:
e9cf4d9b9a6fdb1df6401a59f5ac5d24006bfeae

Would it make sense to include it too?

> Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
> ---
>  drivers/acpi/video_detect.c | 24 ++++++++++++++++++++----
>  include/acpi/video.h        |  5 +++++
>  2 files changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
> index 68a566f69684..5f620054bff4 100644
> --- a/drivers/acpi/video_detect.c
> +++ b/drivers/acpi/video_detect.c
> @@ -17,8 +17,9 @@
>   * Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
>   * sony_acpi,... can take care about backlight brightness.
>   *
> - * Backlight drivers can use acpi_video_get_backlight_type() to determine
> - * which driver should handle the backlight.
> + * Backlight drivers can use acpi_video_get_backlight_type() to determine which
> + * driver should handle the backlight. RAW/GPU-driver backlight drivers must
> + * use the acpi_video_backlight_use_native() helper for this.
>   *
>   * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
>   * this file will not be compiled and acpi_video_get_backlight_type() will
> @@ -635,9 +636,10 @@ static int acpi_video_backlight_notify(struct notifier_block *nb,
>   * Arguably the native on win8 check should be done first, but that would
>   * be a behavior change, which may causes issues.
>   */
> -enum acpi_backlight_type acpi_video_get_backlight_type(void)
> +static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
>  {
>  	static DEFINE_MUTEX(init_mutex);
> +	static bool native_available;
>  	static bool init_done;
>  	static long video_caps;
>  
> @@ -657,6 +659,8 @@ enum acpi_backlight_type acpi_video_get_backlight_type(void)
>  			backlight_notifier_registered = true;
>  		init_done = true;
>  	}
> +	if (native)
> +		native_available = true;
>  	mutex_unlock(&init_mutex);
>  
>  	if (acpi_backlight_cmdline != acpi_backlight_undef)
> @@ -668,13 +672,25 @@ enum acpi_backlight_type acpi_video_get_backlight_type(void)
>  	if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
>  		return acpi_backlight_vendor;
>  
> -	if (acpi_osi_is_win8() && backlight_device_get_by_type(BACKLIGHT_RAW))
> +	if (acpi_osi_is_win8() &&
> +	    (native_available || backlight_device_get_by_type(BACKLIGHT_RAW)))
>  		return acpi_backlight_native;
>  
>  	return acpi_backlight_video;
>  }
> +
> +enum acpi_backlight_type acpi_video_get_backlight_type(void)
> +{
> +	return __acpi_video_get_backlight_type(false);
> +}
>  EXPORT_SYMBOL(acpi_video_get_backlight_type);
>  
> +bool acpi_video_backlight_use_native(void)
> +{
> +	return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
> +}
> +EXPORT_SYMBOL(acpi_video_backlight_use_native);
> +
>  /*
>   * Set the preferred backlight interface type based on DMI info.
>   * This function allows DMI blacklists to be implemented by external
> diff --git a/include/acpi/video.h b/include/acpi/video.h
> index db8548ff03ce..4705e339c252 100644
> --- a/include/acpi/video.h
> +++ b/include/acpi/video.h
> @@ -56,6 +56,7 @@ extern void acpi_video_unregister(void);
>  extern int acpi_video_get_edid(struct acpi_device *device, int type,
>  			       int device_id, void **edid);
>  extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
> +extern bool acpi_video_backlight_use_native(void);
>  extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
>  /*
>   * Note: The value returned by acpi_video_handles_brightness_key_presses()
> @@ -77,6 +78,10 @@ static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
>  {
>  	return acpi_backlight_vendor;
>  }
> +static inline bool acpi_video_backlight_use_native(void)
> +{
> +	return true;
> +}
>  static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
>  {
>  }
> -- 
> 2.34.1
diff mbox series

Patch

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 68a566f69684..5f620054bff4 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -17,8 +17,9 @@ 
  * Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
  * sony_acpi,... can take care about backlight brightness.
  *
- * Backlight drivers can use acpi_video_get_backlight_type() to determine
- * which driver should handle the backlight.
+ * Backlight drivers can use acpi_video_get_backlight_type() to determine which
+ * driver should handle the backlight. RAW/GPU-driver backlight drivers must
+ * use the acpi_video_backlight_use_native() helper for this.
  *
  * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
  * this file will not be compiled and acpi_video_get_backlight_type() will
@@ -635,9 +636,10 @@  static int acpi_video_backlight_notify(struct notifier_block *nb,
  * Arguably the native on win8 check should be done first, but that would
  * be a behavior change, which may causes issues.
  */
-enum acpi_backlight_type acpi_video_get_backlight_type(void)
+static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
 {
 	static DEFINE_MUTEX(init_mutex);
+	static bool native_available;
 	static bool init_done;
 	static long video_caps;
 
@@ -657,6 +659,8 @@  enum acpi_backlight_type acpi_video_get_backlight_type(void)
 			backlight_notifier_registered = true;
 		init_done = true;
 	}
+	if (native)
+		native_available = true;
 	mutex_unlock(&init_mutex);
 
 	if (acpi_backlight_cmdline != acpi_backlight_undef)
@@ -668,13 +672,25 @@  enum acpi_backlight_type acpi_video_get_backlight_type(void)
 	if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
 		return acpi_backlight_vendor;
 
-	if (acpi_osi_is_win8() && backlight_device_get_by_type(BACKLIGHT_RAW))
+	if (acpi_osi_is_win8() &&
+	    (native_available || backlight_device_get_by_type(BACKLIGHT_RAW)))
 		return acpi_backlight_native;
 
 	return acpi_backlight_video;
 }
+
+enum acpi_backlight_type acpi_video_get_backlight_type(void)
+{
+	return __acpi_video_get_backlight_type(false);
+}
 EXPORT_SYMBOL(acpi_video_get_backlight_type);
 
+bool acpi_video_backlight_use_native(void)
+{
+	return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
+}
+EXPORT_SYMBOL(acpi_video_backlight_use_native);
+
 /*
  * Set the preferred backlight interface type based on DMI info.
  * This function allows DMI blacklists to be implemented by external
diff --git a/include/acpi/video.h b/include/acpi/video.h
index db8548ff03ce..4705e339c252 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -56,6 +56,7 @@  extern void acpi_video_unregister(void);
 extern int acpi_video_get_edid(struct acpi_device *device, int type,
 			       int device_id, void **edid);
 extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
+extern bool acpi_video_backlight_use_native(void);
 extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
 /*
  * Note: The value returned by acpi_video_handles_brightness_key_presses()
@@ -77,6 +78,10 @@  static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
 {
 	return acpi_backlight_vendor;
 }
+static inline bool acpi_video_backlight_use_native(void)
+{
+	return true;
+}
 static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
 {
 }