From 8b62740472c4fe3cee64df4588033e1d8ff3b235 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Sat, 12 Sep 2020 11:38:51 +0800 Subject: ACPI, APEI: make apei_resources_all static This eliminates the following sparse warning: drivers/acpi/apei/apei-base.c:290:23: warning: symbol 'apei_resources_all' was not declared. Should it be static? Reported-by: Hulk Robot Signed-off-by: Jason Yan Reviewed-by: Borislav Petkov Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/apei-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index e358d0046494..d3fbac58d91a 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -287,7 +287,7 @@ struct apei_res { }; /* Collect all resources requested, to avoid conflict */ -struct apei_resources apei_resources_all = { +static struct apei_resources apei_resources_all = { .iomem = LIST_HEAD_INIT(apei_resources_all.iomem), .ioport = LIST_HEAD_INIT(apei_resources_all.ioport), }; -- cgit v1.2.3 From 4697958b056b112063e968857cefa7173ad5c732 Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Thu, 12 Nov 2020 14:15:45 +0100 Subject: Documentation: ACPI: explain how to use gpio-line-names The "gpio-line-names" declaration is not fully documented, so can be useful to add some important information and one more example. Signed-off-by: Flavio Suligoi Reviewed-by: Andy Shevchenko Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- .../firmware-guide/acpi/gpio-properties.rst | 56 +++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/Documentation/firmware-guide/acpi/gpio-properties.rst b/Documentation/firmware-guide/acpi/gpio-properties.rst index 59aad6138b6e..b36aa3e743d8 100644 --- a/Documentation/firmware-guide/acpi/gpio-properties.rst +++ b/Documentation/firmware-guide/acpi/gpio-properties.rst @@ -133,7 +133,61 @@ Example:: - gpio-line-names -Example:: +The ``gpio-line-names`` declaration is a list of strings ("names"), which +describes each line/pin of a GPIO controller/expander. This list, contained in +a package, must be inserted inside the GPIO controller declaration of an ACPI +table (typically inside the DSDT). The ``gpio-line-names`` list must respect the +following rules (see also the examples): + + - the first name in the list corresponds with the first line/pin of the GPIO + controller/expander + - the names inside the list must be consecutive (no "holes" are permitted) + - the list can be incomplete and can end before the last GPIO line: in + other words, it is not mandatory to fill all the GPIO lines + - empty names are allowed (two quotation marks ``""`` correspond to an empty + name) + +Example of a GPIO controller of 16 lines, with an incomplete list with two +empty names:: + + Package () { + "gpio-line-names", + Package () { + "pin_0", + "pin_1", + "", + "", + "pin_3", + "pin_4_push_button", + } + } + +At runtime, the above declaration produces the following result (using the +"libgpiod" tools):: + + root@debian:~# gpioinfo gpiochip4 + gpiochip4 - 16 lines: + line 0: "pin_0" unused input active-high + line 1: "pin_1" unused input active-high + line 2: unnamed unused input active-high + line 3: unnamed unused input active-high + line 4: "pin_3" unused input active-high + line 5: "pin_4_push_button" unused input active-high + line 6: unnamed unused input active-high + line 7 unnamed unused input active-high + line 8: unnamed unused input active-high + line 9: unnamed unused input active-high + line 10: unnamed unused input active-high + line 11: unnamed unused input active-high + line 12: unnamed unused input active-high + line 13: unnamed unused input active-high + line 14: unnamed unused input active-high + line 15: unnamed unused input active-high + root@debian:~# gpiofind pin_4_push_button + gpiochip4 5 + root@debian:~# + +Another example:: Package () { "gpio-line-names", -- cgit v1.2.3 From 66f4fa32eb18af9a60bbda589ee239621a49bcc1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:04 +0200 Subject: resource: Simplify region_intersects() by reducing conditionals Now we have for 'other' and 'type' variables other type return 0 0 REGION_DISJOINT 0 x REGION_INTERSECTS x 0 REGION_DISJOINT x x REGION_MIXED Obviously it's easier to check 'type' for 0 first instead of currently checked 'other'. Signed-off-by: Andy Shevchenko Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- kernel/resource.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index 3ae2f56cc79d..82df80417489 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -557,13 +557,13 @@ int region_intersects(resource_size_t start, size_t size, unsigned long flags, } read_unlock(&resource_lock); - if (other == 0) - return type ? REGION_INTERSECTS : REGION_DISJOINT; + if (type == 0) + return REGION_DISJOINT; - if (type) - return REGION_MIXED; + if (other == 0) + return REGION_INTERSECTS; - return REGION_DISJOINT; + return REGION_MIXED; } EXPORT_SYMBOL_GPL(region_intersects); -- cgit v1.2.3 From 1f90f6a835514cb69bfede0b2752b0cb7a351bbd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:05 +0200 Subject: resource: Group resource_overlaps() with other inline helpers For better maintenance group resource_overlaps() with other inline helpers. While at it, drop extra parentheses. Signed-off-by: Andy Shevchenko Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/ioport.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 5135d4b86cd6..df4581107536 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -229,6 +229,11 @@ static inline bool resource_contains(struct resource *r1, struct resource *r2) return r1->start <= r2->start && r1->end >= r2->end; } +/* True if any part of r1 overlaps r2 */ +static inline bool resource_overlaps(struct resource *r1, struct resource *r2) +{ + return r1->start <= r2->end && r1->end >= r2->start; +} /* Convenience shorthand with allocation */ #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) @@ -296,12 +301,6 @@ extern int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); -/* True if any part of r1 overlaps r2 */ -static inline bool resource_overlaps(struct resource *r1, struct resource *r2) -{ - return (r1->start <= r2->end && r1->end >= r2->start); -} - struct resource *devm_request_free_mem_region(struct device *dev, struct resource *base, unsigned long size); struct resource *request_free_mem_region(struct resource *base, -- cgit v1.2.3 From 5562f35d7feabfd68cd58a1ee28b451f90e82417 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:06 +0200 Subject: resource: Introduce resource_union() for overlapping resources Some already present users may utilize resource_union() helper. Provide it for them and for wider use in the future. Signed-off-by: Andy Shevchenko Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/ioport.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index df4581107536..40320eb5bc0e 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -10,9 +10,10 @@ #define _LINUX_IOPORT_H #ifndef __ASSEMBLY__ +#include #include +#include #include -#include /* * Resources are tree-like, allowing * nesting etc.. @@ -235,6 +236,16 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2) return r1->start <= r2->end && r1->end >= r2->start; } +static inline bool +resource_union(struct resource *r1, struct resource *r2, struct resource *r) +{ + if (!resource_overlaps(r1, r2)) + return false; + r->start = min(r1->start, r2->start); + r->end = max(r1->end, r2->end); + return true; +} + /* Convenience shorthand with allocation */ #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) #define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED) -- cgit v1.2.3 From f65674df1b23cdcb6f656a14f659ffea83e7acaa Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:07 +0200 Subject: resource: Introduce resource_intersection() for overlapping resources There will be at least one user that can utilize new helper. Provide the helper for future user and for wider use. Signed-off-by: Andy Shevchenko Reviewed-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/ioport.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 40320eb5bc0e..ece1a8db309c 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -236,6 +236,16 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2) return r1->start <= r2->end && r1->end >= r2->start; } +static inline bool +resource_intersection(struct resource *r1, struct resource *r2, struct resource *r) +{ + if (!resource_overlaps(r1, r2)) + return false; + r->start = max(r1->start, r2->start); + r->end = min(r1->end, r2->end); + return true; +} + static inline bool resource_union(struct resource *r1, struct resource *r2, struct resource *r) { -- cgit v1.2.3 From 5df38ca6afeceaf3ea911ad2f7e2101364dee48d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:08 +0200 Subject: resource: Add test cases for new resource API Add test cases for newly added resource APIs. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- kernel/Makefile | 1 + kernel/resource_kunit.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 11 ++++ 3 files changed, 162 insertions(+) create mode 100644 kernel/resource_kunit.c diff --git a/kernel/Makefile b/kernel/Makefile index af601b9bda0e..aac15aeb9d69 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -123,6 +123,7 @@ obj-$(CONFIG_HAS_IOMEM) += iomem.o obj-$(CONFIG_RSEQ) += rseq.o obj-$(CONFIG_WATCH_QUEUE) += watch_queue.o +obj-$(CONFIG_RESOURCE_KUNIT_TEST) += resource_kunit.o obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o CFLAGS_stackleak.o += $(DISABLE_STACKLEAK_PLUGIN) diff --git a/kernel/resource_kunit.c b/kernel/resource_kunit.c new file mode 100644 index 000000000000..9fdbca8426f1 --- /dev/null +++ b/kernel/resource_kunit.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test cases for API provided by resource.c and ioport.h + */ + +#include +#include +#include +#include + +#define R0_START 0x0000 +#define R0_END 0xffff +#define R1_START 0x1234 +#define R1_END 0x2345 +#define R2_START 0x4567 +#define R2_END 0x5678 +#define R3_START 0x6789 +#define R3_END 0x789a +#define R4_START 0x2000 +#define R4_END 0x7000 + +static struct resource r0 = { .start = R0_START, .end = R0_END }; +static struct resource r1 = { .start = R1_START, .end = R1_END }; +static struct resource r2 = { .start = R2_START, .end = R2_END }; +static struct resource r3 = { .start = R3_START, .end = R3_END }; +static struct resource r4 = { .start = R4_START, .end = R4_END }; + +struct result { + struct resource *r1; + struct resource *r2; + struct resource r; + bool ret; +}; + +static struct result results_for_union[] = { + { + .r1 = &r1, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, + }, { + .r1 = &r2, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, + }, { + .r1 = &r3, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, + }, { + .r1 = &r4, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, + }, { + .r1 = &r2, .r2 = &r1, .ret = false, + }, { + .r1 = &r3, .r2 = &r1, .ret = false, + }, { + .r1 = &r4, .r2 = &r1, .r.start = R1_START, .r.end = R4_END, .ret = true, + }, { + .r1 = &r2, .r2 = &r3, .ret = false, + }, { + .r1 = &r2, .r2 = &r4, .r.start = R4_START, .r.end = R4_END, .ret = true, + }, { + .r1 = &r3, .r2 = &r4, .r.start = R4_START, .r.end = R3_END, .ret = true, + }, +}; + +static struct result results_for_intersection[] = { + { + .r1 = &r1, .r2 = &r0, .r.start = R1_START, .r.end = R1_END, .ret = true, + }, { + .r1 = &r2, .r2 = &r0, .r.start = R2_START, .r.end = R2_END, .ret = true, + }, { + .r1 = &r3, .r2 = &r0, .r.start = R3_START, .r.end = R3_END, .ret = true, + }, { + .r1 = &r4, .r2 = &r0, .r.start = R4_START, .r.end = R4_END, .ret = true, + }, { + .r1 = &r2, .r2 = &r1, .ret = false, + }, { + .r1 = &r3, .r2 = &r1, .ret = false, + }, { + .r1 = &r4, .r2 = &r1, .r.start = R4_START, .r.end = R1_END, .ret = true, + }, { + .r1 = &r2, .r2 = &r3, .ret = false, + }, { + .r1 = &r2, .r2 = &r4, .r.start = R2_START, .r.end = R2_END, .ret = true, + }, { + .r1 = &r3, .r2 = &r4, .r.start = R3_START, .r.end = R4_END, .ret = true, + }, +}; + +static void resource_do_test(struct kunit *test, bool ret, struct resource *r, + bool exp_ret, struct resource *exp_r, + struct resource *r1, struct resource *r2) +{ + KUNIT_EXPECT_EQ_MSG(test, ret, exp_ret, "Resources %pR %pR", r1, r2); + KUNIT_EXPECT_EQ_MSG(test, r->start, exp_r->start, "Start elements are not equal"); + KUNIT_EXPECT_EQ_MSG(test, r->end, exp_r->end, "End elements are not equal"); +} + +static void resource_do_union_test(struct kunit *test, struct result *r) +{ + struct resource result; + bool ret; + + memset(&result, 0, sizeof(result)); + ret = resource_union(r->r1, r->r2, &result); + resource_do_test(test, ret, &result, r->ret, &r->r, r->r1, r->r2); + + memset(&result, 0, sizeof(result)); + ret = resource_union(r->r2, r->r1, &result); + resource_do_test(test, ret, &result, r->ret, &r->r, r->r2, r->r1); +} + +static void resource_test_union(struct kunit *test) +{ + struct result *r = results_for_union; + unsigned int i = 0; + + do { + resource_do_union_test(test, &r[i]); + } while (++i < ARRAY_SIZE(results_for_union)); +} + +static void resource_do_intersection_test(struct kunit *test, struct result *r) +{ + struct resource result; + bool ret; + + memset(&result, 0, sizeof(result)); + ret = resource_intersection(r->r1, r->r2, &result); + resource_do_test(test, ret, &result, r->ret, &r->r, r->r1, r->r2); + + memset(&result, 0, sizeof(result)); + ret = resource_intersection(r->r2, r->r1, &result); + resource_do_test(test, ret, &result, r->ret, &r->r, r->r2, r->r1); +} + +static void resource_test_intersection(struct kunit *test) +{ + struct result *r = results_for_intersection; + unsigned int i = 0; + + do { + resource_do_intersection_test(test, &r[i]); + } while (++i < ARRAY_SIZE(results_for_intersection)); +} + +static struct kunit_case resource_test_cases[] = { + KUNIT_CASE(resource_test_union), + KUNIT_CASE(resource_test_intersection), + {} +}; + +static struct kunit_suite resource_test_suite = { + .name = "resource", + .test_cases = resource_test_cases, +}; +kunit_test_suite(resource_test_suite); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c789b39ed527..64f9501a6b5c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2226,6 +2226,17 @@ config BITFIELD_KUNIT If unsure, say N. +config RESOURCE_KUNIT_TEST + tristate "KUnit test for resource API" + depends on KUNIT + help + This builds the resource API unit test. + Tests the logic of API provided by resource.c and ioport.h. + For more information on KUnit and unit tests in general please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config SYSCTL_KUNIT_TEST tristate "KUnit test for sysctl" if !KUNIT_ALL_TESTS depends on KUNIT -- cgit v1.2.3 From 07aec68ecf35a2cee5173001c70e3d7b345b3d05 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:09 +0200 Subject: PCI/ACPI: Replace open coded variant of resource_union() Since we have resource_union() helper, let's utilize it here. Signed-off-by: Andy Shevchenko Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index c12b5fb3e8fb..0bf072cef6cf 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -722,9 +722,7 @@ static void acpi_pci_root_validate_resources(struct device *dev, * our resources no longer match the ACPI _CRS, but * the kernel resource tree doesn't allow overlaps. */ - if (resource_overlaps(res1, res2)) { - res2->start = min(res1->start, res2->start); - res2->end = max(res1->end, res2->end); + if (resource_union(res1, res2, res2)) { dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n", res2, res1); free = true; -- cgit v1.2.3 From f7499785c8915ef4bda3cfa34c814350f07368fd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Nov 2020 22:45:10 +0200 Subject: ACPI: watchdog: Replace open coded variant of resource_union() Since we have resource_union() helper, let's utilize it here. Signed-off-by: Andy Shevchenko Reviewed-by: Hanjun Guo Tested-by: Hanjun Guo Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_watchdog.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 5c1e9ea43123..ca28183f4d13 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -151,11 +151,7 @@ void __init acpi_watchdog_init(void) found = false; resource_list_for_each_entry(rentry, &resource_list) { if (rentry->res->flags == res.flags && - resource_overlaps(rentry->res, &res)) { - if (res.start < rentry->res->start) - rentry->res->start = res.start; - if (res.end > rentry->res->end) - rentry->res->end = res.end; + resource_union(rentry->res, &res, rentry->res)) { found = true; break; } -- cgit v1.2.3 From eb37ba316fdec9c6af36b8b155732568c5b2a2d4 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 10:08:44 +0800 Subject: ACPI: processor: Remove the duplicated ACPI_PROCESSOR_CLASS macro The ACPI_PROCESSOR_CLASS macro is defined in , and ACPI drivers for processor already included , so we can remove those duplicated ACPI_PROCESSOR_CLASS macros. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_idle.c | 1 - drivers/acpi/processor_perflib.c | 1 - drivers/acpi/processor_thermal.c | 2 -- drivers/acpi/processor_throttling.c | 1 - 4 files changed, 5 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f66236cff69b..d93e400940a3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -31,7 +31,6 @@ #include #endif -#define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_idle"); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index b04a68950ff1..3b5a9646b49d 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -22,7 +22,6 @@ #define PREFIX "ACPI: " -#define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_perflib"); diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 6c7d05b37c98..677a132be242 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -19,8 +19,6 @@ #define PREFIX "ACPI: " -#define ACPI_PROCESSOR_CLASS "processor" - #ifdef CONFIG_CPU_FREQ /* If a passive cooling situation is detected, primarily CPUfreq is used, as it diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index a0bd56ece3ff..b1876534324b 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -22,7 +22,6 @@ #define PREFIX "ACPI: " -#define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_throttling"); -- cgit v1.2.3 From ab5369bba5189f44538bef07943f323992fe964e Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 10:20:29 +0800 Subject: ACPI: debug: Remove the not used function The inline function __acpi_aml_opened() is not used anywhere, remove it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_dbg.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c index fb7290338593..d50261d05f3a 100644 --- a/drivers/acpi/acpi_dbg.c +++ b/drivers/acpi/acpi_dbg.c @@ -117,13 +117,6 @@ static inline bool __acpi_aml_busy(void) return false; } -static inline bool __acpi_aml_opened(void) -{ - if (acpi_aml_io.flags & ACPI_AML_OPEN) - return true; - return false; -} - static inline bool __acpi_aml_used(void) { return acpi_aml_io.usages ? true : false; -- cgit v1.2.3 From dff714087c40644d225094a1f75d2272cc8a4885 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 10:25:10 +0800 Subject: ACPI: SBS: Simplify the driver init code acpi_bus_register_driver() will check acpi_disable and return -ENODEV, so the acpi_disable check outside the acpi_bus_register_driver() is duplicated, can be removed. Also we can just return from acpi_bus_register_driver() then we can simplify the code further. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sbs.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index e6d9f4de2800..cbd1af7ce7f4 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -714,16 +714,7 @@ static struct acpi_driver acpi_sbs_driver = { static int __init acpi_sbs_init(void) { - int result = 0; - - if (acpi_disabled) - return -ENODEV; - - result = acpi_bus_register_driver(&acpi_sbs_driver); - if (result < 0) - return -ENODEV; - - return 0; + return acpi_bus_register_driver(&acpi_sbs_driver); } static void __exit acpi_sbs_exit(void) -- cgit v1.2.3 From e882b0953ccc7ad9938251f9c7e00411a4ac48d7 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 10:25:11 +0800 Subject: ACPI: SBS: Simplify the code using module_acpi_driver() Using the module_acpi_driver() to simplify the code. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sbs.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index cbd1af7ce7f4..3b0b6dd34914 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -711,17 +711,4 @@ static struct acpi_driver acpi_sbs_driver = { }, .drv.pm = &acpi_sbs_pm, }; - -static int __init acpi_sbs_init(void) -{ - return acpi_bus_register_driver(&acpi_sbs_driver); -} - -static void __exit acpi_sbs_exit(void) -{ - acpi_bus_unregister_driver(&acpi_sbs_driver); - return; -} - -module_init(acpi_sbs_init); -module_exit(acpi_sbs_exit); +module_acpi_driver(acpi_sbs_driver); -- cgit v1.2.3 From 907cc9fefe8349d6cc70d6800cc8edf10acf7634 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 10:26:44 +0800 Subject: ACPI: tiny-power-button: Simplify the code using module_acpi_driver() Using module_acpi_driver() to simplify the code. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/tiny-power-button.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/acpi/tiny-power-button.c b/drivers/acpi/tiny-power-button.c index 420e61b8eaae..a19f0e4e69f7 100644 --- a/drivers/acpi/tiny-power-button.c +++ b/drivers/acpi/tiny-power-button.c @@ -40,6 +40,4 @@ static struct acpi_driver acpi_tiny_power_button_driver = { }, }; -module_driver(acpi_tiny_power_button_driver, - acpi_bus_register_driver, - acpi_bus_unregister_driver); +module_acpi_driver(acpi_tiny_power_button_driver); -- cgit v1.2.3 From 146f5f68e3d9263e385c046982ac96ffad12e574 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 11:00:44 +0800 Subject: ACPI: acpi_drivers.h: Remove the leftover dead code After commit 5ba8b1c6fe40 ("ACPI: remove dead code"), ACPI_PROCESSOR_LIMIT_* macros are not used anymore, remove it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/acpi/acpi_drivers.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 5eb175933a5b..634f967016ba 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -94,14 +94,6 @@ void pci_acpi_crs_quirks(void); static inline void pci_acpi_crs_quirks(void) { } #endif -/* -------------------------------------------------------------------------- - Processor - -------------------------------------------------------------------------- */ - -#define ACPI_PROCESSOR_LIMIT_NONE 0x00 -#define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01 -#define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02 - /*-------------------------------------------------------------------------- Dock Station -------------------------------------------------------------------------- */ -- cgit v1.2.3 From ec2a9cea9fca8581b0cd3d994fb99050d61a8130 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 13 Nov 2020 11:00:45 +0800 Subject: ACPI: acpi_drivers.h: Update the kernel doc pci_bind.c is not exist anymore, so just remove all the .c file reference as the c file reference is not useful and avoid future non-consistency update. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/acpi/acpi_drivers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 634f967016ba..d4f39a20aa2a 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -64,14 +64,14 @@ -------------------------------------------------------------------------- */ -/* ACPI PCI Interrupt Link (pci_link.c) */ +/* ACPI PCI Interrupt Link */ int acpi_irq_penalty_init(void); int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, int *polarity, char **name); int acpi_pci_link_free_irq(acpi_handle handle); -/* ACPI PCI Device Binding (pci_bind.c) */ +/* ACPI PCI Device Binding */ struct pci_bus; -- cgit v1.2.3 From 2e84ea5a3269f9e1d4e7658a9893f5eac4aee5ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Nov 2020 19:13:17 +0100 Subject: ACPI: EC: Eliminate in_interrupt() usage advance_transaction() is using in_interrupt() to distinguish between an invocation from the interrupt handler and an invocation from another part of the stack. This looks misleading because chains like acpi_update_all_gpes() -> acpi_ev_gpe_detect() -> acpi_ev_detect_gpe() -> acpi_ec_gpe_handler() should probably also behave as if they were called from an interrupt handler. Replace in_interrupt() usage with a function parameter. Set this parameter to `true' if invoked from an interrupt handler (acpi_ec_gpe_handler() and acpi_ec_irq_handler()) and `false' otherwise. Signed-off-by: Sebastian Andrzej Siewior [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e0cb1bcfffb2..0caf5ca1fc07 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -169,7 +169,7 @@ struct acpi_ec_query { }; static int acpi_ec_query(struct acpi_ec *ec, u8 *data); -static void advance_transaction(struct acpi_ec *ec); +static void advance_transaction(struct acpi_ec *ec, bool interrupt); static void acpi_ec_event_handler(struct work_struct *work); static void acpi_ec_event_processor(struct work_struct *work); @@ -358,7 +358,7 @@ static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) * EN=1 writes. */ ec_dbg_raw("Polling quirk"); - advance_transaction(ec); + advance_transaction(ec, false); } } @@ -488,7 +488,7 @@ static inline void __acpi_ec_enable_event(struct acpi_ec *ec) * Unconditionally invoke this once after enabling the event * handling mechanism to detect the pending events. */ - advance_transaction(ec); + advance_transaction(ec, false); } static inline void __acpi_ec_disable_event(struct acpi_ec *ec) @@ -632,14 +632,13 @@ static inline void ec_transaction_transition(struct acpi_ec *ec, unsigned long f } } -static void advance_transaction(struct acpi_ec *ec) +static void advance_transaction(struct acpi_ec *ec, bool interrupt) { struct transaction *t; u8 status; bool wakeup = false; - ec_dbg_stm("%s (%d)", in_interrupt() ? "IRQ" : "TASK", - smp_processor_id()); + ec_dbg_stm("%s (%d)", interrupt ? "IRQ" : "TASK", smp_processor_id()); /* * By always clearing STS before handling all indications, we can * ensure a hardware STS 0->1 change after this clearing can always @@ -699,7 +698,7 @@ err: * otherwise will take a not handled IRQ as a false one. */ if (!(status & ACPI_EC_FLAG_SCI)) { - if (in_interrupt() && t) { + if (interrupt && t) { if (t->irq_count < ec_storm_threshold) ++t->irq_count; /* Allow triggering on 0 threshold */ @@ -710,7 +709,7 @@ err: out: if (status & ACPI_EC_FLAG_SCI) acpi_ec_submit_query(ec); - if (wakeup && in_interrupt()) + if (wakeup && interrupt) wake_up(&ec->wait); } @@ -767,7 +766,7 @@ static int ec_poll(struct acpi_ec *ec) if (!ec_guard(ec)) return 0; spin_lock_irqsave(&ec->lock, flags); - advance_transaction(ec); + advance_transaction(ec, false); spin_unlock_irqrestore(&ec->lock, flags); } while (time_before(jiffies, delay)); pr_debug("controller reset, restart transaction\n"); @@ -1216,7 +1215,7 @@ static void acpi_ec_check_event(struct acpi_ec *ec) * taking care of it. */ if (!ec->curr) - advance_transaction(ec); + advance_transaction(ec, false); spin_unlock_irqrestore(&ec->lock, flags); } } @@ -1259,7 +1258,7 @@ static void acpi_ec_handle_interrupt(struct acpi_ec *ec) unsigned long flags; spin_lock_irqsave(&ec->lock, flags); - advance_transaction(ec); + advance_transaction(ec, true); spin_unlock_irqrestore(&ec->lock, flags); } -- cgit v1.2.3 From a8b6cfdf978602dbbb0b9b19e74f25af7a8ca389 Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Thu, 19 Nov 2020 13:58:01 +0100 Subject: Documentation: ACPI: _DSD: enable hyperlink in final references For inline web links, no special markup is needed. Signed-off-by: Flavio Suligoi Acked-by: Sakari Ailus [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki --- Documentation/firmware-guide/acpi/dsd/leds.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/firmware-guide/acpi/dsd/leds.rst b/Documentation/firmware-guide/acpi/dsd/leds.rst index aba1e9abfeeb..b99fff8e06f2 100644 --- a/Documentation/firmware-guide/acpi/dsd/leds.rst +++ b/Documentation/firmware-guide/acpi/dsd/leds.rst @@ -90,10 +90,10 @@ where References ========== -[1] Device tree. , referenced 2019-02-21. +[1] Device tree. https://www.devicetree.org, referenced 2019-02-21. [2] Advanced Configuration and Power Interface Specification. - , + https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf, referenced 2019-02-21. [3] Documentation/devicetree/bindings/leds/common.txt @@ -101,11 +101,11 @@ References [4] Documentation/devicetree/bindings/media/video-interfaces.txt [5] Device Properties UUID For _DSD. - , + https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf, referenced 2019-02-21. [6] Hierarchical Data Extension UUID For _DSD. - , + https://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf, referenced 2019-02-21. [7] Documentation/firmware-guide/acpi/dsd/data-node-references.rst -- cgit v1.2.3 From 390029c27ea74099a7f56f7ae502d11953fa1187 Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Fri, 20 Nov 2020 12:11:25 +0100 Subject: Documentation: ACPI: enumeration: add PCI hierarchy representation For "fixed" PCI devices, such as chips directly soldered on the main board (ethernet, Wi-Fi, serial ports, etc.), it is possible to find an ACPI enumeration. This allows to add useful properties to these devices. Just for an example: the property "gpio-line-names" can be added to the pins of a GPIO expander on the PCI bus. In order to find the ACPI name of a PCI device, it's necessary to disassemble the BIOS ACPI tables (in particular the DSDT) and also to analyze the PCI bus topology of the board. This patch, with a practical example, show how to do this. Signed-off-by: Flavio Suligoi Reviewed-by: Mika Westerberg Reviewed-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- Documentation/firmware-guide/acpi/enumeration.rst | 154 ++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/Documentation/firmware-guide/acpi/enumeration.rst b/Documentation/firmware-guide/acpi/enumeration.rst index c13fee8b02ba..9f0d5c854fa4 100644 --- a/Documentation/firmware-guide/acpi/enumeration.rst +++ b/Documentation/firmware-guide/acpi/enumeration.rst @@ -461,3 +461,157 @@ Otherwise, the _DSD itself is regarded as invalid and therefore the "compatible" property returned by it is meaningless. Refer to :doc:`DSD-properties-rules` for more information. + +PCI hierarchy representation +============================ + +Sometimes could be useful to enumerate a PCI device, knowing its position on the +PCI bus. + +For example, some systems use PCI devices soldered directly on the mother board, +in a fixed position (ethernet, Wi-Fi, serial ports, etc.). In this conditions it +is possible to refer to these PCI devices knowing their position on the PCI bus +topology. + +To identify a PCI device, a complete hierarchical description is required, from +the chipset root port to the final device, through all the intermediate +bridges/switches of the board. + +For example, let us assume to have a system with a PCIe serial port, an +Exar XR17V3521, soldered on the main board. This UART chip also includes +16 GPIOs and we want to add the property ``gpio-line-names`` [1] to these pins. +In this case, the ``lspci`` output for this component is:: + + 07:00.0 Serial controller: Exar Corp. XR17V3521 Dual PCIe UART (rev 03) + +The complete ``lspci`` output (manually reduced in length) is:: + + 00:00.0 Host bridge: Intel Corp... Host Bridge (rev 0d) + ... + 00:13.0 PCI bridge: Intel Corp... PCI Express Port A #1 (rev fd) + 00:13.1 PCI bridge: Intel Corp... PCI Express Port A #2 (rev fd) + 00:13.2 PCI bridge: Intel Corp... PCI Express Port A #3 (rev fd) + 00:14.0 PCI bridge: Intel Corp... PCI Express Port B #1 (rev fd) + 00:14.1 PCI bridge: Intel Corp... PCI Express Port B #2 (rev fd) + ... + 05:00.0 PCI bridge: Pericom Semiconductor Device 2404 (rev 05) + 06:01.0 PCI bridge: Pericom Semiconductor Device 2404 (rev 05) + 06:02.0 PCI bridge: Pericom Semiconductor Device 2404 (rev 05) + 06:03.0 PCI bridge: Pericom Semiconductor Device 2404 (rev 05) + 07:00.0 Serial controller: Exar Corp. XR17V3521 Dual PCIe UART (rev 03) <-- Exar + ... + +The bus topology is:: + + -[0000:00]-+-00.0 + ... + +-13.0-[01]----00.0 + +-13.1-[02]----00.0 + +-13.2-[03]-- + +-14.0-[04]----00.0 + +-14.1-[05-09]----00.0-[06-09]--+-01.0-[07]----00.0 <-- Exar + | +-02.0-[08]----00.0 + | \-03.0-[09]-- + ... + \-1f.1 + +To describe this Exar device on the PCI bus, we must start from the ACPI name +of the chipset bridge (also called "root port") with address:: + + Bus: 0 - Device: 14 - Function: 1 + +To find this information is necessary disassemble the BIOS ACPI tables, in +particular the DSDT (see also [2]):: + + mkdir ~/tables/ + cd ~/tables/ + acpidump > acpidump + acpixtract -a acpidump + iasl -e ssdt?.* -d dsdt.dat + +Now, in the dsdt.dsl, we have to search the device whose address is related to +0x14 (device) and 0x01 (function). In this case we can find the following +device:: + + Scope (_SB.PCI0) + { + ... other definitions follow ... + Device (RP02) + { + Method (_ADR, 0, NotSerialized) // _ADR: Address + { + If ((RPA2 != Zero)) + { + Return (RPA2) /* \RPA2 */ + } + Else + { + Return (0x00140001) + } + } + ... other definitions follow ... + +and the _ADR method [3] returns exactly the device/function couple that +we are looking for. With this information and analyzing the above ``lspci`` +output (both the devices list and the devices tree), we can write the following +ACPI description for the Exar PCIe UART, also adding the list of its GPIO line +names:: + + Scope (_SB.PCI0.RP02) + { + Device (BRG1) //Bridge + { + Name (_ADR, 0x0000) + + Device (BRG2) //Bridge + { + Name (_ADR, 0x00010000) + + Device (EXAR) + { + Name (_ADR, 0x0000) + + Name (_DSD, Package () + { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package () + { + "gpio-line-names", + Package () + { + "mode_232", + "mode_422", + "mode_485", + "misc_1", + "misc_2", + "misc_3", + "", + "", + "aux_1", + "aux_2", + "aux_3", + } + } + } + }) + } + } + } + } + +The location "_SB.PCI0.RP02" is obtained by the above investigation in the +dsdt.dsl table, whereas the device names "BRG1", "BRG2" and "EXAR" are +created analyzing the position of the Exar UART in the PCI bus topology. + +References +========== + +[1] Documentation/firmware-guide/acpi/gpio-properties.rst + +[2] Documentation/admin-guide/acpi/initrd_table_override.rst + +[3] ACPI Specifications, Version 6.3 - Paragraph 6.1.1 _ADR Address) + https://uefi.org/sites/default/files/resources/ACPI_6_3_May16.pdf, + referenced 2020-11-18 -- cgit v1.2.3 From d269fb031392d99386b3d11e899e88ae76af9466 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 23 Nov 2020 20:00:18 +0100 Subject: ACPI: EC: Fold acpi_ec_clear_gpe() into its caller Fold acpi_ec_clear_gpe() which is only used in one place into its caller and clean up comments related to that function while at it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 0caf5ca1fc07..97e595238a8c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -372,23 +372,6 @@ static inline void acpi_ec_disable_gpe(struct acpi_ec *ec, bool close) } } -static inline void acpi_ec_clear_gpe(struct acpi_ec *ec) -{ - /* - * GPE STS is a W1C register, which means: - * 1. Software can clear it without worrying about clearing other - * GPEs' STS bits when the hardware sets them in parallel. - * 2. As long as software can ensure only clearing it when it is - * set, hardware won't set it in parallel. - * So software can clear GPE in any contexts. - * Warning: do not move the check into advance_transaction() as the - * EC commands will be sent without GPE raised. - */ - if (!acpi_ec_is_gpe_raised(ec)) - return; - acpi_clear_gpe(NULL, ec->gpe); -} - /* -------------------------------------------------------------------------- * Transaction Management * -------------------------------------------------------------------------- */ @@ -639,13 +622,21 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) bool wakeup = false; ec_dbg_stm("%s (%d)", interrupt ? "IRQ" : "TASK", smp_processor_id()); + /* - * By always clearing STS before handling all indications, we can - * ensure a hardware STS 0->1 change after this clearing can always - * trigger a GPE interrupt. + * Clear GPE_STS upfront to allow subsequent hardware GPE_STS 0->1 + * changes to always trigger a GPE interrupt. + * + * GPE STS is a W1C register, which means: + * + * 1. Software can clear it without worrying about clearing the other + * GPEs' STS bits when the hardware sets them in parallel. + * + * 2. As long as software can ensure only clearing it when it is set, + * hardware won't set it in parallel. */ - if (ec->gpe >= 0) - acpi_ec_clear_gpe(ec); + if (ec->gpe >= 0 && acpi_ec_is_gpe_raised(ec)) + acpi_clear_gpe(NULL, ec->gpe); status = acpi_ec_read_status(ec); t = ec->curr; -- cgit v1.2.3 From d2a2e6ccebb80d297f9827743f49d0f70b4a2daa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 23 Nov 2020 20:00:25 +0100 Subject: ACPI: EC: Rename acpi_ec_is_gpe_raised() Rename acpi_ec_is_gpe_raised() into acpi_ec_gpe_status_set(), update its callers accordingly and drop the ternary operator (which isn't really necessary in there) from it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 97e595238a8c..c4be16a495e1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -335,12 +335,12 @@ static const char *acpi_ec_cmd_string(u8 cmd) * GPE Registers * -------------------------------------------------------------------------- */ -static inline bool acpi_ec_is_gpe_raised(struct acpi_ec *ec) +static inline bool acpi_ec_gpe_status_set(struct acpi_ec *ec) { acpi_event_status gpe_status = 0; (void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status); - return (gpe_status & ACPI_EVENT_FLAG_STATUS_SET) ? true : false; + return !!(gpe_status & ACPI_EVENT_FLAG_STATUS_SET); } static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) @@ -351,7 +351,7 @@ static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) BUG_ON(ec->reference_count < 1); acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); } - if (acpi_ec_is_gpe_raised(ec)) { + if (acpi_ec_gpe_status_set(ec)) { /* * On some platforms, EN=1 writes cannot trigger GPE. So * software need to manually trigger a pseudo GPE event on @@ -635,7 +635,7 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) * 2. As long as software can ensure only clearing it when it is set, * hardware won't set it in parallel. */ - if (ec->gpe >= 0 && acpi_ec_is_gpe_raised(ec)) + if (ec->gpe >= 0 && acpi_ec_gpe_status_set(ec)) acpi_clear_gpe(NULL, ec->gpe); status = acpi_ec_read_status(ec); -- cgit v1.2.3 From 902675fa87e3a3d433481a2df6e50c10da5e20c2 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 23 Nov 2020 20:00:34 +0100 Subject: ACPI: EC: Simplify error handling in advance_transaction() Notice that the value of t in advance_transaction() does not change after its initialization and: - Initialize t upfront (and rearrange the definitions of local variables while at it). - Check it against NULL in a block executed when it is NULL. - Skip error handling for t == NULL, because a valid pointer value of t is required for the error handling. - Drop the (now redundant) check of t against NULL from the error handling block and reduce the indentation level in there. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index c4be16a495e1..23e7b2dec98e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -617,9 +617,9 @@ static inline void ec_transaction_transition(struct acpi_ec *ec, unsigned long f static void advance_transaction(struct acpi_ec *ec, bool interrupt) { - struct transaction *t; - u8 status; + struct transaction *t = ec->curr; bool wakeup = false; + u8 status; ec_dbg_stm("%s (%d)", interrupt ? "IRQ" : "TASK", smp_processor_id()); @@ -639,7 +639,7 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) acpi_clear_gpe(NULL, ec->gpe); status = acpi_ec_read_status(ec); - t = ec->curr; + /* * Another IRQ or a guarded polling mode advancement is detected, * the next QR_EC submission is then allowed. @@ -651,9 +651,10 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) clear_bit(EC_FLAGS_QUERY_GUARDING, &ec->flags); acpi_ec_complete_query(ec); } + if (!t) + goto out; } - if (!t) - goto err; + if (t->flags & ACPI_EC_COMMAND_POLL) { if (t->wlen > t->wi) { if ((status & ACPI_EC_FLAG_IBF) == 0) @@ -688,14 +689,13 @@ err: * If SCI bit is set, then don't think it's a false IRQ * otherwise will take a not handled IRQ as a false one. */ - if (!(status & ACPI_EC_FLAG_SCI)) { - if (interrupt && t) { - if (t->irq_count < ec_storm_threshold) - ++t->irq_count; - /* Allow triggering on 0 threshold */ - if (t->irq_count == ec_storm_threshold) - acpi_ec_mask_events(ec); - } + if (!(status & ACPI_EC_FLAG_SCI) && interrupt) { + if (t->irq_count < ec_storm_threshold) + ++t->irq_count; + + /* Allow triggering on 0 threshold */ + if (t->irq_count == ec_storm_threshold) + acpi_ec_mask_events(ec); } out: if (status & ACPI_EC_FLAG_SCI) -- cgit v1.2.3 From 631734fce3fa27ec5d6f456fc1dd3699617c9efb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 23 Nov 2020 20:00:42 +0100 Subject: ACPI: EC: Untangle error handling in advance_transaction() Introduce acpi_ec_spurious_interrupt() for recording spurious interrupts and use it for error handling in advance_transaction(), drop the (now redundant) original error handling block from there along with a frew goto statements that are not necessary any more. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 23e7b2dec98e..091f0e9f37a0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -615,6 +615,16 @@ static inline void ec_transaction_transition(struct acpi_ec *ec, unsigned long f } } +static void acpi_ec_spurious_interrupt(struct acpi_ec *ec, struct transaction *t) +{ + if (t->irq_count < ec_storm_threshold) + ++t->irq_count; + + /* Trigger if the threshold is 0 too. */ + if (t->irq_count == ec_storm_threshold) + acpi_ec_mask_events(ec); +} + static void advance_transaction(struct acpi_ec *ec, bool interrupt) { struct transaction *t = ec->curr; @@ -659,8 +669,8 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) if (t->wlen > t->wi) { if ((status & ACPI_EC_FLAG_IBF) == 0) acpi_ec_write_data(ec, t->wdata[t->wi++]); - else - goto err; + else if (interrupt && !(status & ACPI_EC_FLAG_SCI)) + acpi_ec_spurious_interrupt(ec, t); } else if (t->rlen > t->ri) { if ((status & ACPI_EC_FLAG_OBF) == 1) { t->rdata[t->ri++] = acpi_ec_read_data(ec); @@ -671,32 +681,19 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); wakeup = true; } - } else - goto err; + } else if (interrupt && !(status & ACPI_EC_FLAG_SCI)) { + acpi_ec_spurious_interrupt(ec, t); + } } else if (t->wlen == t->wi && (status & ACPI_EC_FLAG_IBF) == 0) { ec_transaction_transition(ec, ACPI_EC_COMMAND_COMPLETE); wakeup = true; } - goto out; } else if (!(status & ACPI_EC_FLAG_IBF)) { acpi_ec_write_cmd(ec, t->command); ec_transaction_transition(ec, ACPI_EC_COMMAND_POLL); - goto out; } -err: - /* - * If SCI bit is set, then don't think it's a false IRQ - * otherwise will take a not handled IRQ as a false one. - */ - if (!(status & ACPI_EC_FLAG_SCI) && interrupt) { - if (t->irq_count < ec_storm_threshold) - ++t->irq_count; - /* Allow triggering on 0 threshold */ - if (t->irq_count == ec_storm_threshold) - acpi_ec_mask_events(ec); - } out: if (status & ACPI_EC_FLAG_SCI) acpi_ec_submit_query(ec); -- cgit v1.2.3 From 2a39a30f0d9b5243962a19b2d5a48a8ac3a9a292 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 23 Nov 2020 20:01:01 +0100 Subject: ACPI: EC: Clean up status flags checks in advance_transaction() Eliminate comparisons from the status flags checks in advance_transaction() (especially from the one that is only correct, because the value of the flag checked in there is 1) and rearrange the code for more clarity while at it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 091f0e9f37a0..13565629ce0a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -667,25 +667,24 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) if (t->flags & ACPI_EC_COMMAND_POLL) { if (t->wlen > t->wi) { - if ((status & ACPI_EC_FLAG_IBF) == 0) + if (!(status & ACPI_EC_FLAG_IBF)) acpi_ec_write_data(ec, t->wdata[t->wi++]); else if (interrupt && !(status & ACPI_EC_FLAG_SCI)) acpi_ec_spurious_interrupt(ec, t); } else if (t->rlen > t->ri) { - if ((status & ACPI_EC_FLAG_OBF) == 1) { + if (status & ACPI_EC_FLAG_OBF) { t->rdata[t->ri++] = acpi_ec_read_data(ec); if (t->rlen == t->ri) { ec_transaction_transition(ec, ACPI_EC_COMMAND_COMPLETE); + wakeup = true; if (t->command == ACPI_EC_COMMAND_QUERY) ec_dbg_evt("Command(%s) completed by hardware", acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); - wakeup = true; } } else if (interrupt && !(status & ACPI_EC_FLAG_SCI)) { acpi_ec_spurious_interrupt(ec, t); } - } else if (t->wlen == t->wi && - (status & ACPI_EC_FLAG_IBF) == 0) { + } else if (t->wlen == t->wi && !(status & ACPI_EC_FLAG_IBF)) { ec_transaction_transition(ec, ACPI_EC_COMMAND_COMPLETE); wakeup = true; } @@ -697,6 +696,7 @@ static void advance_transaction(struct acpi_ec *ec, bool interrupt) out: if (status & ACPI_EC_FLAG_SCI) acpi_ec_submit_query(ec); + if (wakeup && interrupt) wake_up(&ec->wait); } -- cgit v1.2.3 From 55130fb22a1c396139c3da46f939bf5a6a92095e Mon Sep 17 00:00:00 2001 From: Punit Agrawal Date: Tue, 24 Nov 2020 08:59:51 +0900 Subject: ACPI: processor: Drop duplicate setting of shared_cpu_map 'shared_cpu_map', stored as part of the per-processor acpi_processor_performance structre, is used to store CPUs that share a performance domain. By definition it contains the owning CPU. While building the 'shared_cpu_map' it is being set twice - once while initialising the performance domains and again when matching CPUs belonging to the same domain. Drop the unnecessary initialisation. Signed-off-by: Punit Agrawal Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_perflib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index b04a68950ff1..b0d320f18163 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -616,7 +616,6 @@ int acpi_processor_preregister_performance( continue; pr->performance = per_cpu_ptr(performance, i); - cpumask_set_cpu(i, pr->performance->shared_cpu_map); pdomain = &(pr->performance->domain_info); if (acpi_processor_get_psd(pr->handle, pdomain)) { retval = -EINVAL; -- cgit v1.2.3 From 85810c1996db86451aa1d08c7de5c51cf8cf3aa3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 24 Nov 2020 11:56:28 +0200 Subject: ASoC: Intel: catpt: Replace open coded variant of resource_intersection() Since we have resource_intersection() helper, let's utilize it here. Signed-off-by: Andy Shevchenko Acked-by: Cezary Rojewski Signed-off-by: Rafael J. Wysocki --- sound/soc/intel/catpt/core.h | 11 ----------- sound/soc/intel/catpt/loader.c | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h index 88dc3fb6306f..174ee5ad138b 100644 --- a/sound/soc/intel/catpt/core.h +++ b/sound/soc/intel/catpt/core.h @@ -22,17 +22,6 @@ void catpt_sram_free(struct resource *sram); struct resource * catpt_request_region(struct resource *root, resource_size_t size); -static inline bool catpt_resource_overlapping(struct resource *r1, - struct resource *r2, - struct resource *ret) -{ - if (!resource_overlaps(r1, r2)) - return false; - ret->start = max(r1->start, r2->start); - ret->end = min(r1->end, r2->end); - return true; -} - struct catpt_ipc_msg { union { u32 header; diff --git a/sound/soc/intel/catpt/loader.c b/sound/soc/intel/catpt/loader.c index 8a5f20abcadb..dbbbf15dded3 100644 --- a/sound/soc/intel/catpt/loader.c +++ b/sound/soc/intel/catpt/loader.c @@ -267,7 +267,7 @@ static int catpt_restore_fwimage(struct catpt_dev *cdev, r2.start = off; r2.end = r2.start + info->size - 1; - if (!catpt_resource_overlapping(&r2, &r1, &common)) + if (!resource_intersection(&r2, &r1, &common)) continue; /* calculate start offset of common data area */ off = common.start - r1.start; -- cgit v1.2.3 From b87e745945e3de3e4d5c5eeb53e0e455e5cd5416 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 25 Nov 2020 18:16:26 +0200 Subject: resource: provide meaningful MODULE_LICENSE() in test suite modpost complains that module has no licence provided. Provide it via meaningful MODULE_LICENSE(). Reported-by: Stephen Rothwell Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- kernel/resource_kunit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/resource_kunit.c b/kernel/resource_kunit.c index 9fdbca8426f1..58ab9f914602 100644 --- a/kernel/resource_kunit.c +++ b/kernel/resource_kunit.c @@ -148,3 +148,5 @@ static struct kunit_suite resource_test_suite = { .test_cases = resource_test_cases, }; kunit_test_suite(resource_test_suite); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c59fe83a3d4f8852fc9f26af057edb5c70e0f18d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 30 Nov 2020 11:20:43 -0800 Subject: ACPICA: Add 5 new UUIDs to the known UUID table All UUID entries are related to NVDIMM and the NFIT table. ACPICA commit c114a02798dd07ccc7e51ffa4365bf039a0dd8d5 Link: https://github.com/acpica/acpica/commit/c114a027 Signed-off-by: Bob Moore Signed-off-by: Erik Kaneda Signed-off-by: Rafael J. Wysocki --- include/acpi/acuuid.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/acpi/acuuid.h b/include/acpi/acuuid.h index 10e30a5030ee..fb7d8d1fd93c 100644 --- a/include/acpi/acuuid.h +++ b/include/acpi/acuuid.h @@ -39,6 +39,7 @@ /* NVDIMM - NFIT table */ +#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66" #define UUID_VOLATILE_MEMORY "7305944f-fdda-44e3-b16c-3f22d252e5d0" #define UUID_PERSISTENT_MEMORY "66f0d379-b4f3-4074-ac43-0d3318b78cdb" #define UUID_CONTROL_REGION "92f701f6-13b4-405d-910b-299367e8234c" @@ -47,6 +48,10 @@ #define UUID_VOLATILE_VIRTUAL_CD "3d5abd30-4175-87ce-6d64-d2ade523c4bb" #define UUID_PERSISTENT_VIRTUAL_DISK "5cea02c9-4d07-69d3-269f-4496fbe096f9" #define UUID_PERSISTENT_VIRTUAL_CD "08018188-42cd-bb48-100f-5387d53ded3d" +#define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05" +#define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6" +#define UUID_NFIT_DIMM_N_HPE2 "5008664b-b758-41a0-a03c-27c2f2d04f7e" +#define UUID_NFIT_DIMM_N_HYPERV "5746c5f2-a9a2-4264-ad0e-e4ddc9e09e80" /* Processor Properties (ACPI 6.2) */ -- cgit v1.2.3 From f2f51e7a13e2de5bedffbd693c43658d2d37854e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 30 Nov 2020 11:20:44 -0800 Subject: ACPICA: Remove extreaneous "the" in comments ACPICA commit f6eae3961bf39ad8beda70c001d1815780600e39 There are several ocurrances of "the the", remove the extraneous "the". Link: https://github.com/acpica/acpica/commit/f6eae396 Signed-off-by: Colin Ian King Signed-off-by: Bob Moore Signed-off-by: Erik Kaneda Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/accommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 89101e53324b..94e18bb76556 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -13,7 +13,7 @@ /* * Common set of includes for all ACPICA source files. * We put them here because we don't want to duplicate them - * in the the source code again and again. + * in the source code again and again. * * Note: The order of these include files is important. */ -- cgit v1.2.3 From 0306f035738fa6981e4e9eb68ab0316ceaa26c88 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 30 Nov 2020 11:20:45 -0800 Subject: ACPICA: Also handle "orphan" _REG methods for GPIO OpRegions ACPICA commit b9dc31e2fc67cf196fab5253a9a673bee68b2ef5 Before this commit acpi_ev_execute_reg_methods() had special handling to handle "orphan" (no matching op_region declared) _REG methods for EC nodes. On Intel Cherry Trail devices there are 2 possible ACPI op_regions for accessing GPIOs. The standard general_purpose_io op_region and the Cherry Trail specific user_defined 0x9X op_regions. Having 2 different types of op_regions leads to potential issues with checks for op_region availability, or in other words checks if _REG has been called for the op_region which the ACPI code wants to use. Except for the "orphan" EC handling, ACPICA core does not call _REG on an ACPI node which does not define an op_region matching the type being registered; and the reference design DSDT, from which most Cherry Trail DSDTs are derived, does not define general_purpose_io, nor user_defined(0x93) op_regions for the GPO2 (UID 3) device, because no pins were assigned ACPI controlled functions in the reference design. Together this leads to the perfect storm, at least on the Cherry Trail based Medion Akayo E1239T. This design does use a GPO2 pin from its ACPI code and has added the Cherry Trail specific user_defined(0x93) opregion to its GPO2 ACPI node to access this pin. But it uses a has _REG been called availability check for the standard general_purpose_io op_region. This clearly is a bug in the DSDT, but this does work under Windows. This issue leads to the intel_vbtn driver reporting the device always being in tablet-mode at boot, even if it is in laptop mode. Which in turn causes userspace to ignore touchpad events. So iow this issues causes the touchpad to not work at boot. This commit fixes this by extending the "orphan" _REG method handling to also apply to GPIO address-space handlers. Note it seems that Windows always calls "orphan" _REG methods so me may want to consider dropping the space-id check and always do "orphan" _REG method handling. Link: https://github.com/acpica/acpica/commit/b9dc31e2 Signed-off-by: Hans de Goede Signed-off-by: Erik Kaneda Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evregion.c | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 738d4b231f34..a8a4c8c9b9ef 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -21,7 +21,8 @@ extern u8 acpi_gbl_default_address_spaces[]; /* Local prototypes */ static void -acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node); +acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, + acpi_adr_space_type space_id); static acpi_status acpi_ev_reg_run(acpi_handle obj_handle, @@ -684,10 +685,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL, &info, NULL); - /* Special case for EC: handle "orphan" _REG methods with no region */ - - if (space_id == ACPI_ADR_SPACE_EC) { - acpi_ev_orphan_ec_reg_method(node); + /* + * Special case for EC and GPIO: handle "orphan" _REG methods with + * no region. + */ + if (space_id == ACPI_ADR_SPACE_EC || space_id == ACPI_ADR_SPACE_GPIO) { + acpi_ev_execute_orphan_reg_method(node, space_id); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, @@ -760,31 +763,28 @@ acpi_ev_reg_run(acpi_handle obj_handle, /******************************************************************************* * - * FUNCTION: acpi_ev_orphan_ec_reg_method + * FUNCTION: acpi_ev_execute_orphan_reg_method * - * PARAMETERS: ec_device_node - Namespace node for an EC device + * PARAMETERS: device_node - Namespace node for an ACPI device + * space_id - The address space ID * * RETURN: None * - * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC + * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI * device. This is a _REG method that has no corresponding region - * within the EC device scope. The orphan _REG method appears to - * have been enabled by the description of the ECDT in the ACPI - * specification: "The availability of the region space can be - * detected by providing a _REG method object underneath the - * Embedded Controller device." - * - * To quickly access the EC device, we use the ec_device_node used - * during EC handler installation. Otherwise, we would need to - * perform a time consuming namespace walk, executing _HID - * methods to find the EC device. + * within the device's scope. ACPI tables depending on these + * "orphan" _REG methods have been seen for both EC and GPIO + * Operation Regions. Presumably the Windows ACPI implementation + * always calls the _REG method independent of the presence of + * an actual Operation Region with the correct address space ID. * * MUTEX: Assumes the namespace is locked * ******************************************************************************/ static void -acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) +acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, + acpi_adr_space_type space_id) { acpi_handle reg_method; struct acpi_namespace_node *next_node; @@ -792,9 +792,9 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) struct acpi_object_list args; union acpi_object objects[2]; - ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); + ACPI_FUNCTION_TRACE(ev_execute_orphan_reg_method); - if (!ec_device_node) { + if (!device_node) { return_VOID; } @@ -804,7 +804,7 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) /* Get a handle to a _REG method immediately under the EC device */ - status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, ®_method); + status = acpi_get_handle(device_node, METHOD_NAME__REG, ®_method); if (ACPI_FAILURE(status)) { goto exit; /* There is no _REG method present */ } @@ -816,23 +816,23 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) * with other space IDs to be present; but the code below will then * execute the _REG method with the embedded_control space_ID argument. */ - next_node = acpi_ns_get_next_node(ec_device_node, NULL); + next_node = acpi_ns_get_next_node(device_node, NULL); while (next_node) { if ((next_node->type == ACPI_TYPE_REGION) && (next_node->object) && - (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { + (next_node->object->region.space_id == space_id)) { goto exit; /* Do not execute the _REG */ } - next_node = acpi_ns_get_next_node(ec_device_node, next_node); + next_node = acpi_ns_get_next_node(device_node, next_node); } - /* Evaluate the _REG(embedded_control,Connect) method */ + /* Evaluate the _REG(space_id,Connect) method */ args.count = 2; args.pointer = objects; objects[0].type = ACPI_TYPE_INTEGER; - objects[0].integer.value = ACPI_ADR_SPACE_EC; + objects[0].integer.value = space_id; objects[1].type = ACPI_TYPE_INTEGER; objects[1].integer.value = ACPI_REG_CONNECT; -- cgit v1.2.3 From 0766efdf9a9d24eaefe260c787f49af225018b16 Mon Sep 17 00:00:00 2001 From: Erik Kaneda Date: Mon, 30 Nov 2020 11:20:46 -0800 Subject: ACPICA: Add function trace macros to improve debugging ACPICA commit 87b8dba05b4cf8c111948327023c710e2b6b5a05 The namespace repair mechanism does not have function tracing macros. Add several trace macros to improve debuggability. Link: https://github.com/acpica/acpica/commit/87b8dba0 Signed-off-by: Erik Kaneda Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nspredef.c | 10 ++++++---- drivers/acpi/acpica/nsprepkg.c | 38 ++++++++++++++++++++------------------ drivers/acpi/acpica/nsrepair2.c | 24 ++++++++++++++---------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 0cea9c363ace..167a1c2495ab 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -71,11 +71,13 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, acpi_status status; const union acpi_predefined_info *predefined; + ACPI_FUNCTION_TRACE(ns_check_return_value); + /* If not a predefined name, we cannot validate the return object */ predefined = info->predefined; if (!predefined) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -83,7 +85,7 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, * validate the return object */ if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -102,7 +104,7 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, if (acpi_gbl_disable_auto_repair || (!predefined->info.expected_btypes) || (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -163,7 +165,7 @@ exit: node->flags |= ANOBJ_EVALUATED; } - return (status); + return_ACPI_STATUS(status); } /******************************************************************************* diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index 237b3ddeb075..1875b1cba202 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c @@ -59,7 +59,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, u32 count; u32 i; - ACPI_FUNCTION_NAME(ns_check_package); + ACPI_FUNCTION_TRACE(ns_check_package); /* The package info for this name is in the next table entry */ @@ -88,14 +88,14 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, */ if (!count) { if (package->ret_info.type == ACPI_PTYPE1_VAR) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, "Return Package has no elements (empty)")); - return (AE_AML_OPERAND_VALUE); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } /* @@ -152,7 +152,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, package->ret_info. object_type1, i); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } elements++; @@ -186,7 +186,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, object_type[i], i); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } } else { /* These are the optional package elements */ @@ -198,7 +198,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, tail_object_type, i); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } } @@ -214,7 +214,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, acpi_ns_check_object_type(info, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } elements++; @@ -234,7 +234,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, acpi_ns_check_object_type(info, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } /* @@ -279,7 +279,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, acpi_ns_wrap_with_package(info, return_object, return_object_ptr); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } /* Update locals to point to the new package (of 1 element) */ @@ -316,7 +316,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, package->ret_info. object_type1, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } /* Validate length of the UUID buffer */ @@ -326,14 +326,14 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, info->full_pathname, info->node_flags, "Invalid length for UUID Buffer")); - return (AE_AML_OPERAND_VALUE); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } status = acpi_ns_check_object_type(info, elements + 1, package->ret_info. object_type2, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } elements += 2; @@ -350,10 +350,10 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, "Invalid internal return type in table entry: %X", package->ret_info.type)); - return (AE_AML_INTERNAL); + return_ACPI_STATUS(AE_AML_INTERNAL); } - return (status); + return_ACPI_STATUS(status); package_too_small: @@ -363,7 +363,7 @@ package_too_small: "Return Package is too small - found %u elements, expected %u", count, expected_count)); - return (AE_AML_OPERAND_VALUE); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } /******************************************************************************* @@ -708,6 +708,8 @@ acpi_ns_check_package_elements(struct acpi_evaluate_info *info, acpi_status status; u32 i; + ACPI_FUNCTION_TRACE(ns_check_package_elements); + /* * Up to two groups of package elements are supported by the data * structure. All elements in each group must be of the same type. @@ -717,7 +719,7 @@ acpi_ns_check_package_elements(struct acpi_evaluate_info *info, status = acpi_ns_check_object_type(info, this_element, type1, i + start_index); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } this_element++; @@ -728,11 +730,11 @@ acpi_ns_check_package_elements(struct acpi_evaluate_info *info, type2, (i + count1 + start_index)); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } this_element++; } - return (AE_OK); + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 125143c41bb8..24c197d91f29 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -155,15 +155,17 @@ acpi_ns_complex_repairs(struct acpi_evaluate_info *info, const struct acpi_repair_info *predefined; acpi_status status; + ACPI_FUNCTION_TRACE(ns_complex_repairs); + /* Check if this name is in the list of repairable names */ predefined = acpi_ns_match_complex_repair(node); if (!predefined) { - return (validate_status); + return_ACPI_STATUS(validate_status); } status = predefined->repair_function(info, return_object_ptr); - return (status); + return_ACPI_STATUS(status); } /****************************************************************************** @@ -344,17 +346,19 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, u16 original_ref_count; u32 i; + ACPI_FUNCTION_TRACE(ns_repair_CID); + /* Check for _CID as a simple string */ if (return_object->common.type == ACPI_TYPE_STRING) { status = acpi_ns_repair_HID(info, return_object_ptr); - return (status); + return_ACPI_STATUS(status); } /* Exit if not a Package */ if (return_object->common.type != ACPI_TYPE_PACKAGE) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* Examine each element of the _CID package */ @@ -366,7 +370,7 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, status = acpi_ns_repair_HID(info, element_ptr); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } if (original_element != *element_ptr) { @@ -380,7 +384,7 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, element_ptr++; } - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /****************************************************************************** @@ -500,7 +504,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, /* We only care about string _HID objects (not integers) */ if (return_object->common.type != ACPI_TYPE_STRING) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } if (return_object->string.length == 0) { @@ -511,14 +515,14 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, /* Return AE_OK anyway, let driver handle it */ info->return_flags |= ACPI_OBJECT_REPAIRED; - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* It is simplest to always create a new string object */ new_string = acpi_ut_create_string_object(return_object->string.length); if (!new_string) { - return (AE_NO_MEMORY); + return_ACPI_STATUS(AE_NO_MEMORY); } /* @@ -551,7 +555,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, acpi_ut_remove_reference(return_object); *return_object_ptr = new_string; - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /****************************************************************************** -- cgit v1.2.3 From 32cf1a12cad43358e47dac8014379c2f33dfbed4 Mon Sep 17 00:00:00 2001 From: Erik Kaneda Date: Mon, 30 Nov 2020 11:20:47 -0800 Subject: ACPICA: Interpreter: fix memory leak by using existing buffer ACPICA commit 52d1da5dcbd79a722b70f02a1a83f04088f51ff6 There was a memory leak that ocurred when a _CID object is defined as a package containing string objects. When _CID is checked for any possible repairs, it calls a helper function to repair _HID (because _CID basically contains multiple _HID entries). The _HID repair function assumes that string objects are standalone objects that are not contained inside of any packages. The _HID repair function replaces the string object with a brand new object and attempts to delete the old object by decrementing the reference count of the old object. Strings inside of packages have a reference count of 2 so the _HID repair function leaves this object in a dangling state and causes a memory leak. Instead of allocating a brand new object and removing the old object, use the existing object when repairing the _HID object. Link: https://github.com/acpica/acpica/commit/52d1da5d Signed-off-by: Erik Kaneda Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsrepair2.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 24c197d91f29..d2c8d8279e7a 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -495,9 +495,8 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, union acpi_operand_object **return_object_ptr) { union acpi_operand_object *return_object = *return_object_ptr; - union acpi_operand_object *new_string; - char *source; char *dest; + char *source; ACPI_FUNCTION_NAME(ns_repair_HID); @@ -518,13 +517,6 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, return_ACPI_STATUS(AE_OK); } - /* It is simplest to always create a new string object */ - - new_string = acpi_ut_create_string_object(return_object->string.length); - if (!new_string) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - /* * Remove a leading asterisk if present. For some unknown reason, there * are many machines in the field that contains IDs like this. @@ -534,7 +526,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, source = return_object->string.pointer; if (*source == '*') { source++; - new_string->string.length--; + return_object->string.length--; ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, "%s: Removed invalid leading asterisk\n", @@ -549,12 +541,11 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, * "NNNN####" where N is an uppercase letter or decimal digit, and * # is a hex digit. */ - for (dest = new_string->string.pointer; *source; dest++, source++) { + for (dest = return_object->string.pointer; *source; dest++, source++) { *dest = (char)toupper((int)*source); } + return_object->string.pointer[return_object->string.length] = 0; - acpi_ut_remove_reference(return_object); - *return_object_ptr = new_string; return_ACPI_STATUS(AE_OK); } -- cgit v1.2.3 From 6d5acf38183937ee31e9aafe91af4ac74b2d1907 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 30 Nov 2020 11:20:48 -0800 Subject: ACPICA: Update version to 20201113 ACPICA commit 090f0444238bd49f563bf80f4f3a863463dfdf78 Version 20201113. Link: https://github.com/acpica/acpica/commit/090f0444 Signed-off-by: Bob Moore Signed-off-by: Erik Kaneda Signed-off-by: Rafael J. Wysocki --- include/acpi/acpixf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index be7de305a622..0bba8b8c350e 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -12,7 +12,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20200925 +#define ACPI_CA_VERSION 0x20201113 #include #include -- cgit v1.2.3 From 637b9f1a1194cc671bac0039824cc472a2960b2f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 21 Nov 2020 21:30:34 +0100 Subject: ACPI: scan: Add acpi_info_matches_hids() helper acpi_device_dep_initialize() disergards _DEP "suppliers" with a _HID of "INT3396" and checks this using an acpi_device_info struct. Because in general there are other device IDs that need to be treated in the same way, add acpi_info_matches_hids() which checks a list of _HIDs for this purpose and switch acpi_device_dep_initialize() over to using it. Signed-off-by: Hans de Goede [ rjw: Changelog rewrite ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index bc6a79e33220..e949265d5667 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -719,6 +719,28 @@ int acpi_device_add(struct acpi_device *device, /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ +static bool acpi_info_matches_hids(struct acpi_device_info *info, + const char * const hids[]) +{ + int i; + + if (!(info->valid & ACPI_VALID_HID)) + return false; + + for (i = 0; hids[i]; i++) { + if (!strcmp(info->hardware_id.string, hids[i])) + return true; + } + + return false; +} + +/* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */ +static const char * const acpi_ignore_dep_hids[] = { + "INT3396", /* Windows System Power Management Controller */ + NULL +}; + static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) { struct acpi_device *device = NULL; @@ -1833,13 +1855,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) continue; } - /* - * Skip the dependency of Windows System Power - * Management Controller - */ - skip = info->valid & ACPI_VALID_HID && - !strcmp(info->hardware_id.string, "INT3396"); - + skip = acpi_info_matches_hids(info, acpi_ignore_dep_hids); kfree(info); if (skip) -- cgit v1.2.3 From 6091b2631032adafa1c8c0bd181aa5d153185c6f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 21 Nov 2020 21:30:35 +0100 Subject: ACPI: scan: Call acpi_get_object_info() from acpi_add_single_object() Call acpi_get_object_info() from acpi_add_single_object() instead of calling it from acpi_set_pnp_ids() and pass the result down to the latter so as to allow acpi_add_single_object() to use that data for other purposes. Signed-off-by: Hans de Goede [ rjw: Changelog rewrite ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/internal.h | 3 ++- drivers/acpi/power.c | 2 +- drivers/acpi/scan.c | 22 ++++++++++++---------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 43411a7457cd..68f79e3fdb98 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -105,7 +105,8 @@ struct acpi_device_bus_id { int acpi_device_add(struct acpi_device *device, void (*release)(struct device *)); void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, - int type, unsigned long long sta); + int type, unsigned long long sta, + struct acpi_device_info *info); int acpi_device_setup_files(struct acpi_device *dev); void acpi_device_remove_files(struct acpi_device *dev); void acpi_device_add_finalize(struct acpi_device *device); diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 837b875d075e..228b0af3fcc6 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -939,7 +939,7 @@ int acpi_add_power_resource(acpi_handle handle) device = &resource->device; acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER, - ACPI_STA_DEFAULT); + ACPI_STA_DEFAULT, NULL); mutex_init(&resource->resource_lock); INIT_LIST_HEAD(&resource->list_node); INIT_LIST_HEAD(&resource->dependents); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e949265d5667..25a46ae24229 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1258,10 +1258,8 @@ static bool acpi_object_is_system_bus(acpi_handle handle) } static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, - int device_type) + int device_type, struct acpi_device_info *info) { - acpi_status status; - struct acpi_device_info *info; struct acpi_pnp_device_id_list *cid_list; int i; @@ -1272,8 +1270,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, break; } - status = acpi_get_object_info(handle, &info); - if (ACPI_FAILURE(status)) { + if (!info) { pr_err(PREFIX "%s: Error reading device info\n", __func__); return; @@ -1298,8 +1295,6 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, if (info->valid & ACPI_VALID_CLS) acpi_add_id(pnp, info->class_code.string); - kfree(info); - /* * Some devices don't reliably have _HIDs & _CIDs, so add * synthetic HIDs to make sure drivers can find them. @@ -1605,7 +1600,8 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) } void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, - int type, unsigned long long sta) + int type, unsigned long long sta, + struct acpi_device_info *info) { INIT_LIST_HEAD(&device->pnp.ids); device->device_type = type; @@ -1614,7 +1610,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, device->fwnode.ops = &acpi_device_fwnode_ops; acpi_set_device_status(device, sta); acpi_device_get_busid(device); - acpi_set_pnp_ids(handle, &device->pnp, type); + acpi_set_pnp_ids(handle, &device->pnp, type, info); acpi_init_properties(device); acpi_bus_get_flags(device); device->flags.match_driver = false; @@ -1642,14 +1638,20 @@ static int acpi_add_single_object(struct acpi_device **child, int result; struct acpi_device *device; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_device_info *info = NULL; + + if (handle != ACPI_ROOT_OBJECT && type == ACPI_BUS_TYPE_DEVICE) + acpi_get_object_info(handle, &info); device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); if (!device) { printk(KERN_ERR PREFIX "Memory allocation error\n"); + kfree(info); return -ENOMEM; } - acpi_init_device_object(device, handle, type, sta); + acpi_init_device_object(device, handle, type, sta, info); + kfree(info); /* * For ACPI_BUS_TYPE_DEVICE getting the status is delayed till here so * that we can call acpi_bus_get_status() and use its quirk handling. -- cgit v1.2.3 From 2ef33ee7f4f68d77b852bb2c946fc2f8f136a3c1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 5 Dec 2020 16:29:41 +0100 Subject: ACPI: scan: Add PNP0D80 to the _DEP exceptions list The PNP0D80 ("Windows-compatible System Power Management Controller") device ID is used for identifying the special device object providing the LPI (Low-power S0 Idle) _DSM interface [1]. That device object does not supply any operation regions, but it appears in _DEP lists for other devices in the ACPI tables on some systems to enforce specific enumeration ordering that does not matter for Linux. For this reason, _DEP list entries pointing to the device object whose _CID returns PNP0D80 need not be taken into account as real operation region dependencies, so add that device ID to the list of device IDs for which the matching _DEP list entries should be ignored. Accordingly, update the function used for matching device IDs in that list to allow it to check _CID as well as _HID and rename it to acpi_info_matches_ids(). Link: https://www.uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf # [1] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 25a46ae24229..b44b2d6b6b22 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -719,25 +719,40 @@ int acpi_device_add(struct acpi_device *device, /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ -static bool acpi_info_matches_hids(struct acpi_device_info *info, - const char * const hids[]) +static bool acpi_info_matches_ids(struct acpi_device_info *info, + const char * const ids[]) { + struct acpi_pnp_device_id_list *cid_list = NULL; int i; if (!(info->valid & ACPI_VALID_HID)) return false; - for (i = 0; hids[i]; i++) { - if (!strcmp(info->hardware_id.string, hids[i])) + if (info->valid & ACPI_VALID_CID) + cid_list = &info->compatible_id_list; + + for (i = 0; ids[i]; i++) { + int j; + + if (!strcmp(info->hardware_id.string, ids[i])) return true; + + if (!cid_list) + continue; + + for (j = 0; j < cid_list->count; j++) { + if (!strcmp(cid_list->ids[j].string, ids[i])) + return true; + } } return false; } /* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */ -static const char * const acpi_ignore_dep_hids[] = { +static const char * const acpi_ignore_dep_ids[] = { "INT3396", /* Windows System Power Management Controller */ + "PNP0D80", /* Windows-compatible System Power Management Controller */ NULL }; @@ -1857,7 +1872,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) continue; } - skip = acpi_info_matches_hids(info, acpi_ignore_dep_hids); + skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids); kfree(info); if (skip) -- cgit v1.2.3 From 12fc4dad94dfac25599f31257aac181c691ca96f Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Sat, 5 Dec 2020 17:04:03 +0000 Subject: Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources walks" This reverts commit 8a66790b7850a6669129af078768a1d42076a0ef. Switching this function to AE_CTRL_TERMINATE broke the documented behaviour of acpi_dev_get_resources() - AE_CTRL_TERMINATE does not, in fact, terminate the resource walk because acpi_walk_resource_buffer() ignores it (specifically converting it to AE_OK), referring to that value as "an OK termination by the user function". This means that acpi_dev_get_resources() does not abort processing when the preproc function returns a negative value. Signed-off-by: Daniel Scally Cc: 3.10+ # 3.10+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index ad04824ca3ba..f2f5f1dc7c61 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -541,7 +541,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, ret = c->preproc(ares, c->preproc_data); if (ret < 0) { c->error = ret; - return AE_CTRL_TERMINATE; + return AE_ABORT_METHOD; } else if (ret > 0) { return AE_OK; } -- cgit v1.2.3 From 25417185e9b5ff90746d50769d2a3fcd1629e254 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Dec 2020 14:39:42 +0800 Subject: ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807 The GIGABYTE GB-BXBT-2807 is a mini-PC which uses off the shelf components, like an Intel GPU which is meant for mobile systems. As such, it, by default, has a backlight controller exposed. Unfortunately, the backlight controller only confuses userspace, which sees the existence of a backlight device node and has the unrealistic belief that there is actually a backlight there! Add a DMI quirk to force the backlight off on this system. Signed-off-by: Jasper St. Pierre Reviewed-by: Chris Chiu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 4f5463b2a217..811d298637cb 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -140,6 +140,13 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, + .ident = "GIGABYTE GB-BXBT-2807", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), + }, + }, + { .ident = "Sony VPCEH3U1E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), -- cgit v1.2.3 From b36b1e9db41fcff860624ece91c71b62f2ad6754 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Dec 2020 17:55:11 +0100 Subject: ACPI: scan: Drop INT3396 from acpi_ignore_dep_ids[] According to Hans, all device objects where the _HID returns "INT3396" also have a _CID returning "PNP0D80", so the former need not be present in acpi_ignore_dep_ids[] any more. Link: https://lore.kernel.org/linux-acpi/52a2b98c-6bf3-760b-eca9-93cf05fb4877@redhat.com/ Suggested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Acked-by: Hans de Goede --- drivers/acpi/scan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b44b2d6b6b22..560385e35d3d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -751,7 +751,6 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info, /* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */ static const char * const acpi_ignore_dep_ids[] = { - "INT3396", /* Windows System Power Management Controller */ "PNP0D80", /* Windows-compatible System Power Management Controller */ NULL }; -- cgit v1.2.3 From 91438aebcd56ed3cfa480e4546c7b06e9db3c73c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Dec 2020 18:46:06 +0100 Subject: ACPI: scan: Fix up _DEP-related terminology with supplier/consumer The ACPI namespace scanning code uses the terms master/slave when populating the list of _DEP dependencies, but that use has no external exposures and is not mandated by nor associated with any external specifications. Change the language used through-out to supplier/consumer. No functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hans de Goede --- drivers/acpi/scan.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 560385e35d3d..37317e0ed65d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -51,8 +51,8 @@ static u64 spcr_uart_addr; struct acpi_dep_data { struct list_head node; - acpi_handle master; - acpi_handle slave; + acpi_handle supplier; + acpi_handle consumer; }; void acpi_scan_lock_acquire(void) @@ -1881,8 +1881,8 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) if (!dep) return; - dep->master = dep_devices.handles[i]; - dep->slave = adev->handle; + dep->supplier = dep_devices.handles[i]; + dep->consumer = adev->handle; adev->dep_unmet++; mutex_lock(&acpi_dep_list_lock); @@ -2058,8 +2058,8 @@ void acpi_walk_dep_device_list(acpi_handle handle) mutex_lock(&acpi_dep_list_lock); list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { - if (dep->master == handle) { - acpi_bus_get_device(dep->slave, &adev); + if (dep->supplier == handle) { + acpi_bus_get_device(dep->consumer, &adev); if (!adev) continue; -- cgit v1.2.3