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 |
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 --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) { }