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