mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
Merge branch 'acpi-docs'
Make ACPI documentation updates for 5.18-rc1: - Update the ACPI device enumeration documentation and unify the ASL style in GPIO-related examples (Andy Shevchenko). * acpi-docs: ACPI: docs: gpio-properties: Unify ASL style for GPIO examples ACPI: docs: enumeration: Unify Package () for properties ACPI: docs: enumeration: Drop comma for terminator entry ACPI: docs: enumeration: Drop ugly ifdeffery from the examples ACPI: docs: enumeration: Amend PWM enumeration ASL example ACPI: docs: enumeration: Remove redundant .owner assignment ACPI: docs: enumeration: Update UART serial bus resource documentation ACPI: docs: enumeration: Discourage to use custom _DSM methods
This commit is contained in:
commit
1bde8bddb5
3 changed files with 67 additions and 91 deletions
|
@ -71,14 +71,14 @@ with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
|
|||
|
||||
Device (FOO) {
|
||||
Name (_CRS, ResourceTemplate () {
|
||||
GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0") {15} // red
|
||||
GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0") {16} // green
|
||||
GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0") {17} // blue
|
||||
GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0") {1} // power
|
||||
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0", 0, ResourceConsumer) { 15 } // red
|
||||
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0", 0, ResourceConsumer) { 16 } // green
|
||||
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0", 0, ResourceConsumer) { 17 } // blue
|
||||
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.GPI0", 0, ResourceConsumer) { 1 } // power
|
||||
})
|
||||
|
||||
Name (_DSD, Package () {
|
||||
|
@ -92,10 +92,7 @@ with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
|
|||
^FOO, 2, 0, 1,
|
||||
}
|
||||
},
|
||||
Package () {
|
||||
"power-gpios",
|
||||
Package () {^FOO, 3, 0, 0},
|
||||
},
|
||||
Package () { "power-gpios", Package () { ^FOO, 3, 0, 0 } },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,16 +19,17 @@ possible we decided to do following:
|
|||
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).
|
||||
are represented as struct spi_device or struct i2c_device. Note
|
||||
that standard UARTs are not busses so there is no struct uart_device,
|
||||
although some of them may be represented by sturct serdev_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.
|
||||
The ACPI implementation enumerates devices behind busses (platform, SPI,
|
||||
I2C, and in some cases UART), 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
|
||||
|
@ -46,18 +47,16 @@ 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),
|
||||
.acpi_match_table = mydrv_acpi_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -155,7 +154,7 @@ Here is what the ACPI namespace for a SPI slave might look like::
|
|||
Device (EEP0)
|
||||
{
|
||||
Name (_ADR, 1)
|
||||
Name (_CID, Package() {
|
||||
Name (_CID, Package () {
|
||||
"ATML0025",
|
||||
"AT25",
|
||||
})
|
||||
|
@ -172,59 +171,51 @@ 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),
|
||||
.acpi_match_table = 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::
|
||||
eeprom, etc. This information can be passed via _DSD method like::
|
||||
|
||||
Device (EEP0)
|
||||
{
|
||||
...
|
||||
Method (_DSM, 4, NotSerialized)
|
||||
Name (_DSD, Package ()
|
||||
{
|
||||
Store (Package (6)
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package ()
|
||||
{
|
||||
"byte-len", 1024,
|
||||
"addr-mode", 2,
|
||||
"page-size, 32
|
||||
}, Local0)
|
||||
Package () { "size", 1024 },
|
||||
Package () { "pagesize", 32 },
|
||||
Package () { "address-width", 16 },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Check UUIDs etc.
|
||||
Then the at25 SPI driver can get this configuration by calling device property
|
||||
APIs during ->probe() phase like::
|
||||
|
||||
Return (Local0)
|
||||
}
|
||||
err = device_property_read_u32(dev, "size", &size);
|
||||
if (err)
|
||||
...error handling...
|
||||
|
||||
Then the at25 SPI driver can get this configuration by calling _DSM on its
|
||||
ACPI handle like::
|
||||
err = device_property_read_u32(dev, "pagesize", &page_size);
|
||||
if (err)
|
||||
...error handling...
|
||||
|
||||
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);
|
||||
err = device_property_read_u32(dev, "address-width", &addr_width);
|
||||
if (err)
|
||||
...error handling...
|
||||
|
||||
I2C serial bus support
|
||||
======================
|
||||
|
@ -237,26 +228,24 @@ 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),
|
||||
.acpi_match_table = mpu3050_acpi_match,
|
||||
},
|
||||
.probe = mpu3050_probe,
|
||||
.remove = mpu3050_remove,
|
||||
.id_table = mpu3050_ids,
|
||||
};
|
||||
module_i2c_driver(mpu3050_i2c_driver);
|
||||
|
||||
Reference to PWM device
|
||||
=======================
|
||||
|
@ -282,9 +271,9 @@ introduced, i.e.::
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
...
|
||||
}
|
||||
|
||||
In the above example the PWM-based LED driver references to the PWM channel 0
|
||||
of \_SB.PCI0.PWM device with initial period setting equal to 600 ms (note that
|
||||
|
@ -306,26 +295,13 @@ For example::
|
|||
{
|
||||
Name (SBUF, ResourceTemplate()
|
||||
{
|
||||
...
|
||||
// Used to power on/off the device
|
||||
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
|
||||
IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
|
||||
0x00, ResourceConsumer,,)
|
||||
{
|
||||
// Pin List
|
||||
0x0055
|
||||
}
|
||||
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.PCI0.GPI0", 0, ResourceConsumer) { 85 }
|
||||
|
||||
// Interrupt for the device
|
||||
GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone,
|
||||
0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
|
||||
{
|
||||
// Pin list
|
||||
0x0058
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone, 0,
|
||||
"\\_SB.PCI0.GPI0", 0, ResourceConsumer) { 88 }
|
||||
}
|
||||
|
||||
Return (SBUF)
|
||||
|
@ -337,11 +313,12 @@ For example::
|
|||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package ()
|
||||
{
|
||||
Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }},
|
||||
Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }},
|
||||
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
|
||||
|
@ -460,10 +437,10 @@ namespace link::
|
|||
Device (TMP0)
|
||||
{
|
||||
Name (_HID, "PRP0001")
|
||||
Name (_DSD, Package() {
|
||||
Name (_DSD, Package () {
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package (2) { "compatible", "ti,tmp75" },
|
||||
Package () { "compatible", "ti,tmp75" },
|
||||
}
|
||||
})
|
||||
Method (_CRS, 0, Serialized)
|
||||
|
|
|
@ -21,18 +21,18 @@ index, like the ASL example below shows::
|
|||
Name (_CRS, ResourceTemplate ()
|
||||
{
|
||||
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) {15}
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) { 15 }
|
||||
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) {27, 31}
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) { 27, 31 }
|
||||
})
|
||||
|
||||
Name (_DSD, Package ()
|
||||
{
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package ()
|
||||
{
|
||||
Package () {"reset-gpios", Package() {^BTH, 1, 1, 0 }},
|
||||
Package () {"shutdown-gpios", Package() {^BTH, 0, 0, 0 }},
|
||||
{
|
||||
Package () { "reset-gpios", Package () { ^BTH, 1, 1, 0 } },
|
||||
Package () { "shutdown-gpios", Package () { ^BTH, 0, 0, 0 } },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -123,17 +123,17 @@ Example::
|
|||
// _DSD Hierarchical Properties Extension UUID
|
||||
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
||||
Package () {
|
||||
Package () {"hog-gpio8", "G8PU"}
|
||||
Package () { "hog-gpio8", "G8PU" }
|
||||
}
|
||||
})
|
||||
|
||||
Name (G8PU, Package () {
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package () {"gpio-hog", 1},
|
||||
Package () {"gpios", Package () {8, 0}},
|
||||
Package () {"output-high", 1},
|
||||
Package () {"line-name", "gpio8-pullup"},
|
||||
Package () { "gpio-hog", 1 },
|
||||
Package () { "gpios", Package () { 8, 0 } },
|
||||
Package () { "output-high", 1 },
|
||||
Package () { "line-name", "gpio8-pullup" },
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -266,15 +266,17 @@ have a device like below::
|
|||
|
||||
Name (_CRS, ResourceTemplate () {
|
||||
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) {15}
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) { 15 }
|
||||
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) {27}
|
||||
"\\_SB.GPO0", 0, ResourceConsumer) { 27 }
|
||||
})
|
||||
}
|
||||
|
||||
The driver might expect to get the right GPIO when it does::
|
||||
|
||||
desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(desc))
|
||||
...error handling...
|
||||
|
||||
but since there is no way to know the mapping between "reset" and
|
||||
the GpioIo() in _CRS desc will hold ERR_PTR(-ENOENT).
|
||||
|
|
Loading…
Reference in a new issue