From 2600bfa3df9944562d43d1f17016832a6ffa3b38 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 15 Apr 2022 13:59:48 +0200 Subject: ACPI: video: Add acpi_video_backlight_use_native() helper 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 Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') 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 -- cgit v1.2.3 From a2fc3c899bb091ec69cd74d4d69d71f8b2acdc11 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 28 Apr 2022 14:45:35 +0200 Subject: ACPI: video: Drop backlight_device_get_by_type() call from acpi_video_get_backlight_type() All x86/ACPI kms drivers which register native/BACKLIGHT_RAW type backlight devices call acpi_video_backlight_use_native() now. This sets __acpi_video_get_backlight_type()'s internal static native_available flag. This makes the backlight_device_get_by_type(BACKLIGHT_RAW) check unnecessary. Relying on the cached native_available value not only is simpler, it will also work correctly in cases where then native backlight registration was skipped because of acpi_video_backlight_use_native() returning false. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 5f105eaa7d30..385eb49c763f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -608,8 +608,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) if (!(video_caps & ACPI_VIDEO_BACKLIGHT)) return acpi_backlight_vendor; - if (acpi_osi_is_win8() && - (native_available || backlight_device_get_by_type(BACKLIGHT_RAW))) + if (acpi_osi_is_win8() && native_available) return acpi_backlight_native; return acpi_backlight_video; -- cgit v1.2.3 From c1af8bec569dd6b8d874c14455ab02398c3d34cd Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 28 Apr 2022 17:53:51 +0200 Subject: ACPI: video: Remove acpi_video_bus from list before tearing it down Move the list_del removing an acpi_video_bus from video_bus_head on teardown to before the teardown is done, to avoid code iterating over the video_bus_head list seeing acpi_video_bus objects on there which are (partly) torn down already. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/acpi_video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 5cbe2196176d..cde8ffa9f0b8 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2111,14 +2111,14 @@ static int acpi_video_bus_remove(struct acpi_device *device) video = acpi_driver_data(device); - acpi_video_bus_remove_notify_handler(video); - acpi_video_bus_unregister_backlight(video); - acpi_video_bus_put_devices(video); - mutex_lock(&video_list_lock); list_del(&video->entry); mutex_unlock(&video_list_lock); + acpi_video_bus_remove_notify_handler(video); + acpi_video_bus_unregister_backlight(video); + acpi_video_bus_put_devices(video); + kfree(video->attached_array); kfree(video); -- cgit v1.2.3 From 038a8191ae7a636586a4415b001cece831ab7019 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 29 Apr 2022 13:29:31 +0200 Subject: ACPI: video: Simplify acpi_video_unregister_backlight() When acpi_video_register() has not run yet the video_bus_head will be empty, so there is no need to check the register_count flag first. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/acpi_video.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index cde8ffa9f0b8..8545bf94866f 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2257,14 +2257,10 @@ void acpi_video_unregister_backlight(void) { struct acpi_video_bus *video; - mutex_lock(®ister_count_mutex); - if (register_count) { - mutex_lock(&video_list_lock); - list_for_each_entry(video, &video_bus_head, entry) - acpi_video_bus_unregister_backlight(video); - mutex_unlock(&video_list_lock); - } - mutex_unlock(®ister_count_mutex); + mutex_lock(&video_list_lock); + list_for_each_entry(video, &video_bus_head, entry) + acpi_video_bus_unregister_backlight(video); + mutex_unlock(&video_list_lock); } bool acpi_video_handles_brightness_key_presses(void) -- cgit v1.2.3 From 3dbc80a3e4c55c4a5b89ef207bed7b7de36157b4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 28 Apr 2022 17:41:46 +0200 Subject: ACPI: video: Make backlight class device registration a separate step (v2) On x86/ACPI boards the acpi_video driver will usually initialize before the kms driver (except i915). This causes /sys/class/backlight/acpi_video0 to show up and then the kms driver registers its own native backlight device after which the drivers/acpi/video_detect.c code unregisters the acpi_video0 device (when acpi_video_get_backlight_type()==native). This means that userspace briefly sees 2 devices and the disappearing of acpi_video0 after a brief time confuses the systemd backlight level save/restore code, see e.g.: https://bbs.archlinux.org/viewtopic.php?id=269920 To fix this make backlight class device registration a separate step done by a new acpi_video_register_backlight() function. The intend is for this to be called by the drm/kms driver *after* it is done setting up its own native backlight device. So that acpi_video_get_backlight_type() knows if a native backlight will be available or not at acpi_video backlight registration time, avoiding the add + remove dance. Note the new acpi_video_register_backlight() function is also called from a delayed work to ensure that the acpi_video backlight devices does get registered if necessary even if there is no drm/kms driver or when it is disabled. Changes in v2: - Make register_backlight_delay a module parameter, mainly so that it can be disabled by Nvidia binary driver users Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/acpi_video.c | 50 ++++++++++++++++++++++++++++++++++++++++++++--- include/acpi/video.h | 2 ++ 2 files changed, 49 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 8545bf94866f..09dd86f86cf3 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -73,6 +73,16 @@ module_param(device_id_scheme, bool, 0444); static int only_lcd = -1; module_param(only_lcd, int, 0444); +/* + * Display probing is known to take up to 5 seconds, so delay the fallback + * backlight registration by 5 seconds + 3 seconds for some extra margin. + */ +static int register_backlight_delay = 8; +module_param(register_backlight_delay, int, 0444); +MODULE_PARM_DESC(register_backlight_delay, + "Delay in seconds before doing fallback (non GPU driver triggered) " + "backlight registration, set to 0 to disable."); + static bool may_report_brightness_keys; static int register_count; static DEFINE_MUTEX(register_count_mutex); @@ -81,6 +91,9 @@ static LIST_HEAD(video_bus_head); static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device); static void acpi_video_bus_notify(struct acpi_device *device, u32 event); +static void acpi_video_bus_register_backlight_work(struct work_struct *ignored); +static DECLARE_DELAYED_WORK(video_bus_register_backlight_work, + acpi_video_bus_register_backlight_work); void acpi_video_detect_exit(void); /* @@ -1859,8 +1872,6 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) if (video->backlight_registered) return 0; - acpi_video_run_bcl_for_osi(video); - if (acpi_video_get_backlight_type() != acpi_backlight_video) return 0; @@ -2086,7 +2097,11 @@ static int acpi_video_bus_add(struct acpi_device *device) list_add_tail(&video->entry, &video_bus_head); mutex_unlock(&video_list_lock); - acpi_video_bus_register_backlight(video); + /* + * The userspace visible backlight_device gets registered separately + * from acpi_video_register_backlight(). + */ + acpi_video_run_bcl_for_osi(video); acpi_video_bus_add_notify_handler(video); return 0; @@ -2125,6 +2140,11 @@ static int acpi_video_bus_remove(struct acpi_device *device) return 0; } +static void acpi_video_bus_register_backlight_work(struct work_struct *ignored) +{ + acpi_video_register_backlight(); +} + static int __init is_i740(struct pci_dev *dev) { if (dev->device == 0x00D1) @@ -2235,6 +2255,18 @@ int acpi_video_register(void) */ register_count = 1; + /* + * acpi_video_bus_add() skips registering the userspace visible + * backlight_device. The intend is for this to be registered by the + * drm/kms driver calling acpi_video_register_backlight() *after* it is + * done setting up its own native backlight device. The delayed work + * ensures that acpi_video_register_backlight() always gets called + * eventually, in case there is no drm/kms driver or it is disabled. + */ + if (register_backlight_delay) + schedule_delayed_work(&video_bus_register_backlight_work, + register_backlight_delay * HZ); + leave: mutex_unlock(®ister_count_mutex); return ret; @@ -2245,6 +2277,7 @@ void acpi_video_unregister(void) { mutex_lock(®ister_count_mutex); if (register_count) { + cancel_delayed_work_sync(&video_bus_register_backlight_work); acpi_bus_unregister_driver(&acpi_video_bus); register_count = 0; may_report_brightness_keys = false; @@ -2253,6 +2286,17 @@ void acpi_video_unregister(void) } EXPORT_SYMBOL(acpi_video_unregister); +void acpi_video_register_backlight(void) +{ + struct acpi_video_bus *video; + + mutex_lock(&video_list_lock); + list_for_each_entry(video, &video_bus_head, entry) + acpi_video_bus_register_backlight(video); + mutex_unlock(&video_list_lock); +} +EXPORT_SYMBOL(acpi_video_register_backlight); + void acpi_video_unregister_backlight(void) { struct acpi_video_bus *video; diff --git a/include/acpi/video.h b/include/acpi/video.h index 4705e339c252..0625806d3bbd 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -53,6 +53,7 @@ enum acpi_backlight_type { #if IS_ENABLED(CONFIG_ACPI_VIDEO) extern int acpi_video_register(void); extern void acpi_video_unregister(void); +extern void acpi_video_register_backlight(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); @@ -69,6 +70,7 @@ extern int acpi_video_get_levels(struct acpi_device *device, #else static inline int acpi_video_register(void) { return -ENODEV; } static inline void acpi_video_unregister(void) { return; } +static inline void acpi_video_register_backlight(void) { return; } static inline int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid) { -- cgit v1.2.3 From 6cb634d0dc850cc1ae54868de7815df53e64a465 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 29 Apr 2022 13:00:15 +0200 Subject: ACPI: video: Remove code to unregister acpi_video backlight when a native backlight registers Remove the code to unregister acpi_video backlight devices when a native backlight device gets registered later. Now that the acpi_video backlight device registration is a separate step which runs later, after the drm/kms driver is done setting up its own native backlight device, it is no longer necessary to monitor for a native (BACKLIGHT_RAW) device showing up later and to then unregister the acpi_video backlight device(s). Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/acpi_video.c | 2 -- drivers/acpi/video_detect.c | 36 ------------------------------------ 2 files changed, 38 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 09dd86f86cf3..d1e41f30c004 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -94,7 +94,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event); static void acpi_video_bus_register_backlight_work(struct work_struct *ignored); static DECLARE_DELAYED_WORK(video_bus_register_backlight_work, acpi_video_bus_register_backlight_work); -void acpi_video_detect_exit(void); /* * Indices in the _BCL method response: the first two items are special, @@ -2342,7 +2341,6 @@ static int __init acpi_video_init(void) static void __exit acpi_video_exit(void) { - acpi_video_detect_exit(); acpi_video_unregister(); } diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 385eb49c763f..fb49b8f4523a 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -38,10 +38,6 @@ void acpi_video_unregister_backlight(void); -static bool backlight_notifier_registered; -static struct notifier_block backlight_nb; -static struct work_struct backlight_notify_work; - static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef; static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef; @@ -538,26 +534,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { }, }; -/* This uses a workqueue to avoid various locking ordering issues */ -static void acpi_video_backlight_notify_work(struct work_struct *work) -{ - if (acpi_video_get_backlight_type() != acpi_backlight_video) - acpi_video_unregister_backlight(); -} - -static int acpi_video_backlight_notify(struct notifier_block *nb, - unsigned long val, void *bd) -{ - struct backlight_device *backlight = bd; - - /* A raw bl registering may change video -> native */ - if (backlight->props.type == BACKLIGHT_RAW && - val == BACKLIGHT_REGISTERED) - schedule_work(&backlight_notify_work); - - return NOTIFY_OK; -} - /* * Determine which type of backlight interface to use on this system, * First check cmdline, then dmi quirks, then do autodetect. @@ -587,12 +563,6 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_video, NULL, &video_caps, NULL); - INIT_WORK(&backlight_notify_work, - acpi_video_backlight_notify_work); - backlight_nb.notifier_call = acpi_video_backlight_notify; - backlight_nb.priority = 0; - if (backlight_register_notifier(&backlight_nb) == 0) - backlight_notifier_registered = true; init_done = true; } if (native) @@ -639,9 +609,3 @@ void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type) acpi_video_unregister_backlight(); } EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type); - -void __exit acpi_video_detect_exit(void) -{ - if (backlight_notifier_registered) - backlight_unregister_notifier(&backlight_nb); -} -- cgit v1.2.3 From b39be9f441f9d7320e6020bdf8ec1522d6c81d1e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 4 Jun 2022 14:38:24 +0200 Subject: ACPI: video: Refactor acpi_video_get_backlight_type() a bit Refactor acpi_video_get_backlight_type() so that the heuristics / detection steps are stricly in order of descending precedence. Also move the comments describing the steps to when the various steps are actually done, to avoid the comments getting out of sync with the code. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index fb49b8f4523a..cc9d0d91e268 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -537,16 +537,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = { /* * Determine which type of backlight interface to use on this system, * First check cmdline, then dmi quirks, then do autodetect. - * - * The autodetect order is: - * 1) Is the acpi-video backlight interface supported -> - * no, use a vendor interface - * 2) Is this a win8 "ready" BIOS and do we have a native interface -> - * yes, use a native interface - * 3) Else use the acpi-video interface - * - * Arguably the native on win8 check should be done first, but that would - * be a behavior change, which may causes issues. */ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) { @@ -569,19 +559,36 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) native_available = true; mutex_unlock(&init_mutex); + /* + * The below heuristics / detection steps are in order of descending + * presedence. The commandline takes presedence over anything else. + */ if (acpi_backlight_cmdline != acpi_backlight_undef) return acpi_backlight_cmdline; + /* DMI quirks override any autodetection. */ if (acpi_backlight_dmi != acpi_backlight_undef) return acpi_backlight_dmi; - if (!(video_caps & ACPI_VIDEO_BACKLIGHT)) - return acpi_backlight_vendor; - - if (acpi_osi_is_win8() && native_available) - return acpi_backlight_native; + /* On systems with ACPI video use either native or ACPI video. */ + if (video_caps & ACPI_VIDEO_BACKLIGHT) { + /* + * Windows 8 and newer no longer use the ACPI video interface, + * so it often does not work. If the ACPI tables are written + * for win8 and native brightness ctl is available, use that. + * + * The native check deliberately is inside the if acpi-video + * block on older devices without acpi-video support native + * is usually not the best choice. + */ + if (acpi_osi_is_win8() && native_available) + return acpi_backlight_native; + else + return acpi_backlight_video; + } - return acpi_backlight_video; + /* No ACPI video (old hw), use vendor specific fw methods. */ + return acpi_backlight_vendor; } enum acpi_backlight_type acpi_video_get_backlight_type(void) -- cgit v1.2.3 From fe7aebb40d42bf8e830019d6f57c47cf7d85aa61 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 4 Jun 2022 14:06:18 +0200 Subject: ACPI: video: Add Nvidia WMI EC brightness control detection (v3) On some new laptop designs a new Nvidia specific WMI interface is present which gives info about panel brightness control and may allow controlling the brightness through this interface when the embedded controller is used for brightness control. When this WMI interface is present and indicates that the EC is used, then this interface should be used for brightness control. Changes in v2: - Use the new shared nvidia-wmi-ec-backlight.h header for the WMI firmware API definitions - ACPI_VIDEO can now be enabled on non X86 too, adjust the Kconfig changes to match this. Changes in v3: - Use WMI_BRIGHTNESS_GUID define Acked-by: Rafael J. Wysocki Reviewed-by: Daniel Dadap Signed-off-by: Hans de Goede --- drivers/acpi/Kconfig | 1 + drivers/acpi/video_detect.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/gma500/Kconfig | 2 ++ drivers/gpu/drm/i915/Kconfig | 2 ++ include/acpi/video.h | 1 + 5 files changed, 43 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 7802d8846a8d..44ad4b6bd234 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -212,6 +212,7 @@ config ACPI_VIDEO tristate "Video" depends on BACKLIGHT_CLASS_DEVICE depends on INPUT + depends on ACPI_WMI || !X86 select THERMAL help This driver implements the ACPI Extensions For Display Adapters diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index cc9d0d91e268..4dc7fb865083 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,36 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } +/* This depends on ACPI_WMI which is X86 only */ +#ifdef CONFIG_X86 +static bool nvidia_wmi_ec_supported(void) +{ + struct wmi_brightness_args args = { + .mode = WMI_BRIGHTNESS_MODE_GET, + .val = 0, + .ret = 0, + }; + struct acpi_buffer buf = { (acpi_size)sizeof(args), &args }; + acpi_status status; + + status = wmi_evaluate_method(WMI_BRIGHTNESS_GUID, 0, + WMI_BRIGHTNESS_METHOD_SOURCE, &buf, &buf); + if (ACPI_FAILURE(status)) + return false; + + /* + * If brightness is handled by the EC then nvidia-wmi-ec-backlight + * should be used, else the GPU driver(s) should be used. + */ + return args.ret == WMI_BRIGHTNESS_SOURCE_EC; +} +#else +static bool nvidia_wmi_ec_supported(void) +{ + return false; +} +#endif + /* Force to use vendor driver when the ACPI device is known to be * buggy */ static int video_detect_force_vendor(const struct dmi_system_id *d) @@ -541,6 +572,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) { static DEFINE_MUTEX(init_mutex); + static bool nvidia_wmi_ec_present; static bool native_available; static bool init_done; static long video_caps; @@ -553,6 +585,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_video, NULL, &video_caps, NULL); + nvidia_wmi_ec_present = nvidia_wmi_ec_supported(); init_done = true; } if (native) @@ -570,6 +603,10 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) if (acpi_backlight_dmi != acpi_backlight_undef) return acpi_backlight_dmi; + /* Special cases such as nvidia_wmi_ec and apple gmux. */ + if (nvidia_wmi_ec_present) + return acpi_backlight_nvidia_wmi_ec; + /* On systems with ACPI video use either native or ACPI video. */ if (video_caps & ACPI_VIDEO_BACKLIGHT) { /* diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig index 0cff20265f97..807b989e3c77 100644 --- a/drivers/gpu/drm/gma500/Kconfig +++ b/drivers/gpu/drm/gma500/Kconfig @@ -7,6 +7,8 @@ config DRM_GMA500 select ACPI_VIDEO if ACPI select BACKLIGHT_CLASS_DEVICE if ACPI select INPUT if ACPI + select X86_PLATFORM_DEVICES if ACPI + select ACPI_WMI if ACPI help Say yes for an experimental 2D KMS framebuffer driver for the Intel GMA500 (Poulsbo), Intel GMA600 (Moorestown/Oak Trail) and diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 7ae3b7d67fcf..3efce05d7b57 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -23,6 +23,8 @@ config DRM_I915 # but for select to work, need to select ACPI_VIDEO's dependencies, ick select BACKLIGHT_CLASS_DEVICE if ACPI select INPUT if ACPI + select X86_PLATFORM_DEVICES if ACPI + select ACPI_WMI if ACPI select ACPI_VIDEO if ACPI select ACPI_BUTTON if ACPI select SYNC_FILE diff --git a/include/acpi/video.h b/include/acpi/video.h index 0625806d3bbd..91578e77ac4e 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -48,6 +48,7 @@ enum acpi_backlight_type { acpi_backlight_video, acpi_backlight_vendor, acpi_backlight_native, + acpi_backlight_nvidia_wmi_ec, }; #if IS_ENABLED(CONFIG_ACPI_VIDEO) -- cgit v1.2.3 From 21245df307cbee9e04d5b4aac3fd04334f6b45dc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 4 Jun 2022 15:21:51 +0200 Subject: ACPI: video: Add Apple GMUX brightness control detection On Apple laptops with an Apple GMUX using this for brightness control, should take precedence of any other brightness control methods. Add apple-gmux detection to acpi_video_get_backlight_type() using the already existing apple_gmux_present() helper function. This will allow removig the (ab)use of: acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); Inside the apple-gmux driver. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 4 ++++ include/acpi/video.h | 1 + 2 files changed, 5 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 4dc7fb865083..be2fc43418af 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -607,6 +608,9 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) if (nvidia_wmi_ec_present) return acpi_backlight_nvidia_wmi_ec; + if (apple_gmux_present()) + return acpi_backlight_apple_gmux; + /* On systems with ACPI video use either native or ACPI video. */ if (video_caps & ACPI_VIDEO_BACKLIGHT) { /* diff --git a/include/acpi/video.h b/include/acpi/video.h index 91578e77ac4e..dbd48cb8bd23 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -49,6 +49,7 @@ enum acpi_backlight_type { acpi_backlight_vendor, acpi_backlight_native, acpi_backlight_nvidia_wmi_ec, + acpi_backlight_apple_gmux, }; #if IS_ENABLED(CONFIG_ACPI_VIDEO) -- cgit v1.2.3 From a2ed70d0ecb11b7eb3ff14ed897cd0995c86651d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 4 Jun 2022 16:18:05 +0200 Subject: platform/x86: toshiba_acpi: Stop using acpi_video_set_dmi_backlight_type() acpi_video_set_dmi_backlight_type() is troublesome because it may end up getting called after other backlight drivers have already called acpi_video_get_backlight_type() resulting in the other drivers already being registered even though they should not. In case of the acpi_video backlight, acpi_video_set_dmi_backlight_type() actually calls acpi_video_unregister_backlight() since that is often probed earlier, leading to userspace seeing the acpi_video0 class device being briefly available, leading to races in userspace where udev probe-rules try to access the device and it is already gone. In case of toshiba_acpi there are no DMI quirks to move to acpi/video_detect.c, but it also (ab)uses it for transflective displays. Adding transflective display support to video_detect.c would be quite involved. But luckily there are only 2 known models with a transflective display, so we can just add DMI quirks for those. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 19 +++++++++++++++++++ drivers/platform/x86/toshiba_acpi.c | 16 ---------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index be2fc43418af..74e2087c8ff0 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -190,6 +190,25 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, + /* + * Toshiba models with Transflective display, these need to use + * the toshiba_acpi vendor driver for proper Transflective handling. + */ + { + .callback = video_detect_force_vendor, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R500"), + }, + }, + { + .callback = video_detect_force_vendor, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R600"), + }, + }, + /* * These models have a working acpi_video backlight control, and using * native backlight causes a regression where backlight does not work diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 0fc9e8b8827b..030dc37d50b8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -271,14 +271,6 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = { { KE_END, 0 }, }; -/* - * List of models which have a broken acpi-video backlight interface and thus - * need to use the toshiba (vendor) interface instead. - */ -static const struct dmi_system_id toshiba_vendor_backlight_dmi[] = { - {} -}; - /* * Utility */ @@ -2881,14 +2873,6 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) return 0; } - /* - * Tell acpi-video-detect code to prefer vendor backlight on all - * systems with transflective backlight and on dmi matched systems. - */ - if (dev->tr_backlight_supported || - dmi_check_system(toshiba_vendor_backlight_dmi)) - acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); - if (acpi_video_get_backlight_type() != acpi_backlight_vendor) return 0; -- cgit v1.2.3 From 0172df18dc4309a7052cbb37a6939f7a8b0735d5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 4 Jun 2022 18:28:52 +0200 Subject: platform/x86: acer-wmi: Move backlight DMI quirks to acpi/video_detect.c Move the backlight DMI quirks to acpi/video_detect.c, so that the driver no longer needs to call acpi_video_set_dmi_backlight_type(). acpi_video_set_dmi_backlight_type() is troublesome because it may end up getting called after other backlight drivers have already called acpi_video_get_backlight_type() resulting in the other drivers already being registered even though they should not. Note that even though the DMI quirk table name was video_vendor_dmi_table, 5/6 quirks were actually quirks to use the GPU native backlight. These 5 quirks also had a callback in their dmi_system_id entry which disabled the acer-wmi vendor driver; and any DMI match resulted in: acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); which disabled the acpi_video driver, so only the native driver was left. The new entries for these 5/6 devices correctly marks these as needing the native backlight driver. Also note that other changes in this series change the native backlight drivers to no longer unconditionally register their backlight. Instead these drivers now do this check: if (acpi_video_get_backlight_type(false) != acpi_backlight_native) return 0; /* bail */ which without this patch would have broken these 5/6 "special" quirks. Since I had to look at all the commits adding the quirks anyways, to make sure that I understood the code correctly, I've also added links to the various original bugzillas for these quirks to the new entries. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 53 +++++++++++++++++++++++++++++++++ drivers/platform/x86/acer-wmi.c | 66 ----------------------------------------- 2 files changed, 53 insertions(+), 66 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 74e2087c8ff0..6a2523bc02ba 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -149,6 +149,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "X360"), }, }, + { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */ + .callback = video_detect_force_vendor, + /* Acer KAV80 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"), + }, + }, { .callback = video_detect_force_vendor, /* Asus UL30VT */ @@ -437,6 +446,41 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "JV50"), }, }, + { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1012674 */ + .callback = video_detect_force_native, + /* Acer Aspire 5741 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"), + }, + }, + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=42993 */ + .callback = video_detect_force_native, + /* Acer Aspire 5750 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), + }, + }, + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=42833 */ + .callback = video_detect_force_native, + /* Acer Extensa 5235 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"), + }, + }, + { + .callback = video_detect_force_native, + /* Acer TravelMate 4750 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"), + }, + }, { /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */ .callback = video_detect_force_native, @@ -447,6 +491,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"), }, }, + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=36322 */ + .callback = video_detect_force_native, + /* Acer TravelMate 5760 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"), + }, + }, { .callback = video_detect_force_native, /* ASUSTeK COMPUTER INC. GA401 */ diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index e0230ea0cb7e..b933a5165edb 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -643,69 +643,6 @@ static const struct dmi_system_id non_acer_quirks[] __initconst = { {} }; -static int __init -video_set_backlight_video_vendor(const struct dmi_system_id *d) -{ - interface->capability &= ~ACER_CAP_BRIGHTNESS; - pr_info("Brightness must be controlled by generic video driver\n"); - return 0; -} - -static const struct dmi_system_id video_vendor_dmi_table[] __initconst = { - { - .callback = video_set_backlight_video_vendor, - .ident = "Acer TravelMate 4750", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"), - }, - }, - { - .callback = video_set_backlight_video_vendor, - .ident = "Acer Extensa 5235", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"), - }, - }, - { - .callback = video_set_backlight_video_vendor, - .ident = "Acer TravelMate 5760", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"), - }, - }, - { - .callback = video_set_backlight_video_vendor, - .ident = "Acer Aspire 5750", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), - }, - }, - { - .callback = video_set_backlight_video_vendor, - .ident = "Acer Aspire 5741", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"), - }, - }, - { - /* - * Note no video_set_backlight_video_vendor, we must use the - * acer interface, as there is no native backlight interface. - */ - .ident = "Acer KAV80", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"), - }, - }, - {} -}; - /* Find which quirks are needed for a particular vendor/ model pair */ static void __init find_quirks(void) { @@ -2477,9 +2414,6 @@ static int __init acer_wmi_init(void) set_quirks(); - if (dmi_check_system(video_vendor_dmi_table)) - acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); - if (acpi_video_get_backlight_type() != acpi_backlight_vendor) interface->capability &= ~ACER_CAP_BRIGHTNESS; -- cgit v1.2.3 From 52796b304a517b002300bbb67074b38a6003fd7a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Jun 2022 17:15:24 +0200 Subject: platform/x86: asus-wmi: Move acpi_backlight=vendor quirks to ACPI video_detect.c Remove the asus-wmi quirk_entry.wmi_backlight_power quirk-flag, which called acpi_video_set_dmi_backlight_type(acpi_backlight_vendor) and replace it with acpi/video_detect.c video_detect_dmi_table[] entries using the video_detect_force_vendor callback. acpi_video_set_dmi_backlight_type() is troublesome because it may end up getting called after other backlight drivers have already called acpi_video_get_backlight_type() resulting in the other drivers already being registered even though they should not. Note no entries are dropped from the dmi_system_id table in asus-nb-wmi.c. This is because the entries using the removed wmi_backlight_power flag also use other model specific quirks from the asus-wmi quirk_entry struct. So the quirk_asus_x55u struct and the entries pointing to it cannot be dropped. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 40 ++++++++++++++++++++++++++++++++++++++ drivers/platform/x86/asus-nb-wmi.c | 7 ------- drivers/platform/x86/asus-wmi.c | 3 --- drivers/platform/x86/asus-wmi.h | 1 - drivers/platform/x86/eeepc-wmi.c | 25 +----------------------- 5 files changed, 41 insertions(+), 35 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 6a2523bc02ba..d893313fe1a0 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -174,6 +174,46 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), }, }, + { + .callback = video_detect_force_vendor, + /* Asus X55U */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X55U"), + }, + }, + { + .callback = video_detect_force_vendor, + /* Asus X101CH */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X101CH"), + }, + }, + { + .callback = video_detect_force_vendor, + /* Asus X401U */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X401U"), + }, + }, + { + .callback = video_detect_force_vendor, + /* Asus X501U */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X501U"), + }, + }, + { + .callback = video_detect_force_vendor, + /* Asus 1015CX */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"), + }, + }, { .callback = video_detect_force_vendor, /* GIGABYTE GB-BXBT-2807 */ diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 478dd300b9c9..810a94557a85 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -79,12 +79,10 @@ static struct quirk_entry quirk_asus_q500a = { /* * For those machines that need software to control bt/wifi status - * and can't adjust brightness through ACPI interface * and have duplicate events(ACPI and WMI) for display toggle */ static struct quirk_entry quirk_asus_x55u = { .wapf = 4, - .wmi_backlight_power = true, .wmi_backlight_set_devstate = true, .no_display_toggle = true, }; @@ -147,11 +145,6 @@ static const struct dmi_system_id asus_quirks[] = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "U32U"), }, - /* - * Note this machine has a Brazos APU, and most Brazos Asus - * machines need quirk_asus_x55u / wmi_backlight_power but - * here acpi-video seems to work fine for backlight control. - */ .driver_data = &quirk_asus_wapf4, }, { diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 301166a5697d..5cf9d9aff164 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -3634,9 +3634,6 @@ static int asus_wmi_add(struct platform_device *pdev) if (asus->driver->quirks->wmi_force_als_set) asus_wmi_set_als(); - if (asus->driver->quirks->wmi_backlight_power) - acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); - if (asus->driver->quirks->wmi_backlight_native) acpi_video_set_dmi_backlight_type(acpi_backlight_native); diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index b302415bf1d9..30770e411301 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h @@ -29,7 +29,6 @@ struct quirk_entry { bool hotplug_wireless; bool scalar_panel_brightness; bool store_backlight_power; - bool wmi_backlight_power; bool wmi_backlight_native; bool wmi_backlight_set_devstate; bool wmi_force_als_set; diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index ce86d84ee796..32d9f0ba6be3 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c @@ -96,11 +96,6 @@ static struct quirk_entry quirk_asus_et2012_type3 = { .store_backlight_power = true, }; -static struct quirk_entry quirk_asus_x101ch = { - /* We need this when ACPI function doesn't do this well */ - .wmi_backlight_power = true, -}; - static struct quirk_entry *quirks; static void et2012_quirks(void) @@ -151,25 +146,7 @@ static const struct dmi_system_id asus_quirks[] = { }, .driver_data = &quirk_asus_unknown, }, - { - .callback = dmi_matched, - .ident = "ASUSTeK Computer INC. X101CH", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X101CH"), - }, - .driver_data = &quirk_asus_x101ch, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK Computer INC. 1015CX", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"), - }, - .driver_data = &quirk_asus_x101ch, - }, - {}, + {} }; static void eeepc_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, -- cgit v1.2.3 From 1e3344d6f2b329ca064b3016bc33d7f33ed7ba0e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Jun 2022 17:44:58 +0200 Subject: platform/x86: asus-wmi: Move acpi_backlight=native quirks to ACPI video_detect.c Remove the asus-wmi quirk_entry.wmi_backlight_native quirk-flag, which called acpi_video_set_dmi_backlight_type(acpi_backlight_native) and replace it with acpi/video_detect.c video_detect_dmi_table[] entries using the video_detect_force_native callback. acpi_video_set_dmi_backlight_type() is troublesome because it may end up getting called after other backlight drivers have already called acpi_video_get_backlight_type() resulting in the other drivers already being registered even though they should not. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 8 ++++++++ drivers/platform/x86/asus-nb-wmi.c | 14 -------------- drivers/platform/x86/asus-wmi.c | 3 --- drivers/platform/x86/asus-wmi.h | 1 - 4 files changed, 8 insertions(+), 18 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index d893313fe1a0..a09089e7fada 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -564,6 +564,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), }, }, + { + .callback = video_detect_force_native, + /* Asus UX303UB */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"), + }, + }, /* * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a * working native and video interface. However the default detection diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 810a94557a85..bbfed85051ee 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -97,11 +97,6 @@ static struct quirk_entry quirk_asus_x200ca = { .wmi_backlight_set_devstate = true, }; -static struct quirk_entry quirk_asus_ux303ub = { - .wmi_backlight_native = true, - .wmi_backlight_set_devstate = true, -}; - static struct quirk_entry quirk_asus_x550lb = { .wmi_backlight_set_devstate = true, .xusb2pr = 0x01D9, @@ -372,15 +367,6 @@ static const struct dmi_system_id asus_quirks[] = { }, .driver_data = &quirk_asus_x200ca, }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. UX303UB", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"), - }, - .driver_data = &quirk_asus_ux303ub, - }, { .callback = dmi_matched, .ident = "ASUSTeK COMPUTER INC. UX330UAK", diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 5cf9d9aff164..434249ac47a5 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -3634,9 +3634,6 @@ static int asus_wmi_add(struct platform_device *pdev) if (asus->driver->quirks->wmi_force_als_set) asus_wmi_set_als(); - if (asus->driver->quirks->wmi_backlight_native) - acpi_video_set_dmi_backlight_type(acpi_backlight_native); - if (asus->driver->quirks->xusb2pr) asus_wmi_set_xusb2pr(asus); diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index 30770e411301..f30252efe1db 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h @@ -29,7 +29,6 @@ struct quirk_entry { bool hotplug_wireless; bool scalar_panel_brightness; bool store_backlight_power; - bool wmi_backlight_native; bool wmi_backlight_set_devstate; bool wmi_force_als_set; bool use_kbd_dock_devid; -- cgit v1.2.3 From 8991d7d9add0d9a711db692458d950050b38307b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Jun 2022 19:01:05 +0200 Subject: platform/x86: samsung-laptop: Move acpi_backlight=[vendor|native] quirks to ACPI video_detect.c acpi_video_set_dmi_backlight_type() is troublesome because it may end up getting called after other backlight drivers have already called acpi_video_get_backlight_type() resulting in the other drivers already being registered even though they should not. Move all the acpi_backlight=[vendor|native] quirks from samsung-laptop to drivers/acpi/video_detect.c . Note the X360 -> acpi_backlight=native quirk is not moved because that already was present in drivers/acpi/video_detect.c . Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 54 ++++++++++++++++++++++ drivers/platform/x86/samsung-laptop.c | 87 ----------------------------------- 2 files changed, 54 insertions(+), 87 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index a09089e7fada..3861d4121172 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -222,6 +222,33 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), }, }, + { + .callback = video_detect_force_vendor, + /* Samsung N150/N210/N220 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), + DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), + }, + }, + { + .callback = video_detect_force_vendor, + /* Samsung NF110/NF210/NF310 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"), + DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"), + }, + }, + { + .callback = video_detect_force_vendor, + /* Samsung NC210 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "NC210/NC110"), + DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"), + }, + }, { .callback = video_detect_force_vendor, /* Sony VPCEH3U1E */ @@ -572,6 +599,33 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"), }, }, + { + .callback = video_detect_force_native, + /* Samsung N150P */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N150P"), + DMI_MATCH(DMI_BOARD_NAME, "N150P"), + }, + }, + { + .callback = video_detect_force_native, + /* Samsung N145P/N250P/N260P */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), + DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), + }, + }, + { + .callback = video_detect_force_native, + /* Samsung N250P */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), + DMI_MATCH(DMI_BOARD_NAME, "N250P"), + }, + }, /* * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a * working native and video interface. However the default detection diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index c187dcdf82f0..cc30cf08f32d 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -356,23 +356,13 @@ struct samsung_laptop { }; struct samsung_quirks { - bool broken_acpi_video; bool four_kbd_backlight_levels; bool enable_kbd_backlight; - bool use_native_backlight; bool lid_handling; }; static struct samsung_quirks samsung_unknown = {}; -static struct samsung_quirks samsung_broken_acpi_video = { - .broken_acpi_video = true, -}; - -static struct samsung_quirks samsung_use_native_backlight = { - .use_native_backlight = true, -}; - static struct samsung_quirks samsung_np740u3e = { .four_kbd_backlight_levels = true, .enable_kbd_backlight = true, @@ -1540,76 +1530,6 @@ static const struct dmi_system_id samsung_dmi_table[] __initconst = { }, }, /* Specific DMI ids for laptop with quirks */ - { - .callback = samsung_dmi_matched, - .ident = "N150P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150P"), - DMI_MATCH(DMI_BOARD_NAME, "N150P"), - }, - .driver_data = &samsung_use_native_backlight, - }, - { - .callback = samsung_dmi_matched, - .ident = "N145P/N250P/N260P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), - DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), - }, - .driver_data = &samsung_use_native_backlight, - }, - { - .callback = samsung_dmi_matched, - .ident = "N150/N210/N220", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), - DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), - }, - .driver_data = &samsung_broken_acpi_video, - }, - { - .callback = samsung_dmi_matched, - .ident = "NF110/NF210/NF310", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"), - DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"), - }, - .driver_data = &samsung_broken_acpi_video, - }, - { - .callback = samsung_dmi_matched, - .ident = "X360", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "X360"), - DMI_MATCH(DMI_BOARD_NAME, "X360"), - }, - .driver_data = &samsung_broken_acpi_video, - }, - { - .callback = samsung_dmi_matched, - .ident = "N250P", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), - DMI_MATCH(DMI_BOARD_NAME, "N250P"), - }, - .driver_data = &samsung_use_native_backlight, - }, - { - .callback = samsung_dmi_matched, - .ident = "NC210", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "NC210/NC110"), - DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"), - }, - .driver_data = &samsung_broken_acpi_video, - }, { .callback = samsung_dmi_matched, .ident = "730U3E/740U3E", @@ -1654,15 +1574,8 @@ static int __init samsung_init(void) samsung->handle_backlight = true; samsung->quirks = quirks; -#ifdef CONFIG_ACPI - if (samsung->quirks->broken_acpi_video) - acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); - if (samsung->quirks->use_native_backlight) - acpi_video_set_dmi_backlight_type(acpi_backlight_native); - if (acpi_video_get_backlight_type() != acpi_backlight_vendor) samsung->handle_backlight = false; -#endif ret = samsung_platform_init(samsung); if (ret) -- cgit v1.2.3 From 77ab9d4d44cd235322d2f30b1c4026302c3ce8c6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 20 Jun 2022 11:49:57 +0200 Subject: ACPI: video: Remove acpi_video_set_dmi_backlight_type() acpi_video_set_dmi_backlight_type() is troublesome because it may end up getting called after other backlight drivers have already called acpi_video_get_backlight_type() resulting in the other drivers already being registered even though they should not. In case of the acpi_video backlight, acpi_video_set_dmi_backlight_type() actually calls acpi_video_unregister_backlight() since that is often probed earlier, leading to userspace seeing the acpi_video0 class device being briefly available, leading to races in userspace where udev probe-rules try to access the device and it is already gone. All callers have been fixed to no longer call it, so remove acpi_video_set_dmi_backlight_type() now. This means we now also no longer need acpi_video_unregister_backlight() for the remove acpi_video backlight after it was wrongly registered hack, so remove that too. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/acpi_video.c | 10 ---------- drivers/acpi/video_detect.c | 16 ---------------- include/acpi/video.h | 4 ---- 3 files changed, 30 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index d1e41f30c004..a7c3d11e0dac 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2296,16 +2296,6 @@ void acpi_video_register_backlight(void) } EXPORT_SYMBOL(acpi_video_register_backlight); -void acpi_video_unregister_backlight(void) -{ - struct acpi_video_bus *video; - - mutex_lock(&video_list_lock); - list_for_each_entry(video, &video_bus_head, entry) - acpi_video_bus_unregister_backlight(video); - mutex_unlock(&video_list_lock); -} - bool acpi_video_handles_brightness_key_presses(void) { return may_report_brightness_keys && diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 3861d4121172..67a0211c07b4 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -38,8 +38,6 @@ #include #include -void acpi_video_unregister_backlight(void); - static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef; static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef; @@ -817,17 +815,3 @@ 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 - * platform drivers instead of putting a big blacklist in video_detect.c - */ -void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type) -{ - acpi_backlight_dmi = type; - /* Remove acpi-video backlight interface if it is no longer desired */ - if (acpi_video_get_backlight_type() != acpi_backlight_video) - acpi_video_unregister_backlight(); -} -EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type); diff --git a/include/acpi/video.h b/include/acpi/video.h index dbd48cb8bd23..a275c35e5249 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -60,7 +60,6 @@ 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() * may change over time and should not be cached. @@ -86,9 +85,6 @@ 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) -{ -} static inline bool acpi_video_handles_brightness_key_presses(void) { return false; -- cgit v1.2.3 From de6f3121dc6b2226b85a91b1fe2ac2d08a8b5248 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Jun 2022 19:06:51 +0200 Subject: ACPI: video: Drop "Samsung X360" acpi_backlight=native quirk acpi_backlight=native is the default for the "Samsung X360", but as the comment explains the quirk was still necessary because even briefly registering the acpi_video0 backlight; and then unregistering it once the native driver showed up, was leading to issues. After the "ACPI: video: Make backlight class device registration a separate step" patch from earlier in this patch-series, we no longer briefly register the acpi_video0 backlight on systems where the native driver should be used. So this is no longer an issue an the quirk is no longer needed. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 67a0211c07b4..af2833b57b8b 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -132,21 +132,6 @@ static int video_detect_force_none(const struct dmi_system_id *d) } static const struct dmi_system_id video_detect_dmi_table[] = { - /* On Samsung X360, the BIOS will set a flag (VDRV) if generic - * ACPI backlight device is used. This flag will definitively break - * the backlight interface (even the vendor interface) until next - * reboot. It's why we should prevent video.ko from being used here - * and we can't rely on a later call to acpi_video_unregister(). - */ - { - .callback = video_detect_force_vendor, - /* X360 */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "X360"), - DMI_MATCH(DMI_BOARD_NAME, "X360"), - }, - }, { /* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */ .callback = video_detect_force_vendor, -- cgit v1.2.3 From 10212754a0d2c4b4ae951c04f154a82dd2a1f9c4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Jun 2022 19:15:22 +0200 Subject: ACPI: video: Drop NL5x?U, PF4NU1F and PF5?U?? acpi_backlight=native quirks acpi_backlight=native is the default for these, but as the comment explains the quirk was still necessary because even briefly registering the acpi_video0 backlight; and then unregistering it once the native driver showed up, was leading to issues. After the "ACPI: video: Make backlight class device registration a separate step" patch from earlier in this patch-series, we no longer briefly register the acpi_video0 backlight on systems where the native driver should be used. So this is no longer an issue an the quirks are no longer needed. Link: https://bugzilla.kernel.org/show_bug.cgi?id=215683 Tested-by: Werner Sembach Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 92 +-------------------------------------------- 1 file changed, 1 insertion(+), 91 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index af2833b57b8b..789d5913c178 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -609,97 +609,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "N250P"), }, }, - /* - * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a - * working native and video interface. However the default detection - * mechanism first registers the video interface before unregistering - * it again and switching to the native interface during boot. This - * results in a dangling SBIOS request for backlight change for some - * reason, causing the backlight to switch to ~2% once per boot on the - * first power cord connect or disconnect event. Setting the native - * interface explicitly circumvents this buggy behaviour, by avoiding - * the unregistering process. - */ - { - .callback = video_detect_force_native, - .ident = "Clevo NL5xRU", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "Clevo NL5xRU", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), - DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "Clevo NL5xRU", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), - DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "Clevo NL5xNU", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), - }, - }, - /* - * The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10, - * Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo - * NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description - * above. - */ - { - .callback = video_detect_force_native, - .ident = "TongFang PF5PU1G", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "TongFang PF4NU1F", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "TongFang PF4NU1F", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), - DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "TongFang PF5NU1G", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "TongFang PF5NU1G", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), - DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"), - }, - }, - { - .callback = video_detect_force_native, - .ident = "TongFang PF5LUXG", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"), - }, - }, + /* * Desktops which falsely report a backlight and which our heuristics * for this do not catch. -- cgit v1.2.3 From c2d6920e9877c8298502ec6163a93ab0db1dd761 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 18 Jun 2022 19:19:51 +0200 Subject: ACPI: video: Fix indentation of video_detect_dmi_table[] entries The video_detect_dmi_table[] uses an unusual indentation for before the ".name = ..." named struct initializers. Instead of being indented with an extra tab compared to the previous line's '{' these are indented to with only a single space to allow for long DMI_MATCH() lines without wrapping. But over time some entries did not event have the single space indent in front of the ".name = ..." lines. Make things consistent by using a single space indent for these lines everywhere. Acked-by: Rafael J. Wysocki Signed-off-by: Hans de Goede --- drivers/acpi/video_detect.c | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 789d5913c178..db2474fe58ac 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -142,17 +142,17 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, { - .callback = video_detect_force_vendor, - /* Asus UL30VT */ - .matches = { + .callback = video_detect_force_vendor, + /* Asus UL30VT */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), }, }, { - .callback = video_detect_force_vendor, - /* Asus UL30A */ - .matches = { + .callback = video_detect_force_vendor, + /* Asus UL30A */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), }, @@ -198,9 +198,9 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, { - .callback = video_detect_force_vendor, - /* GIGABYTE GB-BXBT-2807 */ - .matches = { + .callback = video_detect_force_vendor, + /* GIGABYTE GB-BXBT-2807 */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), }, @@ -233,17 +233,17 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, { - .callback = video_detect_force_vendor, - /* Sony VPCEH3U1E */ - .matches = { + .callback = video_detect_force_vendor, + /* Sony VPCEH3U1E */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"), }, }, { - .callback = video_detect_force_vendor, - /* Xiaomi Mi Pad 2 */ - .matches = { + .callback = video_detect_force_vendor, + /* Xiaomi Mi Pad 2 */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), }, @@ -551,25 +551,25 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, { - .callback = video_detect_force_native, - /* ASUSTeK COMPUTER INC. GA401 */ - .matches = { + .callback = video_detect_force_native, + /* ASUSTeK COMPUTER INC. GA401 */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA401"), }, }, { - .callback = video_detect_force_native, - /* ASUSTeK COMPUTER INC. GA502 */ - .matches = { + .callback = video_detect_force_native, + /* ASUSTeK COMPUTER INC. GA502 */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA502"), }, }, { - .callback = video_detect_force_native, - /* ASUSTeK COMPUTER INC. GA503 */ - .matches = { + .callback = video_detect_force_native, + /* ASUSTeK COMPUTER INC. GA503 */ + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), }, -- cgit v1.2.3 From 811d59fdf56a17c66742578fe8be8a6a841af448 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 29 Aug 2022 11:29:49 -0500 Subject: ACPI: s2idle: Add a new ->check() callback for platform_s2idle_ops On some platforms it is found that Linux more aggressively enters s2idle than Windows enters Modern Standby and this uncovers some synchronization issues for the platform. To aid in debugging this class of problems in the future, add support for an extra optional callback intended for drivers to emit extra debugging. Signed-off-by: Mario Limonciello Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20220829162953.5947-2-mario.limonciello@amd.com Signed-off-by: Hans de Goede --- drivers/acpi/sleep.h | 1 + drivers/acpi/x86/s2idle.c | 14 ++++++++++++++ include/linux/acpi.h | 1 + include/linux/suspend.h | 1 + kernel/power/suspend.c | 3 +++ 5 files changed, 20 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 7fe41ee489d6..d960a238be4e 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h @@ -18,6 +18,7 @@ static inline acpi_status acpi_set_waking_vector(u32 wakeup_address) extern int acpi_s2idle_begin(void); extern int acpi_s2idle_prepare(void); extern int acpi_s2idle_prepare_late(void); +extern void acpi_s2idle_check(void); extern bool acpi_s2idle_wake(void); extern void acpi_s2idle_restore_early(void); extern void acpi_s2idle_restore(void); diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index f9ac12b778e6..474aa46f82f6 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -486,6 +486,19 @@ int acpi_s2idle_prepare_late(void) return 0; } +void acpi_s2idle_check(void) +{ + struct acpi_s2idle_dev_ops *handler; + + if (!lps0_device_handle || sleep_no_lps0) + return; + + list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) { + if (handler->check) + handler->check(); + } +} + void acpi_s2idle_restore_early(void) { struct acpi_s2idle_dev_ops *handler; @@ -527,6 +540,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { .begin = acpi_s2idle_begin, .prepare = acpi_s2idle_prepare, .prepare_late = acpi_s2idle_prepare_late, + .check = acpi_s2idle_check, .wake = acpi_s2idle_wake, .restore_early = acpi_s2idle_restore_early, .restore = acpi_s2idle_restore, diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6f64b2f3dc54..acaa2ddc067d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1075,6 +1075,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, struct acpi_s2idle_dev_ops { struct list_head list_node; void (*prepare)(void); + void (*check)(void); void (*restore)(void); }; int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 70f2921e2e70..03ed42ed2c7f 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -191,6 +191,7 @@ struct platform_s2idle_ops { int (*begin)(void); int (*prepare)(void); int (*prepare_late)(void); + void (*check)(void); bool (*wake)(void); void (*restore_early)(void); void (*restore)(void); diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 827075944d28..c6272d466e58 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -136,6 +136,9 @@ static void s2idle_loop(void) break; } + if (s2idle_ops && s2idle_ops->check) + s2idle_ops->check(); + s2idle_enter(); } -- cgit v1.2.3 From c5b94f5b7819348c59f9949b2b75c341a114cdd4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 29 Aug 2022 15:39:23 +0200 Subject: ACPI: video: Change disable_backlight_sysfs_if quirks to acpi_backlight=native Some Toshibas have a broken acpi-video interface for brightness control and need a special firmware call on resume to turn the panel back on. So far these have been using the disable_backlight_sysfs_if workaround to deal with this. The recent x86/acpi backlight refactoring has broken this workaround: 1. This workaround relies on acpi_video_get_backlight_type() returning acpi_video so that the acpi_video code actually runs; and 2. this relies on the actual native GPU driver to offer the sysfs backlight interface to userspace. After the refactor this breaks since the native driver will no longer register its backlight-device if acpi_video_get_backlight_type() does not return native and making it return native breaks 1. Keeping the acpi_video backlight handling on resume active, while not using it to set the brightness, is necessary because it does a _BCM call on resume which is necessary to turn the panel back on on resume. Looking at the DSDT shows that this _BCM call results in a Toshiba HCI_SET HCI_LCD_BRIGHTNESS call, which turns the panel back on. This kind of special vendor specific handling really belongs in the vendor specific acpi driver. An earlier patch in this series modifies toshiba_acpi to make the necessary HCI_SET call on resume on affected models. With toshiba_acpi taking care of the HCI_SET call on resume, the acpi_video code no longer needs to call _BCM on resume. So instead of using the (now broken) disable_backlight_sysfs_if workaround, simply setting acpi_backlight=native to disable the broken apci-video interface is sufficient fix things now. After this there are no more users of the disable_backlight_sysfs_if flag and as discussed above the flag also no longer works as intended, so remove the disable_backlight_sysfs_if flag entirely. Acked-by: Rafael J. Wysocki Tested-by: Arvid Norlander Signed-off-by: Hans de Goede --- drivers/acpi/acpi_video.c | 48 --------------------------------------------- drivers/acpi/video_detect.c | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 48 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index a7c3d11e0dac..99894fbcf4e3 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -47,9 +47,6 @@ module_param(brightness_switch_enabled, bool, 0644); static bool allow_duplicates; module_param(allow_duplicates, bool, 0644); -static int disable_backlight_sysfs_if = -1; -module_param(disable_backlight_sysfs_if, int, 0444); - #define REPORT_OUTPUT_KEY_EVENTS 0x01 #define REPORT_BRIGHTNESS_KEY_EVENTS 0x02 static int report_key_events = -1; @@ -394,14 +391,6 @@ static int video_set_bqc_offset(const struct dmi_system_id *d) return 0; } -static int video_disable_backlight_sysfs_if( - const struct dmi_system_id *d) -{ - if (disable_backlight_sysfs_if == -1) - disable_backlight_sysfs_if = 1; - return 0; -} - static int video_set_device_id_scheme(const struct dmi_system_id *d) { device_id_scheme = true; @@ -474,40 +463,6 @@ static const struct dmi_system_id video_dmi_table[] = { }, }, - /* - * Some machines have a broken acpi-video interface for brightness - * control, but still need an acpi_video_device_lcd_set_level() call - * on resume to turn the backlight power on. We Enable backlight - * control on these systems, but do not register a backlight sysfs - * as brightness control does not work. - */ - { - /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ - .callback = video_disable_backlight_sysfs_if, - .ident = "Toshiba Portege R700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"), - }, - }, - { - /* https://bugs.freedesktop.org/show_bug.cgi?id=82634 */ - .callback = video_disable_backlight_sysfs_if, - .ident = "Toshiba Portege R830", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"), - }, - }, - { - /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ - .callback = video_disable_backlight_sysfs_if, - .ident = "Toshiba Satellite R830", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), - }, - }, /* * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set * but the IDs actually follow the Device ID Scheme. @@ -1770,9 +1725,6 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) if (result) return; - if (disable_backlight_sysfs_if > 0) - return; - name = kasprintf(GFP_KERNEL, "acpi_video%d", count); if (!name) return; diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index db2474fe58ac..0d9064a9804c 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -610,6 +610,41 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, }, + /* + * These Toshibas have a broken acpi-video interface for brightness + * control. They also have an issue where the panel is off after + * suspend until a special firmware call is made to turn it back + * on. This is handled by the toshiba_acpi kernel module, so that + * module must be enabled for these models to work correctly. + */ + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ + .callback = video_detect_force_native, + /* Toshiba Portégé R700 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"), + }, + }, + { + /* Portégé: https://bugs.freedesktop.org/show_bug.cgi?id=82634 */ + /* Satellite: https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ + .callback = video_detect_force_native, + /* Toshiba Satellite/Portégé R830 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "R830"), + }, + }, + { + .callback = video_detect_force_native, + /* Toshiba Satellite/Portégé Z830 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Z830"), + }, + }, + /* * Desktops which falsely report a backlight and which our heuristics * for this do not catch. -- cgit v1.2.3