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@xxxxxxxxx> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- 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 5d7f38016a24..5f105eaa7d30 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 @@ -571,9 +572,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; @@ -593,6 +595,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) @@ -604,13 +608,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.37.2