Commit 5e2cde03 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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
+154 −0
Original line number Diff line number Diff line
@@ -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
+55 −1
Original line number Diff line number Diff line
@@ -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",
+1 −5
Original line number Diff line number Diff line
@@ -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;
			}
+1 −3
Original line number Diff line number Diff line
@@ -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;
Loading