18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci============================= 48c2ecf20Sopenharmony_ciACPI Based Device Enumeration 58c2ecf20Sopenharmony_ci============================= 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus, 88c2ecf20Sopenharmony_ciSpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave 98c2ecf20Sopenharmony_cidevices behind serial bus controllers. 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ciIn addition we are starting to see peripherals integrated in the 128c2ecf20Sopenharmony_ciSoC/Chipset to appear only in ACPI namespace. These are typically devices 138c2ecf20Sopenharmony_cithat are accessed through memory-mapped registers. 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciIn order to support this and re-use the existing drivers as much as 168c2ecf20Sopenharmony_cipossible we decided to do following: 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci - Devices that have no bus connector resource are represented as 198c2ecf20Sopenharmony_ci platform devices. 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci - Devices behind real busses where there is a connector resource 228c2ecf20Sopenharmony_ci are represented as struct spi_device or struct i2c_device 238c2ecf20Sopenharmony_ci (standard UARTs are not busses so there is no struct uart_device). 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ciAs both ACPI and Device Tree represent a tree of devices (and their 268c2ecf20Sopenharmony_ciresources) this implementation follows the Device Tree way as much as 278c2ecf20Sopenharmony_cipossible. 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ciThe ACPI implementation enumerates devices behind busses (platform, SPI and 308c2ecf20Sopenharmony_ciI2C), creates the physical devices and binds them to their ACPI handle in 318c2ecf20Sopenharmony_cithe ACPI namespace. 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciThis means that when ACPI_HANDLE(dev) returns non-NULL the device was 348c2ecf20Sopenharmony_cienumerated from ACPI namespace. This handle can be used to extract other 358c2ecf20Sopenharmony_cidevice-specific configuration. There is an example of this below. 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciPlatform bus support 388c2ecf20Sopenharmony_ci==================== 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciSince we are using platform devices to represent devices that are not 418c2ecf20Sopenharmony_ciconnected to any physical bus we only need to implement a platform driver 428c2ecf20Sopenharmony_cifor the device and add supported ACPI IDs. If this same IP-block is used on 438c2ecf20Sopenharmony_cisome other non-ACPI platform, the driver might work out of the box or needs 448c2ecf20Sopenharmony_cisome minor changes. 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciAdding ACPI support for an existing driver should be pretty 478c2ecf20Sopenharmony_cistraightforward. Here is the simplest example:: 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci #ifdef CONFIG_ACPI 508c2ecf20Sopenharmony_ci static const struct acpi_device_id mydrv_acpi_match[] = { 518c2ecf20Sopenharmony_ci /* ACPI IDs here */ 528c2ecf20Sopenharmony_ci { } 538c2ecf20Sopenharmony_ci }; 548c2ecf20Sopenharmony_ci MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match); 558c2ecf20Sopenharmony_ci #endif 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci static struct platform_driver my_driver = { 588c2ecf20Sopenharmony_ci ... 598c2ecf20Sopenharmony_ci .driver = { 608c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(mydrv_acpi_match), 618c2ecf20Sopenharmony_ci }, 628c2ecf20Sopenharmony_ci }; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ciIf the driver needs to perform more complex initialization like getting and 658c2ecf20Sopenharmony_ciconfiguring GPIOs it can get its ACPI handle and extract this information 668c2ecf20Sopenharmony_cifrom ACPI tables. 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ciDMA support 698c2ecf20Sopenharmony_ci=========== 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciDMA controllers enumerated via ACPI should be registered in the system to 728c2ecf20Sopenharmony_ciprovide generic access to their resources. For example, a driver that would 738c2ecf20Sopenharmony_cilike to be accessible to slave devices via generic API call 748c2ecf20Sopenharmony_cidma_request_chan() must register itself at the end of the probe function like 758c2ecf20Sopenharmony_cithis:: 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci err = devm_acpi_dma_controller_register(dev, xlate_func, dw); 788c2ecf20Sopenharmony_ci /* Handle the error if it's not a case of !CONFIG_ACPI */ 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ciand implement custom xlate function if needed (usually acpi_dma_simple_xlate() 818c2ecf20Sopenharmony_ciis enough) which converts the FixedDMA resource provided by struct 828c2ecf20Sopenharmony_ciacpi_dma_spec into the corresponding DMA channel. A piece of code for that case 838c2ecf20Sopenharmony_cicould look like:: 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci #ifdef CONFIG_ACPI 868c2ecf20Sopenharmony_ci struct filter_args { 878c2ecf20Sopenharmony_ci /* Provide necessary information for the filter_func */ 888c2ecf20Sopenharmony_ci ... 898c2ecf20Sopenharmony_ci }; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci static bool filter_func(struct dma_chan *chan, void *param) 928c2ecf20Sopenharmony_ci { 938c2ecf20Sopenharmony_ci /* Choose the proper channel */ 948c2ecf20Sopenharmony_ci ... 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec, 988c2ecf20Sopenharmony_ci struct acpi_dma *adma) 998c2ecf20Sopenharmony_ci { 1008c2ecf20Sopenharmony_ci dma_cap_mask_t cap; 1018c2ecf20Sopenharmony_ci struct filter_args args; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* Prepare arguments for filter_func */ 1048c2ecf20Sopenharmony_ci ... 1058c2ecf20Sopenharmony_ci return dma_request_channel(cap, filter_func, &args); 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci #else 1088c2ecf20Sopenharmony_ci static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec, 1098c2ecf20Sopenharmony_ci struct acpi_dma *adma) 1108c2ecf20Sopenharmony_ci { 1118c2ecf20Sopenharmony_ci return NULL; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci #endif 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cidma_request_chan() will call xlate_func() for each registered DMA controller. 1168c2ecf20Sopenharmony_ciIn the xlate function the proper channel must be chosen based on 1178c2ecf20Sopenharmony_ciinformation in struct acpi_dma_spec and the properties of the controller 1188c2ecf20Sopenharmony_ciprovided by struct acpi_dma. 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ciClients must call dma_request_chan() with the string parameter that corresponds 1218c2ecf20Sopenharmony_cito a specific FixedDMA resource. By default "tx" means the first entry of the 1228c2ecf20Sopenharmony_ciFixedDMA resource array, "rx" means the second entry. The table below shows a 1238c2ecf20Sopenharmony_cilayout:: 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci Device (I2C0) 1268c2ecf20Sopenharmony_ci { 1278c2ecf20Sopenharmony_ci ... 1288c2ecf20Sopenharmony_ci Method (_CRS, 0, NotSerialized) 1298c2ecf20Sopenharmony_ci { 1308c2ecf20Sopenharmony_ci Name (DBUF, ResourceTemplate () 1318c2ecf20Sopenharmony_ci { 1328c2ecf20Sopenharmony_ci FixedDMA (0x0018, 0x0004, Width32bit, _Y48) 1338c2ecf20Sopenharmony_ci FixedDMA (0x0019, 0x0005, Width32bit, ) 1348c2ecf20Sopenharmony_ci }) 1358c2ecf20Sopenharmony_ci ... 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ciSo, the FixedDMA with request line 0x0018 is "tx" and next one is "rx" in 1408c2ecf20Sopenharmony_cithis example. 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ciIn robust cases the client unfortunately needs to call 1438c2ecf20Sopenharmony_ciacpi_dma_request_slave_chan_by_index() directly and therefore choose the 1448c2ecf20Sopenharmony_cispecific FixedDMA resource by its index. 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ciSPI serial bus support 1478c2ecf20Sopenharmony_ci====================== 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ciSlave devices behind SPI bus have SpiSerialBus resource attached to them. 1508c2ecf20Sopenharmony_ciThis is extracted automatically by the SPI core and the slave devices are 1518c2ecf20Sopenharmony_cienumerated once spi_register_master() is called by the bus driver. 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ciHere is what the ACPI namespace for a SPI slave might look like:: 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci Device (EEP0) 1568c2ecf20Sopenharmony_ci { 1578c2ecf20Sopenharmony_ci Name (_ADR, 1) 1588c2ecf20Sopenharmony_ci Name (_CID, Package() { 1598c2ecf20Sopenharmony_ci "ATML0025", 1608c2ecf20Sopenharmony_ci "AT25", 1618c2ecf20Sopenharmony_ci }) 1628c2ecf20Sopenharmony_ci ... 1638c2ecf20Sopenharmony_ci Method (_CRS, 0, NotSerialized) 1648c2ecf20Sopenharmony_ci { 1658c2ecf20Sopenharmony_ci SPISerialBus(1, PolarityLow, FourWireMode, 8, 1668c2ecf20Sopenharmony_ci ControllerInitiated, 1000000, ClockPolarityLow, 1678c2ecf20Sopenharmony_ci ClockPhaseFirst, "\\_SB.PCI0.SPI1",) 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci ... 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ciThe SPI device drivers only need to add ACPI IDs in a similar way than with 1728c2ecf20Sopenharmony_cithe platform device drivers. Below is an example where we add ACPI support 1738c2ecf20Sopenharmony_cito at25 SPI eeprom driver (this is meant for the above ACPI snippet):: 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci #ifdef CONFIG_ACPI 1768c2ecf20Sopenharmony_ci static const struct acpi_device_id at25_acpi_match[] = { 1778c2ecf20Sopenharmony_ci { "AT25", 0 }, 1788c2ecf20Sopenharmony_ci { }, 1798c2ecf20Sopenharmony_ci }; 1808c2ecf20Sopenharmony_ci MODULE_DEVICE_TABLE(acpi, at25_acpi_match); 1818c2ecf20Sopenharmony_ci #endif 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci static struct spi_driver at25_driver = { 1848c2ecf20Sopenharmony_ci .driver = { 1858c2ecf20Sopenharmony_ci ... 1868c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(at25_acpi_match), 1878c2ecf20Sopenharmony_ci }, 1888c2ecf20Sopenharmony_ci }; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ciNote that this driver actually needs more information like page size of the 1918c2ecf20Sopenharmony_cieeprom etc. but at the time writing this there is no standard way of 1928c2ecf20Sopenharmony_cipassing those. One idea is to return this in _DSM method like:: 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci Device (EEP0) 1958c2ecf20Sopenharmony_ci { 1968c2ecf20Sopenharmony_ci ... 1978c2ecf20Sopenharmony_ci Method (_DSM, 4, NotSerialized) 1988c2ecf20Sopenharmony_ci { 1998c2ecf20Sopenharmony_ci Store (Package (6) 2008c2ecf20Sopenharmony_ci { 2018c2ecf20Sopenharmony_ci "byte-len", 1024, 2028c2ecf20Sopenharmony_ci "addr-mode", 2, 2038c2ecf20Sopenharmony_ci "page-size, 32 2048c2ecf20Sopenharmony_ci }, Local0) 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci // Check UUIDs etc. 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci Return (Local0) 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ciThen the at25 SPI driver can get this configuration by calling _DSM on its 2128c2ecf20Sopenharmony_ciACPI handle like:: 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 2158c2ecf20Sopenharmony_ci struct acpi_object_list input; 2168c2ecf20Sopenharmony_ci acpi_status status; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci /* Fill in the input buffer */ 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "_DSM", 2218c2ecf20Sopenharmony_ci &input, &output); 2228c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) 2238c2ecf20Sopenharmony_ci /* Handle the error */ 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci /* Extract the data here */ 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci kfree(output.pointer); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ciI2C serial bus support 2308c2ecf20Sopenharmony_ci====================== 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciThe slaves behind I2C bus controller only need to add the ACPI IDs like 2338c2ecf20Sopenharmony_ciwith the platform and SPI drivers. The I2C core automatically enumerates 2348c2ecf20Sopenharmony_ciany slave devices behind the controller device once the adapter is 2358c2ecf20Sopenharmony_ciregistered. 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ciBelow is an example of how to add ACPI support to the existing mpu3050 2388c2ecf20Sopenharmony_ciinput driver:: 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci #ifdef CONFIG_ACPI 2418c2ecf20Sopenharmony_ci static const struct acpi_device_id mpu3050_acpi_match[] = { 2428c2ecf20Sopenharmony_ci { "MPU3050", 0 }, 2438c2ecf20Sopenharmony_ci { }, 2448c2ecf20Sopenharmony_ci }; 2458c2ecf20Sopenharmony_ci MODULE_DEVICE_TABLE(acpi, mpu3050_acpi_match); 2468c2ecf20Sopenharmony_ci #endif 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci static struct i2c_driver mpu3050_i2c_driver = { 2498c2ecf20Sopenharmony_ci .driver = { 2508c2ecf20Sopenharmony_ci .name = "mpu3050", 2518c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 2528c2ecf20Sopenharmony_ci .pm = &mpu3050_pm, 2538c2ecf20Sopenharmony_ci .of_match_table = mpu3050_of_match, 2548c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(mpu3050_acpi_match), 2558c2ecf20Sopenharmony_ci }, 2568c2ecf20Sopenharmony_ci .probe = mpu3050_probe, 2578c2ecf20Sopenharmony_ci .remove = mpu3050_remove, 2588c2ecf20Sopenharmony_ci .id_table = mpu3050_ids, 2598c2ecf20Sopenharmony_ci }; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ciGPIO support 2628c2ecf20Sopenharmony_ci============ 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ciACPI 5 introduced two new resources to describe GPIO connections: GpioIo 2658c2ecf20Sopenharmony_ciand GpioInt. These resources can be used to pass GPIO numbers used by 2668c2ecf20Sopenharmony_cithe device to the driver. ACPI 5.1 extended this with _DSD (Device 2678c2ecf20Sopenharmony_ciSpecific Data) which made it possible to name the GPIOs among other things. 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ciFor example:: 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci Device (DEV) 2728c2ecf20Sopenharmony_ci { 2738c2ecf20Sopenharmony_ci Method (_CRS, 0, NotSerialized) 2748c2ecf20Sopenharmony_ci { 2758c2ecf20Sopenharmony_ci Name (SBUF, ResourceTemplate() 2768c2ecf20Sopenharmony_ci { 2778c2ecf20Sopenharmony_ci ... 2788c2ecf20Sopenharmony_ci // Used to power on/off the device 2798c2ecf20Sopenharmony_ci GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, 2808c2ecf20Sopenharmony_ci IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0", 2818c2ecf20Sopenharmony_ci 0x00, ResourceConsumer,,) 2828c2ecf20Sopenharmony_ci { 2838c2ecf20Sopenharmony_ci // Pin List 2848c2ecf20Sopenharmony_ci 0x0055 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci // Interrupt for the device 2888c2ecf20Sopenharmony_ci GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone, 2898c2ecf20Sopenharmony_ci 0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,) 2908c2ecf20Sopenharmony_ci { 2918c2ecf20Sopenharmony_ci // Pin list 2928c2ecf20Sopenharmony_ci 0x0058 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci ... 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci Return (SBUF) 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci // ACPI 5.1 _DSD used for naming the GPIOs 3038c2ecf20Sopenharmony_ci Name (_DSD, Package () 3048c2ecf20Sopenharmony_ci { 3058c2ecf20Sopenharmony_ci ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 3068c2ecf20Sopenharmony_ci Package () 3078c2ecf20Sopenharmony_ci { 3088c2ecf20Sopenharmony_ci Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }}, 3098c2ecf20Sopenharmony_ci Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }}, 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci }) 3128c2ecf20Sopenharmony_ci ... 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ciThese GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" 3158c2ecf20Sopenharmony_cispecifies the path to the controller. In order to use these GPIOs in Linux 3168c2ecf20Sopenharmony_ciwe need to translate them to the corresponding Linux GPIO descriptors. 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ciThere is a standard GPIO API for that and is documented in 3198c2ecf20Sopenharmony_ciDocumentation/admin-guide/gpio/. 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ciIn the above example we can get the corresponding two GPIO descriptors with 3228c2ecf20Sopenharmony_cia code like this:: 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci #include <linux/gpio/consumer.h> 3258c2ecf20Sopenharmony_ci ... 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci struct gpio_desc *irq_desc, *power_desc; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci irq_desc = gpiod_get(dev, "irq"); 3308c2ecf20Sopenharmony_ci if (IS_ERR(irq_desc)) 3318c2ecf20Sopenharmony_ci /* handle error */ 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci power_desc = gpiod_get(dev, "power"); 3348c2ecf20Sopenharmony_ci if (IS_ERR(power_desc)) 3358c2ecf20Sopenharmony_ci /* handle error */ 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci /* Now we can use the GPIO descriptors */ 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ciThere are also devm_* versions of these functions which release the 3408c2ecf20Sopenharmony_cidescriptors once the device is released. 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ciSee Documentation/firmware-guide/acpi/gpio-properties.rst for more information about the 3438c2ecf20Sopenharmony_ci_DSD binding related to GPIOs. 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ciMFD devices 3468c2ecf20Sopenharmony_ci=========== 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ciThe MFD devices register their children as platform devices. For the child 3498c2ecf20Sopenharmony_cidevices there needs to be an ACPI handle that they can use to reference 3508c2ecf20Sopenharmony_ciparts of the ACPI namespace that relate to them. In the Linux MFD subsystem 3518c2ecf20Sopenharmony_ciwe provide two ways: 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci - The children share the parent ACPI handle. 3548c2ecf20Sopenharmony_ci - The MFD cell can specify the ACPI id of the device. 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ciFor the first case, the MFD drivers do not need to do anything. The 3578c2ecf20Sopenharmony_ciresulting child platform device will have its ACPI_COMPANION() set to point 3588c2ecf20Sopenharmony_cito the parent device. 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ciIf the ACPI namespace has a device that we can match using an ACPI id or ACPI 3618c2ecf20Sopenharmony_ciadr, the cell should be set like:: 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = { 3648c2ecf20Sopenharmony_ci .pnpid = "XYZ0001", 3658c2ecf20Sopenharmony_ci .adr = 0, 3668c2ecf20Sopenharmony_ci }; 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci static struct mfd_cell my_subdevice_cell = { 3698c2ecf20Sopenharmony_ci .name = "my_subdevice", 3708c2ecf20Sopenharmony_ci /* set the resources relative to the parent */ 3718c2ecf20Sopenharmony_ci .acpi_match = &my_subdevice_cell_acpi_match, 3728c2ecf20Sopenharmony_ci }; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ciThe ACPI id "XYZ0001" is then used to lookup an ACPI device directly under 3758c2ecf20Sopenharmony_cithe MFD device and if found, that ACPI companion device is bound to the 3768c2ecf20Sopenharmony_ciresulting child platform device. 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ciDevice Tree namespace link device ID 3798c2ecf20Sopenharmony_ci==================================== 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ciThe Device Tree protocol uses device identification based on the "compatible" 3828c2ecf20Sopenharmony_ciproperty whose value is a string or an array of strings recognized as device 3838c2ecf20Sopenharmony_ciidentifiers by drivers and the driver core. The set of all those strings may be 3848c2ecf20Sopenharmony_ciregarded as a device identification namespace analogous to the ACPI/PNP device 3858c2ecf20Sopenharmony_ciID namespace. Consequently, in principle it should not be necessary to allocate 3868c2ecf20Sopenharmony_cia new (and arguably redundant) ACPI/PNP device ID for a devices with an existing 3878c2ecf20Sopenharmony_ciidentification string in the Device Tree (DT) namespace, especially if that ID 3888c2ecf20Sopenharmony_ciis only needed to indicate that a given device is compatible with another one, 3898c2ecf20Sopenharmony_cipresumably having a matching driver in the kernel already. 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ciIn ACPI, the device identification object called _CID (Compatible ID) is used to 3928c2ecf20Sopenharmony_cilist the IDs of devices the given one is compatible with, but those IDs must 3938c2ecf20Sopenharmony_cibelong to one of the namespaces prescribed by the ACPI specification (see 3948c2ecf20Sopenharmony_ciSection 6.1.2 of ACPI 6.0 for details) and the DT namespace is not one of them. 3958c2ecf20Sopenharmony_ciMoreover, the specification mandates that either a _HID or an _ADR identification 3968c2ecf20Sopenharmony_ciobject be present for all ACPI objects representing devices (Section 6.1 of ACPI 3978c2ecf20Sopenharmony_ci6.0). For non-enumerable bus types that object must be _HID and its value must 3988c2ecf20Sopenharmony_cibe a device ID from one of the namespaces prescribed by the specification too. 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ciThe special DT namespace link device ID, PRP0001, provides a means to use the 4018c2ecf20Sopenharmony_ciexisting DT-compatible device identification in ACPI and to satisfy the above 4028c2ecf20Sopenharmony_cirequirements following from the ACPI specification at the same time. Namely, 4038c2ecf20Sopenharmony_ciif PRP0001 is returned by _HID, the ACPI subsystem will look for the 4048c2ecf20Sopenharmony_ci"compatible" property in the device object's _DSD and will use the value of that 4058c2ecf20Sopenharmony_ciproperty to identify the corresponding device in analogy with the original DT 4068c2ecf20Sopenharmony_cidevice identification algorithm. If the "compatible" property is not present 4078c2ecf20Sopenharmony_cior its value is not valid, the device will not be enumerated by the ACPI 4088c2ecf20Sopenharmony_cisubsystem. Otherwise, it will be enumerated automatically as a platform device 4098c2ecf20Sopenharmony_ci(except when an I2C or SPI link from the device to its parent is present, in 4108c2ecf20Sopenharmony_ciwhich case the ACPI core will leave the device enumeration to the parent's 4118c2ecf20Sopenharmony_cidriver) and the identification strings from the "compatible" property value will 4128c2ecf20Sopenharmony_cibe used to find a driver for the device along with the device IDs listed by _CID 4138c2ecf20Sopenharmony_ci(if present). 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ciAnalogously, if PRP0001 is present in the list of device IDs returned by _CID, 4168c2ecf20Sopenharmony_cithe identification strings listed by the "compatible" property value (if present 4178c2ecf20Sopenharmony_ciand valid) will be used to look for a driver matching the device, but in that 4188c2ecf20Sopenharmony_cicase their relative priority with respect to the other device IDs listed by 4198c2ecf20Sopenharmony_ci_HID and _CID depends on the position of PRP0001 in the _CID return package. 4208c2ecf20Sopenharmony_ciSpecifically, the device IDs returned by _HID and preceding PRP0001 in the _CID 4218c2ecf20Sopenharmony_cireturn package will be checked first. Also in that case the bus type the device 4228c2ecf20Sopenharmony_ciwill be enumerated to depends on the device ID returned by _HID. 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ciFor example, the following ACPI sample might be used to enumerate an lm75-type 4258c2ecf20Sopenharmony_ciI2C temperature sensor and match it to the driver using the Device Tree 4268c2ecf20Sopenharmony_cinamespace link:: 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci Device (TMP0) 4298c2ecf20Sopenharmony_ci { 4308c2ecf20Sopenharmony_ci Name (_HID, "PRP0001") 4318c2ecf20Sopenharmony_ci Name (_DSD, Package() { 4328c2ecf20Sopenharmony_ci ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 4338c2ecf20Sopenharmony_ci Package () { 4348c2ecf20Sopenharmony_ci Package (2) { "compatible", "ti,tmp75" }, 4358c2ecf20Sopenharmony_ci } 4368c2ecf20Sopenharmony_ci }) 4378c2ecf20Sopenharmony_ci Method (_CRS, 0, Serialized) 4388c2ecf20Sopenharmony_ci { 4398c2ecf20Sopenharmony_ci Name (SBUF, ResourceTemplate () 4408c2ecf20Sopenharmony_ci { 4418c2ecf20Sopenharmony_ci I2cSerialBusV2 (0x48, ControllerInitiated, 4428c2ecf20Sopenharmony_ci 400000, AddressingMode7Bit, 4438c2ecf20Sopenharmony_ci "\\_SB.PCI0.I2C1", 0x00, 4448c2ecf20Sopenharmony_ci ResourceConsumer, , Exclusive,) 4458c2ecf20Sopenharmony_ci }) 4468c2ecf20Sopenharmony_ci Return (SBUF) 4478c2ecf20Sopenharmony_ci } 4488c2ecf20Sopenharmony_ci } 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ciIt is valid to define device objects with a _HID returning PRP0001 and without 4518c2ecf20Sopenharmony_cithe "compatible" property in the _DSD or a _CID as long as one of their 4528c2ecf20Sopenharmony_ciancestors provides a _DSD with a valid "compatible" property. Such device 4538c2ecf20Sopenharmony_ciobjects are then simply regarded as additional "blocks" providing hierarchical 4548c2ecf20Sopenharmony_ciconfiguration information to the driver of the composite ancestor device. 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ciHowever, PRP0001 can only be returned from either _HID or _CID of a device 4578c2ecf20Sopenharmony_ciobject if all of the properties returned by the _DSD associated with it (either 4588c2ecf20Sopenharmony_cithe _DSD of the device object itself or the _DSD of its ancestor in the 4598c2ecf20Sopenharmony_ci"composite device" case described above) can be used in the ACPI environment. 4608c2ecf20Sopenharmony_ciOtherwise, the _DSD itself is regarded as invalid and therefore the "compatible" 4618c2ecf20Sopenharmony_ciproperty returned by it is meaningless. 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ciRefer to :doc:`DSD-properties-rules` for more information. 464