Sie sind auf Seite 1von 13

ACPI Enumeration

Application Note

July 2018

Document Number: 598506-0.5


You may not use or facilitate the use of this document in connection with any infringement or other legal analysis concerning Intel products
described herein. You agree to grant Intel a non-exclusive, royalty-free license to any patent claim thereafter drafted which includes subject
matter disclosed herein

No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this document.

All information provided here is subject to change without notice. Contact your Intel representative to obtain the latest Intel product
specifications and roadmaps.

The products described may contain design defects or errors known as errata, which may cause the product to deviate from published
specifications. Current characterized errata are available on request.

Copies of documents, which have an order number and are referenced in this document may be obtained by calling 1-800-548-4725 or by
visiting: http://www.intel.com/design/literature.htm

Intel technologies’ features and benefits depend on system configuration and may require enabled hardware, software, or service activation. Learn
more at h ttp://www.intel.com/ or from the OEM or retailer.

Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.

*Other names and brands may be claimed as the property of others.

Copyright© 2018, Intel Corporation. All rights reserved.

ACPI Enumeration
Application Note July 2018
2 Document Number: 598506-0.5
Contents
1.0 Introduction ...............................................................................................................................................................5
2.0 Create the Device ACPI Table..................................................................................................................................6
2.1 Definition Block .............................................................................................................................................6
2.2 External and Scope .......................................................................................................................................6
2.3 Device Definition ...........................................................................................................................................8
2.3.1 _CRS: Current Resource Settings ................................................................................................8
2.3.2 _DSD: Device Specific Data ....................................................................................................... 10
3.0 Create the Device Driver ....................................................................................................................................... 11
3.1 Create and Register a SPI Driver ............................................................................................................. 11
3.2 Access the Device Resources from the Probe Function ..................................................................... 11
4.0 Verification Tips ...................................................................................................................................................... 13

ACPI Enumeration
July 2018 Application Note
Document Number: 598506-0.5 3
Revision History

Date Revision Description

July 2018 0.5 Initial release

Terminology
Term Descripti
on
ACPI Advanced Configuration and Power Interface

DSDT Differentiated System Description Table Fields

GPIO General Purpose Input Output

I2C Inter-Integrated Circuit

SPI Serial Peripheral Interface

SSDT Secondary System Description Table Fields

_ADR Address

_CID Compatible ID

_CRS Current Resource Settings

_DSD Device Specific Data

_HID Hardware ID

Relevant Documents
Document Description

ACPI 5.1 Advanced Configuration and Power Interface Specification

acpi/enumeration.txt Linux Kernel ACPI Enumeration Documentation

acpi/gpio-properties.txt Linux Kernel ACPI properties and GPIO Documentation

gpio/consumer.txt Linux Kernel GPIO Descriptor Consumer Interface

ACPI Enumeration
Application Note July 2018
4 Document Number: 598506-0.5
1.0 Introduction
This Application Note walks through the ACPI 5.1 (Advanced Configuration and Power
Interface) specification and the basics of the Linux driver ACPI enumeration and
property access. The Linux driver section is taken from the Linux Kernel ACPI
Enumeration documentation.

This document walks through the details of defining the JMM device that is connected
to a non-enumerable bus. In example used in this document, the JMM device is
connected to the third SPI (Serial Peripheral Interface) bus connected to the root PCI
bus. This example can easily be translated to other non-enumerable buses like I2C
(Inter-Integrated Circuit).

The purpose of this document is to walk through the documentation and create a
working ACPI table and Linux driver. This document does not go into detail. Instead, it
provide links to publicly available documentation that the reader should visit.

This document includes two additional files (see the PDF reader attachment menu):
• JMM00001.asl – The working example of the SSDT ACPI table
• jmm.c – The working example of a SPI driver, which supports the JMM device.

ACPI Enumeration
July 2018 Application Note
Document Number: 598506-0.5 5
2.0 Create the Device ACPI Table
This section walks through the different parts of the JMM0001.asl file.

2.1 Definition Block


The DefinitionBlock parameters are:
• AMLFileName – This is the name of the generated file when the ACPI compiler is
passed this source file as parameter. The ACPI iasl compiler is available at
ACPICA.org.
• TableSignature – Should be "SSDT" (Secondary System Description Table Fields)
as the goal is to declare a device that has not been declared as part of the DSDT
(Differentiated System Description Table) ACPI table.
• ComplianceRevision – Should be 2 to allow the use of 64-bit integers.
• OEMID is a six-character string defining the name of the OEM who designed this
ACPI table.
• TableID is an eight-character string defining the name of the table. It is normally
OEM specific.
• OEMRevision is the revision of that table.
Listing 1. DefinitionBlock Example
DefinitionBlock ("JMM00001.aml", "SSDT", 2, "INTEL ", "JMM00001", 1)
{
[...]
}

The JMM example device definition should be enclosed in the DefinitionBlock


brackets.

2.2 External and Scope


The ACPI Namespaces is organized hierarchically, cf. Figure 5-30 Example ACPI
NameSpace. The declaration of that tree does not need to be expressed in a single ACPI
table and it is possible to reference any node from another node.

The JMM example device is connected to the third SPI bus connected to the root PCI
bus. Usually the root PCI bus is named PCI0 and its parent is _SB (System Bus).
Consult the DSDT ACPI table of the system to verify what is the right path to the non-
enumerable bus on which the device is connected. For instance, on an Intel Apollo
Lake SoC:
Listing 2. Decompile the DSDT Table
# Generate the DSDT.dsl file
▶ iasl -d /sys/firmware/acpi/tables/DSDT

ACPI Enumeration
Application Note July 2018
6 Document Number: 598506-0.5
Listing 3. Extract from the Apollo Lake DSDT.dsl

[...]
Scope (\_SB.PCI0)
{
[...]
Device (SPI3)
{
Name (_ADR, 0x00190002)
Name (_DDN, "Intel(R) SPI Controller #3")
Name (_UID, 0x03)
Name (RBUF, ResourceTemplate ()
{
})
Method (_CRS, 0, NotSerialized)
{
Return (RBUF)
}
}
[...]

Device(SPI3) is an SPI controller within APL SoC with PCI bus 0, device number
0x19, and function number 2. The Linux kernel links this device namespace to the
actual PCI device 19.2 at PCI enumeration.
Listing 4. ACPI Namespace Tree with the JMM Device

ACPI Enumeration
July 2018 Application Note
Document Number: 598506-0.5 7
Listing 5. ACPI Namespace Tree with the JMM Device External and Scope Example

[...]
External (\_SB.PCI0.SPI3, DeviceObj)
Scope (\_SB.PCI0.SPI3)
{
[...]
}
[...]

The JMM device definition has to be inside the _SB.PCI0.SPI3 Namespace.

2.3 Device Definition


The unique Device parameter is the name of the device. It is usually 3 to 4 characters
long.

The common Device fields are:


• _ADR (Address) is the device's address on its parent bus.
• _HID (Hardware ID) is the Plug and Play Hardware ID or ACPI ID - should be
specified by the vendor or OEM.
• _CID (Compatible ID) is the device's Plug and Play-compatible ID list - should be
specified by the vendor or OEM.

_HID is the only required field. _ADR is necessary:


1. If more than one device is connected to the same parent – the parent being
_SB.PCI0.SPI3 in this example.
2. The device is on a bus that has a standard enumeration.
Listing 6. Device Header Example - Use JMM00001 as the JMM Hardware ID
[...]
Device (JMM)
{
Name (_HID, "JMM00001")
[...]
}
[...]

2.3.1 _CRS: Current Resource Settings

The _CRS Method is either an object that specifies the device's current resource
settings, or a control method that generates such an object. The purpose of this
method is to return a list of hardware resources used by the driver.
In our example, this is a control method that returns a ResourceTemplate object
containing two GpioIo objects, and a SPISerialBus object. See acpi/enumeration.txt
Linux Kernel Documentation for more details. For GPIO meant to be used as interrupt,
see GpioInt and gpio/consumer.txt - GPIOs mapped to IRQs.

ACPI Enumeration
Application Note July 2018
8 Document Number: 598506-0.5
Listing 7. JMM Device _CRS Example Method

[...]
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
/* GPIO 24 of the North Community. */
GpioIo (Exclusive, PullDown, 0, 0,
IoRestrictionOutputOnly,
"\\_SB.GPO0", 0, ResourceConsumer)
{
24
}
/* GPIO 74 of the Northwest Community. */
GpioIo (Exclusive, PullDown, 0, 0,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0, ResourceConsumer)
{
74
}
SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
ControllerInitiated, 0x000F4240,
ClockPolarityLow, ClockPhaseFirst,
"\\_SB.PCI0.SPI3", 0x00, ResourceConsumer)
})
Return (RBUF)
}
[...]

Consult the DSDT ACPI table of the system to verify the correct ACPI namespace path
for the GPIO community of the GPIO wired to the device. For example, the following
extract shows that the Northwest community GPIO ACPI namespace path is
_SB.GPO1.
Listing 8. Extract from the Apollo Lake DSDT.dsl
[...]
Scope (_SB)
{
[...]
Device (GPO1)
{
Name (_ADR, Zero)
Name (_HID, "INT3452")
Name (_CID, "INT3452")
Name (_DDN, "General Purpose Input/Output (GPIO) Controller -
Northwest")
Name (_UID, 0x02)
[...]

ACPI Enumeration
July 2018 Application Note
Document Number: 598506-0.5 9
2.3.2 _DSD: Device Specific Data

The _DSD (Device Specific Data) is a variable length Package of "Device Data
Descriptor". A "Device Data Descriptor" consists of a UUID and a variable length
Package of Data Structure. The daffd814-6eba-4d8c-8a91-bc9bbf4aa301 UUID is
used to identify Device Properties, which consist of:
1. A key, which should a unique string
2. A value associated with that key

The following example declares:


1. Two GPIO references (reset-gpio and power-gpio keys)
2. One integer value (int key)
3. One string value (string key)
4. An array of four integers (array_of_int key)
Listing 9. JMM Device _DSD Example Method
[...]
Name (_DSD, Package ()
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package () { "reset-gpio",
Package() {^JMM, 0, 0, 0 }
},
Package () { "power-gpio",
Package() {^JMM, 1, 0, 0 }
},
Package () { "int", 16 },
Package () { "string", "example string" },
Package () { "array_of_int", Package() { 1, 2, 3, 4 } }
}
})
[...]

Note:
1. The GPIO name should be suffixed with -gpio in the ACPI table. From the driver side,
gpiod_get() like functions use the name of the GPIO without the -gpio suffix.
2. The format of the supported GPIO property is:
Package () { "name", Package () { ref, index, pin, active_low }}

• ref – The device that has _CRS containing GpioIo()/GpioInt() resources,


typically the device itself.
• index – Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
• pin – Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
• active_low – If 1 the GPIO is marked as active_low.
For more details on GPIO declaration, consult acpi/gpio-properties.txt - _DSD
Device Properties Related to GPIO.

ACPI Enumeration
Application Note July 2018
10 Document Number: 598506-0.5
3.0 Create the Device Driver
This section walks through the attached example jmm.c.

3.1 Create and Register a SPI Driver


We declare the list of ACPI IDs that our driver supports in a jmm_acpi_ids[] array of ID
and optional driver data. Currently we only support "JMM00001".

Then declare our driver "hook" data structure where we bind altogether the name of
our driver, the array of supported IDs, and the probe and the remove functions,
which are called by the Linux kernel when a matching device is found or when a
matching device is removed from the system.
Listing 10. Driver Declaration for "JMM00001" Devices
static const struct acpi_device_id jmm_acpi_ids[] = {
{ "JMM00001", 0 }
};
MODULE_DEVICE_TABLE(acpi, jmm_acpi_ids);

static struct spi_driver jmm_driver = {


.driver = {
.name = "jmm",
.acpi_match_table = ACPI_PTR(jmm_acpi_ids),
},
.probe = jmm_probe,
.remove = jmm_remove,
};

module_spi_driver(jmm_driver);

MODULE_DESCRIPTION("Driver for JMM device");


MODULE_AUTHOR("Jeremy Compostella");
MODULE_LICENSE("GPL");

3.2 Access the Device Resources from the Probe Function


For information regarding how to consume GPIOs, see gpio/consumer.txt -
GPIO Descriptor Consumer Interface.

As an example, the following function is accessing the data provided by the _DSD
object:
1. The power and reset gpios
2. The int property as a uint32_t
3. The string property as a char *
4. The array_of_int property as a uint32_t []

ACPI Enumeration
July 2018 Application Note
Document Number: 598506-0.5 11
Listing 11. GPIO and Properties

static int jmm_probe(struct spi_device *spi)


{
struct gpio_desc *power, *reset;
u32 int_val, int_array[4];
char *string_val;
int ret;
size_t i;

power = devm_gpiod_get(&spi->dev, "power", GPIOD_ASIS);


if (IS_ERR(power)) {
dev_err(spi, "Could not get the 'power' GPIO, %d\n",
PTR_ERR(power));
return -EINVAL;
}

reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_ASIS);


if (IS_ERR(reset)) {
dev_err(&spi->dev, "Could not get the 'reset' GPIO, %d\n",
PTR_ERR(reset));
return -EINVAL;
}

ret = device_property_read_u32(&spi->dev, "int", &int_val);


if (ret == 0)
dev_info(&spi->dev, "read %d 'int' property", int_val);

ret = device_property_read_string(&spi->dev, "string",


&string_val);
if (ret == 0)
dev_info(&spi->dev, "read %s 'string' property",
string_val);

ret = device_property_read_u32_array(&spi->dev, "array_of_int",


&int_array, 4);
if (ret == 0) {
dev_info(&spi->dev, "array_of_int[] = {");
for (i = 0; i < ARRAY_SIZE(int_array); i++)
dev_info(&spi->dev, " %d,", int_array[i]);
dev_info(&spi->dev, "}\n");
}

return 0;
}

ACPI Enumeration
Application Note July 2018
12 Document Number: 598506-0.5
4.0 Verification Tips
The Linux sysfs is a great source of information regarding device enumeration drivers.
Listing 12. Device Is Enumerated Through ACPI
▶ ls /sys/bus/acpi/devices/ | grep JMM
JMM00001:00

Listing 13. This Is an SPI Device


▶ ls /sys/bus/spi/devices/ | grep JMM
spi-JMM00001:00

Listing 14. The jmm Driver Is Loaded


▶ ls /sys/bus/spi/drivers | grep jmm
jmm

Listing 15. The pxa2xx spi Master and jmm Driver Are Linked
▶ find /sys/devices/pci0000:00 -name *JMM*
/sys/devices/pci0000:00/0000:00:19.2/pxa2xx-spi.5/spi_master/spi3/spi-
JMM00001:00

Listing 16. Driver Initialization Information


▶ dmesg | grep jmm
[ 0.297136] jmm spi-JMM00001:00: read 16 'int' property
[ 0.297143] jmm spi-JMM00001:00: read example string 'string'
property
[ 0.297147] jmm spi-JMM00001:00: array_of_int[] = {
[ 0.297150] jmm spi-JMM00001:00: 1,
[ 0.297153] jmm spi-JMM00001:00: 2,
[ 0.297155] jmm spi-JMM00001:00: 3,
[ 0.297158] jmm spi-JMM00001:00: 4,
[ 0.297161] jmm spi-JMM00001:00: }

ACPI Enumeration
July 2018 Application Note
Document Number: 598506-0.5 13

Das könnte Ihnen auch gefallen