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 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 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 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