mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
Merge branches 'acpi-resources' and 'acpi-docs'
* acpi-resources: Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources walks" resource: provide meaningful MODULE_LICENSE() in test suite ASoC: Intel: catpt: Replace open coded variant of resource_intersection() ACPI: watchdog: Replace open coded variant of resource_union() PCI/ACPI: Replace open coded variant of resource_union() resource: Add test cases for new resource API resource: Introduce resource_intersection() for overlapping resources resource: Introduce resource_union() for overlapping resources resource: Group resource_overlaps() with other inline helpers resource: Simplify region_intersects() by reducing conditionals * acpi-docs: Documentation: ACPI: enumeration: add PCI hierarchy representation Documentation: ACPI: _DSD: enable hyperlink in final references Documentation: ACPI: explain how to use gpio-line-names
This commit is contained in:
commit
5e2cde03da
@ -90,10 +90,10 @@ where
|
||||
References
|
||||
==========
|
||||
|
||||
[1] Device tree. <URL:https://www.devicetree.org>, referenced 2019-02-21.
|
||||
[1] Device tree. https://www.devicetree.org, referenced 2019-02-21.
|
||||
|
||||
[2] Advanced Configuration and Power Interface Specification.
|
||||
<URL:https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf>,
|
||||
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.
|
||||
<URL:https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>,
|
||||
https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf,
|
||||
referenced 2019-02-21.
|
||||
|
||||
[6] Hierarchical Data Extension UUID For _DSD.
|
||||
<URL:https://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>,
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -10,9 +10,10 @@
|
||||
#define _LINUX_IOPORT_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/types.h>
|
||||
/*
|
||||
* Resources are tree-like, allowing
|
||||
* nesting etc..
|
||||
@ -229,6 +230,31 @@ 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -296,12 +322,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,
|
||||
|
@ -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)
|
||||
|
@ -557,13 +557,13 @@ int region_intersects(resource_size_t start, size_t size, unsigned long flags,
|
||||
}
|
||||
read_unlock(&resource_lock);
|
||||
|
||||
if (type == 0)
|
||||
return REGION_DISJOINT;
|
||||
|
||||
if (other == 0)
|
||||
return type ? REGION_INTERSECTS : REGION_DISJOINT;
|
||||
return REGION_INTERSECTS;
|
||||
|
||||
if (type)
|
||||
return REGION_MIXED;
|
||||
|
||||
return REGION_DISJOINT;
|
||||
return REGION_MIXED;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(region_intersects);
|
||||
|
||||
|
152
kernel/resource_kunit.c
Normal file
152
kernel/resource_kunit.c
Normal file
@ -0,0 +1,152 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test cases for API provided by resource.c and ioport.h
|
||||
*/
|
||||
|
||||
#include <kunit/test.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#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);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user