+++ /dev/null
-ACPI based device enumeration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-ACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus,
-SpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave
-devices behind serial bus controllers.
-
-In addition we are starting to see peripherals integrated in the
-SoC/Chipset to appear only in ACPI namespace. These are typically devices
-that are accessed through memory-mapped registers.
-
-In order to support this and re-use the existing drivers as much as
-possible we decided to do following:
-
- o Devices that have no bus connector resource are represented as
- platform devices.
-
- o Devices behind real busses where there is a connector resource
- are represented as struct spi_device or struct i2c_device
- (standard UARTs are not busses so there is no struct uart_device).
-
-As both ACPI and Device Tree represent a tree of devices (and their
-resources) this implementation follows the Device Tree way as much as
-possible.
-
-The ACPI implementation enumerates devices behind busses (platform, SPI and
-I2C), creates the physical devices and binds them to their ACPI handle in
-the ACPI namespace.
-
-This means that when ACPI_HANDLE(dev) returns non-NULL the device was
-enumerated from ACPI namespace. This handle can be used to extract other
-device-specific configuration. There is an example of this below.
-
-Platform bus support
-~~~~~~~~~~~~~~~~~~~~
-Since we are using platform devices to represent devices that are not
-connected to any physical bus we only need to implement a platform driver
-for the device and add supported ACPI IDs. If this same IP-block is used on
-some other non-ACPI platform, the driver might work out of the box or needs
-some minor changes.
-
-Adding ACPI support for an existing driver should be pretty
-straightforward. Here is the simplest example:
-
- #ifdef CONFIG_ACPI
- static const struct acpi_device_id mydrv_acpi_match[] = {
- /* ACPI IDs here */
- { }
- };
- MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match);
- #endif
-
- static struct platform_driver my_driver = {
- ...
- .driver = {
- .acpi_match_table = ACPI_PTR(mydrv_acpi_match),
- },
- };
-
-If the driver needs to perform more complex initialization like getting and
-configuring GPIOs it can get its ACPI handle and extract this information
-from ACPI tables.
-
-DMA support
-~~~~~~~~~~~
-DMA controllers enumerated via ACPI should be registered in the system to
-provide generic access to their resources. For example, a driver that would
-like to be accessible to slave devices via generic API call
-dma_request_slave_channel() must register itself at the end of the probe
-function like this:
-
- err = devm_acpi_dma_controller_register(dev, xlate_func, dw);
- /* Handle the error if it's not a case of !CONFIG_ACPI */
-
-and implement custom xlate function if needed (usually acpi_dma_simple_xlate()
-is enough) which converts the FixedDMA resource provided by struct
-acpi_dma_spec into the corresponding DMA channel. A piece of code for that case
-could look like:
-
- #ifdef CONFIG_ACPI
- struct filter_args {
- /* Provide necessary information for the filter_func */
- ...
- };
-
- static bool filter_func(struct dma_chan *chan, void *param)
- {
- /* Choose the proper channel */
- ...
- }
-
- static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec,
- struct acpi_dma *adma)
- {
- dma_cap_mask_t cap;
- struct filter_args args;
-
- /* Prepare arguments for filter_func */
- ...
- return dma_request_channel(cap, filter_func, &args);
- }
- #else
- static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec,
- struct acpi_dma *adma)
- {
- return NULL;
- }
- #endif
-
-dma_request_slave_channel() will call xlate_func() for each registered DMA
-controller. In the xlate function the proper channel must be chosen based on
-information in struct acpi_dma_spec and the properties of the controller
-provided by struct acpi_dma.
-
-Clients must call dma_request_slave_channel() with the string parameter that
-corresponds to a specific FixedDMA resource. By default "tx" means the first
-entry of the FixedDMA resource array, "rx" means the second entry. The table
-below shows a layout:
-
- Device (I2C0)
- {
- ...
- Method (_CRS, 0, NotSerialized)
- {
- Name (DBUF, ResourceTemplate ()
- {
- FixedDMA (0x0018, 0x0004, Width32bit, _Y48)
- FixedDMA (0x0019, 0x0005, Width32bit, )
- })
- ...
- }
- }
-
-So, the FixedDMA with request line 0x0018 is "tx" and next one is "rx" in
-this example.
-
-In robust cases the client unfortunately needs to call
-acpi_dma_request_slave_chan_by_index() directly and therefore choose the
-specific FixedDMA resource by its index.
-
-SPI serial bus support
-~~~~~~~~~~~~~~~~~~~~~~
-Slave devices behind SPI bus have SpiSerialBus resource attached to them.
-This is extracted automatically by the SPI core and the slave devices are
-enumerated once spi_register_master() is called by the bus driver.
-
-Here is what the ACPI namespace for a SPI slave might look like:
-
- Device (EEP0)
- {
- Name (_ADR, 1)
- Name (_CID, Package() {
- "ATML0025",
- "AT25",
- })
- ...
- Method (_CRS, 0, NotSerialized)
- {
- SPISerialBus(1, PolarityLow, FourWireMode, 8,
- ControllerInitiated, 1000000, ClockPolarityLow,
- ClockPhaseFirst, "\\_SB.PCI0.SPI1",)
- }
- ...
-
-The SPI device drivers only need to add ACPI IDs in a similar way than with
-the platform device drivers. Below is an example where we add ACPI support
-to at25 SPI eeprom driver (this is meant for the above ACPI snippet):
-
- #ifdef CONFIG_ACPI
- static const struct acpi_device_id at25_acpi_match[] = {
- { "AT25", 0 },
- { },
- };
- MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
- #endif
-
- static struct spi_driver at25_driver = {
- .driver = {
- ...
- .acpi_match_table = ACPI_PTR(at25_acpi_match),
- },
- };
-
-Note that this driver actually needs more information like page size of the
-eeprom etc. but at the time writing this there is no standard way of
-passing those. One idea is to return this in _DSM method like:
-
- Device (EEP0)
- {
- ...
- Method (_DSM, 4, NotSerialized)
- {
- Store (Package (6)
- {
- "byte-len", 1024,
- "addr-mode", 2,
- "page-size, 32
- }, Local0)
-
- // Check UUIDs etc.
-
- Return (Local0)
- }
-
-Then the at25 SPI driver can get this configuration by calling _DSM on its
-ACPI handle like:
-
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_object_list input;
- acpi_status status;
-
- /* Fill in the input buffer */
-
- status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "_DSM",
- &input, &output);
- if (ACPI_FAILURE(status))
- /* Handle the error */
-
- /* Extract the data here */
-
- kfree(output.pointer);
-
-I2C serial bus support
-~~~~~~~~~~~~~~~~~~~~~~
-The slaves behind I2C bus controller only need to add the ACPI IDs like
-with the platform and SPI drivers. The I2C core automatically enumerates
-any slave devices behind the controller device once the adapter is
-registered.
-
-Below is an example of how to add ACPI support to the existing mpu3050
-input driver:
-
- #ifdef CONFIG_ACPI
- static const struct acpi_device_id mpu3050_acpi_match[] = {
- { "MPU3050", 0 },
- { },
- };
- MODULE_DEVICE_TABLE(acpi, mpu3050_acpi_match);
- #endif
-
- static struct i2c_driver mpu3050_i2c_driver = {
- .driver = {
- .name = "mpu3050",
- .owner = THIS_MODULE,
- .pm = &mpu3050_pm,
- .of_match_table = mpu3050_of_match,
- .acpi_match_table = ACPI_PTR(mpu3050_acpi_match),
- },
- .probe = mpu3050_probe,
- .remove = mpu3050_remove,
- .id_table = mpu3050_ids,
- };
-
-GPIO support
-~~~~~~~~~~~~
-ACPI 5 introduced two new resources to describe GPIO connections: GpioIo
-and GpioInt. These resources can be used to pass GPIO numbers used by
-the device to the driver. ACPI 5.1 extended this with _DSD (Device
-Specific Data) which made it possible to name the GPIOs among other things.
-
-For example:
-
-Device (DEV)
-{
- Method (_CRS, 0, NotSerialized)
- {
- Name (SBUF, ResourceTemplate()
- {
- ...
- // Used to power on/off the device
- GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
- IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
- 0x00, ResourceConsumer,,)
- {
- // Pin List
- 0x0055
- }
-
- // Interrupt for the device
- GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone,
- 0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
- {
- // Pin list
- 0x0058
- }
-
- ...
-
- }
-
- Return (SBUF)
- }
-
- // ACPI 5.1 _DSD used for naming the GPIOs
- Name (_DSD, Package ()
- {
- ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
- Package ()
- {
- Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }},
- Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }},
- }
- })
- ...
-
-These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
-specifies the path to the controller. In order to use these GPIOs in Linux
-we need to translate them to the corresponding Linux GPIO descriptors.
-
-There is a standard GPIO API for that and is documented in
-Documentation/gpio/.
-
-In the above example we can get the corresponding two GPIO descriptors with
-a code like this:
-
- #include <linux/gpio/consumer.h>
- ...
-
- struct gpio_desc *irq_desc, *power_desc;
-
- irq_desc = gpiod_get(dev, "irq");
- if (IS_ERR(irq_desc))
- /* handle error */
-
- power_desc = gpiod_get(dev, "power");
- if (IS_ERR(power_desc))
- /* handle error */
-
- /* Now we can use the GPIO descriptors */
-
-There are also devm_* versions of these functions which release the
-descriptors once the device is released.
-
-See Documentation/acpi/gpio-properties.txt for more information about the
-_DSD binding related to GPIOs.
-
-MFD devices
-~~~~~~~~~~~
-The MFD devices register their children as platform devices. For the child
-devices there needs to be an ACPI handle that they can use to reference
-parts of the ACPI namespace that relate to them. In the Linux MFD subsystem
-we provide two ways:
-
- o The children share the parent ACPI handle.
- o The MFD cell can specify the ACPI id of the device.
-
-For the first case, the MFD drivers do not need to do anything. The
-resulting child platform device will have its ACPI_COMPANION() set to point
-to the parent device.
-
-If the ACPI namespace has a device that we can match using an ACPI id or ACPI
-adr, the cell should be set like:
-
- static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
- .pnpid = "XYZ0001",
- .adr = 0,
- };
-
- static struct mfd_cell my_subdevice_cell = {
- .name = "my_subdevice",
- /* set the resources relative to the parent */
- .acpi_match = &my_subdevice_cell_acpi_match,
- };
-
-The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
-the MFD device and if found, that ACPI companion device is bound to the
-resulting child platform device.
-
-Device Tree namespace link device ID
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The Device Tree protocol uses device identification based on the "compatible"
-property whose value is a string or an array of strings recognized as device
-identifiers by drivers and the driver core. The set of all those strings may be
-regarded as a device identification namespace analogous to the ACPI/PNP device
-ID namespace. Consequently, in principle it should not be necessary to allocate
-a new (and arguably redundant) ACPI/PNP device ID for a devices with an existing
-identification string in the Device Tree (DT) namespace, especially if that ID
-is only needed to indicate that a given device is compatible with another one,
-presumably having a matching driver in the kernel already.
-
-In ACPI, the device identification object called _CID (Compatible ID) is used to
-list the IDs of devices the given one is compatible with, but those IDs must
-belong to one of the namespaces prescribed by the ACPI specification (see
-Section 6.1.2 of ACPI 6.0 for details) and the DT namespace is not one of them.
-Moreover, the specification mandates that either a _HID or an _ADR identification
-object be present for all ACPI objects representing devices (Section 6.1 of ACPI
-6.0). For non-enumerable bus types that object must be _HID and its value must
-be a device ID from one of the namespaces prescribed by the specification too.
-
-The special DT namespace link device ID, PRP0001, provides a means to use the
-existing DT-compatible device identification in ACPI and to satisfy the above
-requirements following from the ACPI specification at the same time. Namely,
-if PRP0001 is returned by _HID, the ACPI subsystem will look for the
-"compatible" property in the device object's _DSD and will use the value of that
-property to identify the corresponding device in analogy with the original DT
-device identification algorithm. If the "compatible" property is not present
-or its value is not valid, the device will not be enumerated by the ACPI
-subsystem. Otherwise, it will be enumerated automatically as a platform device
-(except when an I2C or SPI link from the device to its parent is present, in
-which case the ACPI core will leave the device enumeration to the parent's
-driver) and the identification strings from the "compatible" property value will
-be used to find a driver for the device along with the device IDs listed by _CID
-(if present).
-
-Analogously, if PRP0001 is present in the list of device IDs returned by _CID,
-the identification strings listed by the "compatible" property value (if present
-and valid) will be used to look for a driver matching the device, but in that
-case their relative priority with respect to the other device IDs listed by
-_HID and _CID depends on the position of PRP0001 in the _CID return package.
-Specifically, the device IDs returned by _HID and preceding PRP0001 in the _CID
-return package will be checked first. Also in that case the bus type the device
-will be enumerated to depends on the device ID returned by _HID.
-
-For example, the following ACPI sample might be used to enumerate an lm75-type
-I2C temperature sensor and match it to the driver using the Device Tree
-namespace link:
-
- Device (TMP0)
- {
- Name (_HID, "PRP0001")
- Name (_DSD, Package() {
- ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
- Package () {
- Package (2) { "compatible", "ti,tmp75" },
- }
- })
- Method (_CRS, 0, Serialized)
- {
- Name (SBUF, ResourceTemplate ()
- {
- I2cSerialBusV2 (0x48, ControllerInitiated,
- 400000, AddressingMode7Bit,
- "\\_SB.PCI0.I2C1", 0x00,
- ResourceConsumer, , Exclusive,)
- })
- Return (SBUF)
- }
- }
-
-It is valid to define device objects with a _HID returning PRP0001 and without
-the "compatible" property in the _DSD or a _CID as long as one of their
-ancestors provides a _DSD with a valid "compatible" property. Such device
-objects are then simply regarded as additional "blocks" providing hierarchical
-configuration information to the driver of the composite ancestor device.
-
-However, PRP0001 can only be returned from either _HID or _CID of a device
-object if all of the properties returned by the _DSD associated with it (either
-the _DSD of the device object itself or the _DSD of its ancestor in the
-"composite device" case described above) can be used in the ACPI environment.
-Otherwise, the _DSD itself is regarded as invalid and therefore the "compatible"
-property returned by it is meaningless.
-
-Refer to DSD-properties-rules.txt for more information.
--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0
+
+=============================
+ACPI Based Device Enumeration
+=============================
+
+ACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus,
+SpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave
+devices behind serial bus controllers.
+
+In addition we are starting to see peripherals integrated in the
+SoC/Chipset to appear only in ACPI namespace. These are typically devices
+that are accessed through memory-mapped registers.
+
+In order to support this and re-use the existing drivers as much as
+possible we decided to do following:
+
+ - Devices that have no bus connector resource are represented as
+ platform devices.
+
+ - Devices behind real busses where there is a connector resource
+ are represented as struct spi_device or struct i2c_device
+ (standard UARTs are not busses so there is no struct uart_device).
+
+As both ACPI and Device Tree represent a tree of devices (and their
+resources) this implementation follows the Device Tree way as much as
+possible.
+
+The ACPI implementation enumerates devices behind busses (platform, SPI and
+I2C), creates the physical devices and binds them to their ACPI handle in
+the ACPI namespace.
+
+This means that when ACPI_HANDLE(dev) returns non-NULL the device was
+enumerated from ACPI namespace. This handle can be used to extract other
+device-specific configuration. There is an example of this below.
+
+Platform bus support
+====================
+
+Since we are using platform devices to represent devices that are not
+connected to any physical bus we only need to implement a platform driver
+for the device and add supported ACPI IDs. If this same IP-block is used on
+some other non-ACPI platform, the driver might work out of the box or needs
+some minor changes.
+
+Adding ACPI support for an existing driver should be pretty
+straightforward. Here is the simplest example::
+
+ #ifdef CONFIG_ACPI
+ static const struct acpi_device_id mydrv_acpi_match[] = {
+ /* ACPI IDs here */
+ { }
+ };
+ MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match);
+ #endif
+
+ static struct platform_driver my_driver = {
+ ...
+ .driver = {
+ .acpi_match_table = ACPI_PTR(mydrv_acpi_match),
+ },
+ };
+
+If the driver needs to perform more complex initialization like getting and
+configuring GPIOs it can get its ACPI handle and extract this information
+from ACPI tables.
+
+DMA support
+===========
+
+DMA controllers enumerated via ACPI should be registered in the system to
+provide generic access to their resources. For example, a driver that would
+like to be accessible to slave devices via generic API call
+dma_request_slave_channel() must register itself at the end of the probe
+function like this::
+
+ err = devm_acpi_dma_controller_register(dev, xlate_func, dw);
+ /* Handle the error if it's not a case of !CONFIG_ACPI */
+
+and implement custom xlate function if needed (usually acpi_dma_simple_xlate()
+is enough) which converts the FixedDMA resource provided by struct
+acpi_dma_spec into the corresponding DMA channel. A piece of code for that case
+could look like::
+
+ #ifdef CONFIG_ACPI
+ struct filter_args {
+ /* Provide necessary information for the filter_func */
+ ...
+ };
+
+ static bool filter_func(struct dma_chan *chan, void *param)
+ {
+ /* Choose the proper channel */
+ ...
+ }
+
+ static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec,
+ struct acpi_dma *adma)
+ {
+ dma_cap_mask_t cap;
+ struct filter_args args;
+
+ /* Prepare arguments for filter_func */
+ ...
+ return dma_request_channel(cap, filter_func, &args);
+ }
+ #else
+ static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec,
+ struct acpi_dma *adma)
+ {
+ return NULL;
+ }
+ #endif
+
+dma_request_slave_channel() will call xlate_func() for each registered DMA
+controller. In the xlate function the proper channel must be chosen based on
+information in struct acpi_dma_spec and the properties of the controller
+provided by struct acpi_dma.
+
+Clients must call dma_request_slave_channel() with the string parameter that
+corresponds to a specific FixedDMA resource. By default "tx" means the first
+entry of the FixedDMA resource array, "rx" means the second entry. The table
+below shows a layout::
+
+ Device (I2C0)
+ {
+ ...
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (DBUF, ResourceTemplate ()
+ {
+ FixedDMA (0x0018, 0x0004, Width32bit, _Y48)
+ FixedDMA (0x0019, 0x0005, Width32bit, )
+ })
+ ...
+ }
+ }
+
+So, the FixedDMA with request line 0x0018 is "tx" and next one is "rx" in
+this example.
+
+In robust cases the client unfortunately needs to call
+acpi_dma_request_slave_chan_by_index() directly and therefore choose the
+specific FixedDMA resource by its index.
+
+SPI serial bus support
+======================
+
+Slave devices behind SPI bus have SpiSerialBus resource attached to them.
+This is extracted automatically by the SPI core and the slave devices are
+enumerated once spi_register_master() is called by the bus driver.
+
+Here is what the ACPI namespace for a SPI slave might look like::
+
+ Device (EEP0)
+ {
+ Name (_ADR, 1)
+ Name (_CID, Package() {
+ "ATML0025",
+ "AT25",
+ })
+ ...
+ Method (_CRS, 0, NotSerialized)
+ {
+ SPISerialBus(1, PolarityLow, FourWireMode, 8,
+ ControllerInitiated, 1000000, ClockPolarityLow,
+ ClockPhaseFirst, "\\_SB.PCI0.SPI1",)
+ }
+ ...
+
+The SPI device drivers only need to add ACPI IDs in a similar way than with
+the platform device drivers. Below is an example where we add ACPI support
+to at25 SPI eeprom driver (this is meant for the above ACPI snippet)::
+
+ #ifdef CONFIG_ACPI
+ static const struct acpi_device_id at25_acpi_match[] = {
+ { "AT25", 0 },
+ { },
+ };
+ MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
+ #endif
+
+ static struct spi_driver at25_driver = {
+ .driver = {
+ ...
+ .acpi_match_table = ACPI_PTR(at25_acpi_match),
+ },
+ };
+
+Note that this driver actually needs more information like page size of the
+eeprom etc. but at the time writing this there is no standard way of
+passing those. One idea is to return this in _DSM method like::
+
+ Device (EEP0)
+ {
+ ...
+ Method (_DSM, 4, NotSerialized)
+ {
+ Store (Package (6)
+ {
+ "byte-len", 1024,
+ "addr-mode", 2,
+ "page-size, 32
+ }, Local0)
+
+ // Check UUIDs etc.
+
+ Return (Local0)
+ }
+
+Then the at25 SPI driver can get this configuration by calling _DSM on its
+ACPI handle like::
+
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_object_list input;
+ acpi_status status;
+
+ /* Fill in the input buffer */
+
+ status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "_DSM",
+ &input, &output);
+ if (ACPI_FAILURE(status))
+ /* Handle the error */
+
+ /* Extract the data here */
+
+ kfree(output.pointer);
+
+I2C serial bus support
+======================
+
+The slaves behind I2C bus controller only need to add the ACPI IDs like
+with the platform and SPI drivers. The I2C core automatically enumerates
+any slave devices behind the controller device once the adapter is
+registered.
+
+Below is an example of how to add ACPI support to the existing mpu3050
+input driver::
+
+ #ifdef CONFIG_ACPI
+ static const struct acpi_device_id mpu3050_acpi_match[] = {
+ { "MPU3050", 0 },
+ { },
+ };
+ MODULE_DEVICE_TABLE(acpi, mpu3050_acpi_match);
+ #endif
+
+ static struct i2c_driver mpu3050_i2c_driver = {
+ .driver = {
+ .name = "mpu3050",
+ .owner = THIS_MODULE,
+ .pm = &mpu3050_pm,
+ .of_match_table = mpu3050_of_match,
+ .acpi_match_table = ACPI_PTR(mpu3050_acpi_match),
+ },
+ .probe = mpu3050_probe,
+ .remove = mpu3050_remove,
+ .id_table = mpu3050_ids,
+ };
+
+GPIO support
+============
+
+ACPI 5 introduced two new resources to describe GPIO connections: GpioIo
+and GpioInt. These resources can be used to pass GPIO numbers used by
+the device to the driver. ACPI 5.1 extended this with _DSD (Device
+Specific Data) which made it possible to name the GPIOs among other things.
+
+For example::
+
+ Device (DEV)
+ {
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBUF, ResourceTemplate()
+ {
+ ...
+ // Used to power on/off the device
+ GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
+ IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
+ 0x00, ResourceConsumer,,)
+ {
+ // Pin List
+ 0x0055
+ }
+
+ // Interrupt for the device
+ GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone,
+ 0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
+ {
+ // Pin list
+ 0x0058
+ }
+
+ ...
+
+ }
+
+ Return (SBUF)
+ }
+
+ // ACPI 5.1 _DSD used for naming the GPIOs
+ Name (_DSD, Package ()
+ {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }},
+ Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }},
+ }
+ })
+ ...
+
+These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
+specifies the path to the controller. In order to use these GPIOs in Linux
+we need to translate them to the corresponding Linux GPIO descriptors.
+
+There is a standard GPIO API for that and is documented in
+Documentation/gpio/.
+
+In the above example we can get the corresponding two GPIO descriptors with
+a code like this::
+
+ #include <linux/gpio/consumer.h>
+ ...
+
+ struct gpio_desc *irq_desc, *power_desc;
+
+ irq_desc = gpiod_get(dev, "irq");
+ if (IS_ERR(irq_desc))
+ /* handle error */
+
+ power_desc = gpiod_get(dev, "power");
+ if (IS_ERR(power_desc))
+ /* handle error */
+
+ /* Now we can use the GPIO descriptors */
+
+There are also devm_* versions of these functions which release the
+descriptors once the device is released.
+
+See Documentation/acpi/gpio-properties.txt for more information about the
+_DSD binding related to GPIOs.
+
+MFD devices
+===========
+
+The MFD devices register their children as platform devices. For the child
+devices there needs to be an ACPI handle that they can use to reference
+parts of the ACPI namespace that relate to them. In the Linux MFD subsystem
+we provide two ways:
+
+ - The children share the parent ACPI handle.
+ - The MFD cell can specify the ACPI id of the device.
+
+For the first case, the MFD drivers do not need to do anything. The
+resulting child platform device will have its ACPI_COMPANION() set to point
+to the parent device.
+
+If the ACPI namespace has a device that we can match using an ACPI id or ACPI
+adr, the cell should be set like::
+
+ static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
+ .pnpid = "XYZ0001",
+ .adr = 0,
+ };
+
+ static struct mfd_cell my_subdevice_cell = {
+ .name = "my_subdevice",
+ /* set the resources relative to the parent */
+ .acpi_match = &my_subdevice_cell_acpi_match,
+ };
+
+The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
+the MFD device and if found, that ACPI companion device is bound to the
+resulting child platform device.
+
+Device Tree namespace link device ID
+====================================
+
+The Device Tree protocol uses device identification based on the "compatible"
+property whose value is a string or an array of strings recognized as device
+identifiers by drivers and the driver core. The set of all those strings may be
+regarded as a device identification namespace analogous to the ACPI/PNP device
+ID namespace. Consequently, in principle it should not be necessary to allocate
+a new (and arguably redundant) ACPI/PNP device ID for a devices with an existing
+identification string in the Device Tree (DT) namespace, especially if that ID
+is only needed to indicate that a given device is compatible with another one,
+presumably having a matching driver in the kernel already.
+
+In ACPI, the device identification object called _CID (Compatible ID) is used to
+list the IDs of devices the given one is compatible with, but those IDs must
+belong to one of the namespaces prescribed by the ACPI specification (see
+Section 6.1.2 of ACPI 6.0 for details) and the DT namespace is not one of them.
+Moreover, the specification mandates that either a _HID or an _ADR identification
+object be present for all ACPI objects representing devices (Section 6.1 of ACPI
+6.0). For non-enumerable bus types that object must be _HID and its value must
+be a device ID from one of the namespaces prescribed by the specification too.
+
+The special DT namespace link device ID, PRP0001, provides a means to use the
+existing DT-compatible device identification in ACPI and to satisfy the above
+requirements following from the ACPI specification at the same time. Namely,
+if PRP0001 is returned by _HID, the ACPI subsystem will look for the
+"compatible" property in the device object's _DSD and will use the value of that
+property to identify the corresponding device in analogy with the original DT
+device identification algorithm. If the "compatible" property is not present
+or its value is not valid, the device will not be enumerated by the ACPI
+subsystem. Otherwise, it will be enumerated automatically as a platform device
+(except when an I2C or SPI link from the device to its parent is present, in
+which case the ACPI core will leave the device enumeration to the parent's
+driver) and the identification strings from the "compatible" property value will
+be used to find a driver for the device along with the device IDs listed by _CID
+(if present).
+
+Analogously, if PRP0001 is present in the list of device IDs returned by _CID,
+the identification strings listed by the "compatible" property value (if present
+and valid) will be used to look for a driver matching the device, but in that
+case their relative priority with respect to the other device IDs listed by
+_HID and _CID depends on the position of PRP0001 in the _CID return package.
+Specifically, the device IDs returned by _HID and preceding PRP0001 in the _CID
+return package will be checked first. Also in that case the bus type the device
+will be enumerated to depends on the device ID returned by _HID.
+
+For example, the following ACPI sample might be used to enumerate an lm75-type
+I2C temperature sensor and match it to the driver using the Device Tree
+namespace link:
+
+ Device (TMP0)
+ {
+ Name (_HID, "PRP0001")
+ Name (_DSD, Package() {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package () {
+ Package (2) { "compatible", "ti,tmp75" },
+ }
+ })
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBUF, ResourceTemplate ()
+ {
+ I2cSerialBusV2 (0x48, ControllerInitiated,
+ 400000, AddressingMode7Bit,
+ "\\_SB.PCI0.I2C1", 0x00,
+ ResourceConsumer, , Exclusive,)
+ })
+ Return (SBUF)
+ }
+ }
+
+It is valid to define device objects with a _HID returning PRP0001 and without
+the "compatible" property in the _DSD or a _CID as long as one of their
+ancestors provides a _DSD with a valid "compatible" property. Such device
+objects are then simply regarded as additional "blocks" providing hierarchical
+configuration information to the driver of the composite ancestor device.
+
+However, PRP0001 can only be returned from either _HID or _CID of a device
+object if all of the properties returned by the _DSD associated with it (either
+the _DSD of the device object itself or the _DSD of its ancestor in the
+"composite device" case described above) can be used in the ACPI environment.
+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.