From 8a02d99876362f35bc918097440445de18e3c47c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 16 Mar 2021 16:54:03 +0100 Subject: ACPI: CPPC: Add emtpy stubs of functions for CONFIG_ACPI_CPPC_LIB unset For convenience, add empty stubs of library functions defined in cppc_acpi.c for the CONFIG_ACPI_CPPC_LIB unset case. Because one of them needs to return CPUFREQ_ETERNAL, include linux/cpufreq.h into the CPPC library header file and drop the direct inclusion of it from cppc_acpi.c. Signed-off-by: Rafael J. Wysocki Tested-by: Chen Yu --- drivers/acpi/cppc_acpi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 69057fcd2c04..d20092815c39 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -33,7 +33,6 @@ #define pr_fmt(fmt) "ACPI CPPC: " fmt -#include #include #include #include -- cgit v1.2.3 From 8eb99e9a64a07ea08070591bdc2615526a103e62 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 7 Apr 2021 19:58:20 +0200 Subject: ACPI: utils: Add acpi_reduced_hardware() helper Add a getter for the acpi_gbl_reduced_hardware variable so that modules can check if they are running on an ACPI reduced-hw platform or not. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/utils.c | 11 +++++++++++ include/acpi/acpi_bus.h | 1 + include/linux/acpi.h | 5 +++++ 3 files changed, 17 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 682edd913b3b..b20774c48c74 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -872,6 +872,17 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) } EXPORT_SYMBOL(acpi_dev_get_first_match_dev); +/** + * acpi_reduced_hardware - Return if this is an ACPI-reduced-hw machine + * + * Return true when running on an ACPI-reduced-hw machine, false otherwise. + */ +bool acpi_reduced_hardware(void) +{ + return acpi_gbl_reduced_hardware; +} +EXPORT_SYMBOL_GPL(acpi_reduced_hardware); + /* * acpi_backlight= handling, this is done here rather then in video_detect.c * because __setup cannot be used in modules. diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f28b097c658f..d631cb52283e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -78,6 +78,7 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev, bool acpi_dev_found(const char *hid); bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); +bool acpi_reduced_hardware(void); #ifdef CONFIG_ACPI diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3bdcfc4401b7..e2e6db8313c8 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -748,6 +748,11 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) return NULL; } +static inline bool acpi_reduced_hardware(void) +{ + return false; +} + static inline void acpi_dev_put(struct acpi_device *adev) {} static inline bool is_acpi_node(const struct fwnode_handle *fwnode) -- cgit v1.2.3 From 81cc7e9947c0d54ba2b714899ca90f14f029cb0b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 6 Apr 2021 23:16:53 +0200 Subject: ACPI: video: Check LCD flag on ACPI-reduced-hardware devices Starting with Windows 8, Windows no longer uses the ACPI-video interface for backlight control by default. Instead backlight control is left up to the GPU drivers and these are typically directly accessing the GPU for this instead of going through ACPI. This means that the ACPI video interface is no longer being tested by many vendors, which leads to false-positive /sys/class/backlight entries on devices which don't have a backlight at all such as desktops or top-set boxes. These false-positives causes desktop environments to show a non functional brightness slider in various places. Checking the LCD flag greatly reduces the amount of false-positives, so commit 5928c281524f ("ACPI / video: Default lcd_only to true on Win8-ready and newer machines") enabled the checking of this flag by default on all win8 BIOS-es. But this let to regressions on some models, so the check was made stricter adding a DMI chassis-type check to only enable the LCD flag checking on desktop/server chassis. Unfortunately the chassis-type reported in the DMI strings is not always reliable. One class of devices where this is a problem is Intel Bay Trail-T based top-set boxes / mini PCs / HDMI sticks. These are based on reference designs which were targetets and the reference design BIOS code is often used without changing the chassis-type to something more appropriate. There are many, many Bay Trail-T based devices affected by this, so DMI quirking our way out of this is a bad idea. This patch takes a different approach, Bay Trail-T (unlike regular Bay Trail) is an ACPI-reduced-hw platform and ACPI-reduced-hw platforms generally don't have an embedded-controller and thus will use a native (GPU specific) backlight interface. This patch enables Checking the LCD flag by default on ACPI-reduced-hw platforms with a win8 BIOS independent of the reported chassis-type, fixing the false positive /sys/class/backlight entries on these devices. Note in hindsight I should have never added the DMI chassis-type check when the enabling of LCD flag checking on Windows 8 BIOS-es let to some regressions. Instead I should have added DMI quirks for the (presumably few) models where the LCD flag check let to issues. But I'm afraid that it is too late to change this now, changing this now will likely lead to a bunch of regressions. This patch was tested on a Mele PCG03 mini PC. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_video.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 2ea1781290cc..ade02152bb06 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2182,6 +2182,30 @@ static bool dmi_is_desktop(void) return false; } +/* + * We're seeing a lot of bogus backlight interfaces on newer machines + * without a LCD such as desktops, servers and HDMI sticks. Checking the + * lcd flag fixes this, enable this by default on any machines which are: + * 1. Win8 ready (where we also prefer the native backlight driver, so + * normally the acpi_video code should not register there anyways); *and* + * 2.1 Report a desktop/server DMI chassis-type, or + * 2.2 Are an ACPI-reduced-hardware platform (and thus won't use the EC for + backlight control) + */ +static bool should_check_lcd_flag(void) +{ + if (!acpi_osi_is_win8()) + return false; + + if (dmi_is_desktop()) + return true; + + if (acpi_reduced_hardware()) + return true; + + return false; +} + int acpi_video_register(void) { int ret = 0; @@ -2195,19 +2219,8 @@ int acpi_video_register(void) goto leave; } - /* - * We're seeing a lot of bogus backlight interfaces on newer machines - * without a LCD such as desktops, servers and HDMI sticks. Checking - * the lcd flag fixes this, so enable this on any machines which are - * win8 ready (where we also prefer the native backlight driver, so - * normally the acpi_video code should not register there anyways). - */ - if (only_lcd == -1) { - if (dmi_is_desktop() && acpi_osi_is_win8()) - only_lcd = true; - else - only_lcd = false; - } + if (only_lcd == -1) + only_lcd = should_check_lcd_flag(); dmi_check_system(video_dmi_table); -- cgit v1.2.3 From 2bc6262c6117dd18106d5aa50d53e945b5d99c51 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 7 Apr 2021 14:30:48 -0700 Subject: ACPI: CPPC: Replace cppc_attr with kobj_attribute All of the CPPC sysfs show functions are called via indirect call in kobj_attr_show(), where they should be of type ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf); because that is the type of the ->show() member in 'struct kobj_attribute' but they are actually of type ssize_t (*show)(struct kobject *kobj, struct attribute *attr, char *buf); because of the ->show() member in 'struct cppc_attr', resulting in a Control Flow Integrity violation [1]. $ cat /sys/devices/system/cpu/cpu0/acpi_cppc/highest_perf 3400 $ dmesg | grep "CFI failure" [ 175.970559] CFI failure (target: show_highest_perf+0x0/0x8): As far as I can tell, the only difference between 'struct cppc_attr' and 'struct kobj_attribute' aside from the type of the attr parameter is the type of the count parameter in the ->store() member (ssize_t vs. size_t), which does not actually matter because all of these nodes are read-only. Eliminate 'struct cppc_attr' in favor of 'struct kobj_attribute' to fix the violation. [1]: https://lore.kernel.org/r/20210401233216.2540591-1-samitolvanen@google.com/ Fixes: 158c998ea44b ("ACPI / CPPC: add sysfs support to compute delivered performance") Link: https://github.com/ClangBuiltLinux/linux/issues/1343 Signed-off-by: Nathan Chancellor Signed-off-by: Rafael J. Wysocki --- drivers/acpi/cppc_acpi.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index d20092815c39..2c2748041cef 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -118,23 +118,15 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); */ #define NUM_RETRIES 500ULL -struct cppc_attr { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, - struct attribute *attr, char *buf); - ssize_t (*store)(struct kobject *kobj, - struct attribute *attr, const char *c, ssize_t count); -}; - #define define_one_cppc_ro(_name) \ -static struct cppc_attr _name = \ +static struct kobj_attribute _name = \ __ATTR(_name, 0444, show_##_name, NULL) #define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj) #define show_cppc_data(access_fn, struct_name, member_name) \ static ssize_t show_##member_name(struct kobject *kobj, \ - struct attribute *attr, char *buf) \ + struct kobj_attribute *attr, char *buf) \ { \ struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); \ struct struct_name st_name = {0}; \ @@ -160,7 +152,7 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); static ssize_t show_feedback_ctrs(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); struct cppc_perf_fb_ctrs fb_ctrs = {0}; -- cgit v1.2.3 From 81eeb2f57782d0dff15db97665599121e289b614 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 13 Apr 2021 02:20:51 +0300 Subject: ACPI: utils: Document for_each_acpi_dev_match() macro The macro requires to call acpi_dev_put() on each iteration. Due to this it doesn't tolerate sudden disappearence of the devices. Document all these nuances to prevent users blindly call it without understanding the possible issues. While at it, add the note to the acpi_dev_get_next_match_dev() and advertise acpi_dev_put() instead of put_device() in the whole family of the helper functions. Fixes: bf263f64e804 ("media: ACPI / bus: Add acpi_dev_get_next_match_dev() and helper macro") Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/utils.c | 8 ++++++-- include/acpi/acpi_bus.h | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 682edd913b3b..35c3b52fb6ad 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -832,7 +832,11 @@ EXPORT_SYMBOL(acpi_dev_present); * Return the next match of ACPI device if another matching device was present * at the moment of invocation, or NULL otherwise. * - * The caller is responsible to call put_device() on the returned device. + * FIXME: The function does not tolerate the sudden disappearance of @adev, e.g. + * in the case of a hotplug event. That said, the caller should ensure that + * this will never happen. + * + * The caller is responsible for invoking acpi_dev_put() on the returned device. * * See additional information in acpi_dev_present() as well. */ @@ -861,7 +865,7 @@ EXPORT_SYMBOL(acpi_dev_get_next_match_dev); * Return the first match of ACPI device if a matching device was present * at the moment of invocation, or NULL otherwise. * - * The caller is responsible to call put_device() on the returned device. + * The caller is responsible for invoking acpi_dev_put() on the returned device. * * See additional information in acpi_dev_present() as well. */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f28b097c658f..61937d243374 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -689,6 +689,20 @@ acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const cha struct acpi_device * acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); +/** + * for_each_acpi_dev_match - iterate over ACPI devices that matching the criteria + * @adev: pointer to the matching ACPI device, NULL at the end of the loop + * @hid: Hardware ID of the device. + * @uid: Unique ID of the device, pass NULL to not check _UID + * @hrv: Hardware Revision of the device, pass -1 to not check _HRV + * + * The caller is responsible for invoking acpi_dev_put() on the returned device. + * + * FIXME: Due to above requirement there is a window that may invalidate @adev + * and next iteration will use a dangling pointer, e.g. in the case of a + * hotplug event. That said, the caller should ensure that this will never + * happen. + */ #define for_each_acpi_dev_match(adev, hid, uid, hrv) \ for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \ adev; \ -- cgit v1.2.3 From e7b07d3e00dc8547be43467a63c4d1e7823b640c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 13 Apr 2021 02:20:52 +0300 Subject: ACPI: utils: Capitalize abbreviations in the comments The DSDT and ACPI should be capitalized. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 35c3b52fb6ad..b458b2d50ba6 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -797,7 +797,7 @@ static int acpi_dev_match_cb(struct device *dev, const void *data) * Note that if the device is pluggable, it may since have disappeared. * * Note that unlike acpi_dev_found() this function checks the status - * of the device. So for devices which are present in the dsdt, but + * of the device. So for devices which are present in the DSDT, but * which are disabled (their _STA callback returns 0) this function * will return false. * @@ -824,7 +824,7 @@ EXPORT_SYMBOL(acpi_dev_present); /** * acpi_dev_get_next_match_dev - Return the next match of ACPI device - * @adev: Pointer to the previous acpi_device matching this @hid, @uid and @hrv + * @adev: Pointer to the previous ACPI device matching this @hid, @uid and @hrv * @hid: Hardware ID of the device. * @uid: Unique ID of the device, pass NULL to not check _UID * @hrv: Hardware Revision of the device, pass -1 to not check _HRV -- cgit v1.2.3 From 2dfbacc65d1d2eae587ccb6b93f6280542641858 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Mon, 19 Apr 2021 19:39:17 +1200 Subject: ACPI: video: use native backlight for GA401/GA502/GA503 Force backlight control in these models to use the native interface at /sys/class/backlight/amdgpu_bl0. Signed-off-by: Luke D. Jones Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 83cd4c95faf0..33474fd96991 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -385,6 +385,30 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"), }, }, + { + .callback = video_detect_force_native, + .ident = "ASUSTeK COMPUTER INC. GA401", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "ASUSTeK COMPUTER INC. GA502", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA502"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "ASUSTeK COMPUTER INC. GA503", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), + }, + }, /* * Desktops which falsely report a backlight and which our heuristics -- cgit v1.2.3