diff mbox

[04/13] ACPI: Document ACPI device specific properties

Message ID 4876377.qMEam54Cox@vostro.rjw.lan (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Rafael J. Wysocki Oct. 7, 2014, 12:14 a.m. UTC
From: Mika Westerberg <mika.westerberg@linux.intel.com>

This document describes the data format and interfaces of ACPI device
specific properties.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 Documentation/acpi/properties.txt |  376 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 376 insertions(+)
 create mode 100644 Documentation/acpi/properties.txt


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Grant Likely Oct. 13, 2014, 12:41 p.m. UTC | #1
On Tue, 07 Oct 2014 02:14:06 +0200
, "Rafael J. Wysocki" <rjw@rjwysocki.net>
 wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> This document describes the data format and interfaces of ACPI device
> specific properties.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  Documentation/acpi/properties.txt |  376 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 376 insertions(+)
>  create mode 100644 Documentation/acpi/properties.txt
> 
> Index: linux-pm/Documentation/acpi/properties.txt
> ===================================================================
> --- /dev/null
> +++ linux-pm/Documentation/acpi/properties.txt
> @@ -0,0 +1,376 @@
> +ACPI device properties
> +======================
> +This document describes the format and interfaces of ACPI device
> +properties as specified in "Device Properties UUID For _DSD" available
> +here:
> +
> +http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> +
> +1. Introduction
> +---------------
> +In systems that use ACPI and want to take advantage of device specific
> +properties, there needs to be a standard way to return and extract
> +name-value pairs for a given ACPI device.
> +
> +An ACPI device that wants to export its properties must implement a
> +static name called _DSD that takes no arguments and returns a package of
> +packages:
> +
> +	Name (_DSD, Package () {
> +		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +		Package () {
> +			Package () {"name1", <VALUE1>},
> +			Package () {"name2", <VALUE2>}
> +		}
> +	})
> +
> +The UUID identifies contents of the following package. In case of ACPI
> +device properties it is daffd814-6eba-4d8c-8a91-bc9bbf4aa301.
> +
> +In each returned package, the first item is the name and must be a string.
> +The corresponding value can be a string, integer, reference, or package. If
> +a package it may only contain strings, integers, and references.
> +
> +An example device where we might need properties is a device that uses
> +GPIOs. In addition to the GpioIo/GpioInt resources the driver needs to
> +know which GPIO is used for which purpose.
> +
> +To solve this we add the following ACPI device properties to the device:
> +
> +	Device (DEV0)
> +	{
> +		Name (_CRS, ResourceTemplate () {
> +			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
> +				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
> +			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
> +				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
> +			...
> +		})
> +
> +		Name (_DSD, Package () {
> +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +			Package () {
> +				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
> +				Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
> +			}
> +		})
> +	}
> +
> +Now the device driver can reference the GPIOs using names instead of
> +using indexes.

Ummm... so this is kind of odd. Why would arguments be needed for the
gpio reference, or a device trying to reference itself (^DEV0) within
it's own device.

It looks like it is trying to shoehorn DT design patterns into the ACPI
tables when ACPI already has a native method for doing the same thing.
That concerns me.

[...]
> +In addition to simple object references it is also possible to have object
> +references with arguments. These are represented in ASL as follows:
> +
> +	Device (\_SB.PCI0.PWM)
> +	{
> +		Name (_DSD, Package () {
> +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +			Package () {
> +				Package () {"#pwm-cells", 2}
> +			}
> +		})
> +	}
> +
> +	Device (\_SB.PCI0.BL)
> +	{
> +		Name (_DSD, Package () {
> +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +			Package () {
> +				Package () {
> +					"pwms",
> +					Package () {
> +						\_SB.PCI0.PWM, 0, 5000000,
> +						\_SB.PCI0.PWM, 1, 4500000,
> +					}
> +				}
> +			}
> +		})
> +	}

This worries me even more. #x-cells is a very devicetree oriented
pattern that looks wrong for ACPI data. I would expect PWM resources in
ACPI to look much like ACPI GPIO resources or Serial bus resources.

g.

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mika Westerberg Oct. 14, 2014, 9:42 a.m. UTC | #2
On Mon, Oct 13, 2014 at 02:41:32PM +0200, Grant Likely wrote:
> On Tue, 07 Oct 2014 02:14:06 +0200
> , "Rafael J. Wysocki" <rjw@rjwysocki.net>
>  wrote:
> > From: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > This document describes the data format and interfaces of ACPI device
> > specific properties.
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Signed-off-by: Darren Hart <dvhart@linux.intel.com>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  Documentation/acpi/properties.txt |  376 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 376 insertions(+)
> >  create mode 100644 Documentation/acpi/properties.txt
> > 
> > Index: linux-pm/Documentation/acpi/properties.txt
> > ===================================================================
> > --- /dev/null
> > +++ linux-pm/Documentation/acpi/properties.txt
> > @@ -0,0 +1,376 @@
> > +ACPI device properties
> > +======================
> > +This document describes the format and interfaces of ACPI device
> > +properties as specified in "Device Properties UUID For _DSD" available
> > +here:
> > +
> > +http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
> > +
> > +1. Introduction
> > +---------------
> > +In systems that use ACPI and want to take advantage of device specific
> > +properties, there needs to be a standard way to return and extract
> > +name-value pairs for a given ACPI device.
> > +
> > +An ACPI device that wants to export its properties must implement a
> > +static name called _DSD that takes no arguments and returns a package of
> > +packages:
> > +
> > +	Name (_DSD, Package () {
> > +		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +		Package () {
> > +			Package () {"name1", <VALUE1>},
> > +			Package () {"name2", <VALUE2>}
> > +		}
> > +	})
> > +
> > +The UUID identifies contents of the following package. In case of ACPI
> > +device properties it is daffd814-6eba-4d8c-8a91-bc9bbf4aa301.
> > +
> > +In each returned package, the first item is the name and must be a string.
> > +The corresponding value can be a string, integer, reference, or package. If
> > +a package it may only contain strings, integers, and references.
> > +
> > +An example device where we might need properties is a device that uses
> > +GPIOs. In addition to the GpioIo/GpioInt resources the driver needs to
> > +know which GPIO is used for which purpose.
> > +
> > +To solve this we add the following ACPI device properties to the device:
> > +
> > +	Device (DEV0)
> > +	{
> > +		Name (_CRS, ResourceTemplate () {
> > +			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
> > +				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
> > +			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
> > +				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
> > +			...
> > +		})
> > +
> > +		Name (_DSD, Package () {
> > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +			Package () {
> > +				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
> > +				Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
> > +			}
> > +		})
> > +	}
> > +
> > +Now the device driver can reference the GPIOs using names instead of
> > +using indexes.
> 
> Ummm... so this is kind of odd. Why would arguments be needed for the
> gpio reference, or a device trying to reference itself (^DEV0) within
> it's own device.

The reference doesn't need to be the device itself. It can be the parent
device for example.

Also arguments contain information that is not available in ACPI GpioIo
resources:

 - Name of the GPIO
 - Is the GPIO active low

Remember that we can write the above also like:

		Name (_CRS, ResourceTemplate () {
			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0, 1}
			...
		})

		Name (_DSD, Package () {
			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
			Package () {
				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
				Package () {"shutdown-gpio", {^DEV0, 0, 1, 0}},
			}
		})

So the first two integers are used as indexes in _CRS and in the
pinlist.

> It looks like it is trying to shoehorn DT design patterns into the ACPI
> tables when ACPI already has a native method for doing the same thing.
> That concerns me.

There is no native method in ACPI to do what we are doing.

> [...]
> > +In addition to simple object references it is also possible to have object
> > +references with arguments. These are represented in ASL as follows:
> > +
> > +	Device (\_SB.PCI0.PWM)
> > +	{
> > +		Name (_DSD, Package () {
> > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +			Package () {
> > +				Package () {"#pwm-cells", 2}
> > +			}
> > +		})
> > +	}
> > +
> > +	Device (\_SB.PCI0.BL)
> > +	{
> > +		Name (_DSD, Package () {
> > +			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > +			Package () {
> > +				Package () {
> > +					"pwms",
> > +					Package () {
> > +						\_SB.PCI0.PWM, 0, 5000000,
> > +						\_SB.PCI0.PWM, 1, 4500000,
> > +					}
> > +				}
> > +			}
> > +		})
> > +	}
> 
> This worries me even more. #x-cells is a very devicetree oriented
> pattern that looks wrong for ACPI data. I would expect PWM resources in
> ACPI to look much like ACPI GPIO resources or Serial bus resources.

This was already discussed in v3 version of the series and our argument
here is that we should be able to reuse the existing DT schemas as much
as possible as long as ACPI does not have a native method to describe
the thing (and it makes sense in general).

However, nothing prevents us to extend the
acpi_dev_get_property_reference() in future to support a more ACPI style
way of doing things:

http://www.spinics.net/lists/linux-acpi/msg53367.html
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Index: linux-pm/Documentation/acpi/properties.txt
===================================================================
--- /dev/null
+++ linux-pm/Documentation/acpi/properties.txt
@@ -0,0 +1,376 @@ 
+ACPI device properties
+======================
+This document describes the format and interfaces of ACPI device
+properties as specified in "Device Properties UUID For _DSD" available
+here:
+
+http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
+
+1. Introduction
+---------------
+In systems that use ACPI and want to take advantage of device specific
+properties, there needs to be a standard way to return and extract
+name-value pairs for a given ACPI device.
+
+An ACPI device that wants to export its properties must implement a
+static name called _DSD that takes no arguments and returns a package of
+packages:
+
+	Name (_DSD, Package () {
+		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+		Package () {
+			Package () {"name1", <VALUE1>},
+			Package () {"name2", <VALUE2>}
+		}
+	})
+
+The UUID identifies contents of the following package. In case of ACPI
+device properties it is daffd814-6eba-4d8c-8a91-bc9bbf4aa301.
+
+In each returned package, the first item is the name and must be a string.
+The corresponding value can be a string, integer, reference, or package. If
+a package it may only contain strings, integers, and references.
+
+An example device where we might need properties is a device that uses
+GPIOs. In addition to the GpioIo/GpioInt resources the driver needs to
+know which GPIO is used for which purpose.
+
+To solve this we add the following ACPI device properties to the device:
+
+	Device (DEV0)
+	{
+		Name (_CRS, ResourceTemplate () {
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+			...
+		})
+
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
+				Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
+			}
+		})
+	}
+
+Now the device driver can reference the GPIOs using names instead of
+using indexes.
+
+If there is an existing Device Tree binding for a device, it is expected
+that the same bindings are used with ACPI properties, so that the driver
+dealing with the device needs only minor modifications if any.
+
+2. Formal definition of properties
+----------------------------------
+The following chapters define the currently supported properties. For
+these there exists a helper function that can be used to extract the
+property value.
+
+2.1 Integer types
+-----------------
+ACPI integers are always 64-bit. However, for drivers the full range is
+typically not needed so we provide a set of functions which convert the
+64-bit integer to a smaller Linux integer type.
+
+An integer property looks like this:
+
+	Package () {"i2c-sda-hold-time-ns", 300},
+	Package () {"clock-frequency", 400000},
+
+To read a property value, use a unified property accessor as shown
+below:
+
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, "clock-frequency", &val);
+	if (ret)
+		/* Handle error */
+
+The function returns 0 if the property is copied to 'val' or negative
+errno if something went wrong (or the property does not exist).
+
+2.2 Integer arrays
+------------------
+An integer array is a package holding only integers. Arrays can be used to
+represent different things like Linux input key codes to GPIO mappings, pin
+control settings, dma request lines, etc.
+
+An integer array looks like this:
+
+	Package () {
+		"max8952,dvs-mode-microvolt",
+		Package () {
+			1250000,
+			1200000,
+			1050000,
+			950000,
+		}
+	}
+
+The above array property can be accessed like:
+
+	u32 voltages[4];
+	int ret;
+
+	ret = device_property_read_u32_array(dev, "max8952,dvs-mode-microvolt",
+					     voltages, ARRAY_SIZE(voltages));
+	if (ret)
+		/* Handle error */
+
+
+All functions copy the resulting values cast to a requested type to the
+caller supplied array. If you pass NULL in the value pointer ('voltages' in
+this case), the function returns number of items in the array. This can be
+useful if caller does not know size of the array beforehand.
+
+2.3 Strings
+-----------
+String properties can be used to describe many things like labels for GPIO
+buttons, compability ids, etc.
+
+A string property looks like this:
+
+	Package () {"name", "value"},
+	Package () {"label", "Status-LED"},
+
+You can use device_property_read_string() to extract strings:
+
+	const char *val;
+	int ret;
+
+	ret = device_property_read_string(dev, "label", &val);
+	if (ret)
+		/* Handle error */
+
+Note that the function does not copy the returned string but instead the
+value is modified to point to the string property itself.
+
+The memory is owned by the associated ACPI device object and released
+when it is removed. The user need not free the associated memory.
+
+2.4 String arrays
+-----------------
+String arrays can be useful in describing a list of labels, names for
+DMA channels, etc.
+
+A string array property looks like this:
+
+	Package () {"dma-names", Package () {"tx", "rx", "rx-tx"}},
+	Package () {"clock-output-names", Package () {"pll", "pll-switched"}},
+
+And these can be read in similar way that the integer arrrays:
+
+	const char *dma_names[3];
+	int ret;
+
+	ret = device_property_read_string_array(dev, "dma-names", dma_names,
+						ARRAY_SIZE(dma_names));
+	if (ret)
+		/* Handle error */
+
+The memory management rules follow what is specified for single strings.
+Specifically the returned pointers should be treated as constant and not to
+be freed. That is done automatically when the correspondig ACPI device
+object is released.
+
+2.5 Object references
+---------------------
+An ACPI object reference is used to refer to some object in the
+namespace. For example, if a device has dependencies with some other
+object, an object reference can be used.
+
+An object reference looks like this:
+
+	Package () {"dev0", \_SB.DEV0},
+
+At the time of writing this, there is no unified device_property_* accessor
+for references so one needs to use the following ACPI helper function:
+
+	int acpi_dev_get_property_reference(struct acpi_device *adev,
+					    const char *name,
+					    const char *size_prop, int index,
+					    struct acpi_reference_args *args);
+
+The referenced ACPI device is returned in args->adev if found.
+
+In addition to simple object references it is also possible to have object
+references with arguments. These are represented in ASL as follows:
+
+	Device (\_SB.PCI0.PWM)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"#pwm-cells", 2}
+			}
+		})
+	}
+
+	Device (\_SB.PCI0.BL)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {
+					"pwms",
+					Package () {
+						\_SB.PCI0.PWM, 0, 5000000,
+						\_SB.PCI0.PWM, 1, 4500000,
+					}
+				}
+			}
+		})
+	}
+
+In the above example, the referenced device declares a property that
+returns the number of expected arguments (here it is "#pwm-cells"). If
+no such property is given we assume that all the integers following the
+reference are arguments.
+
+In the above example PWM device expects 2 additional arguments. This
+will be validated by the ACPI property core.
+
+The additional arguments must be integers. Nothing else is supported.
+
+It is possible, as in the above example, to have multiple references
+with varying number of integer arguments. It is up to the referenced
+device to declare how many arguments it expects. The 'index' parameter
+selects which reference is returned.
+
+One can use acpi_dev_get_property_reference() as well to extract the
+information in additional parameters:
+
+	struct acpi_reference_args args;
+	struct acpi_device *adev = /* this will point to the BL device */
+	int ret;
+
+	/* extract the first reference */
+	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 0, &args);
+
+	BUG_ON(args.nargs != 2);
+	BUG_ON(args.args[0] != 0);
+	BUG_ON(args.args[1] != 5000000);
+
+	/* extract the second reference */
+	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 1, &args);
+
+	BUG_ON(args.nargs != 2);
+	BUG_ON(args.args[0] != 1);
+	BUG_ON(args.args[1] != 4500000);
+
+In addition to arguments, args.adev now points to the ACPI device that
+corresponds to \_SB.PCI0.PWM.
+
+It is intended that this function is not used directly but instead
+subsystems like pwm implement their ACPI support on top of this function
+in such way that it is hidden from the client drivers, such as via
+pwm_get().
+
+3. Device property hierarchies
+------------------------------
+Devices are organized in a tree within the Linux kernel. It follows that
+the configuration data would also be hierarchical. In order to reach
+equivalence with Device Tree, the ACPI mechanism must also provide some
+sort of tree-like representation. Fortunately, the ACPI namespace is
+already such a structure.
+
+For example, we could have the following device in ACPI namespace. The
+KEYS device is much like gpio_keys_polled.c in that it includes "pseudo"
+devices for each GPIO:
+
+	Device (KEYS)
+	{
+		Name (_CRS, ResourceTemplate () {
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
+			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
+			...
+		})
+
+		// "pseudo" devices declared under the parent device
+		Device (BTN0) {
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"label", "minnow_btn0"}
+					Package () {"gpios", Package () {^KEYS, 0, 0, 1}}
+				}
+			})
+		}
+
+		Device (BTN1) {
+			Name (_DSD, Package () {
+				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+				Package () {
+					Package () {"label", "minnow_btn1"}
+					Package () {"gpios", Package () {^KEYS, 1, 0, 1}}
+				}
+			})
+		}
+	}
+
+We can extract the above in gpio_keys_polled.c like:
+
+	static void gpio_keys_polled_probe(struct device *dev)
+	{
+		void *child;
+
+		/* Properties for the KEYS device itself */
+		device_property_read(dev, ...);
+
+		/*
+		 * Iterate over button devices and extract their
+		 * firmware configuration.
+		 */
+		device_for_each_child_node(dev, child) {
+			const char *label = NULL;
+
+			/*
+			 * We need to use device_child_ variant here to access
+			 * properties of the child.
+			 */
+			device_child_property_read_string(dev, child, "label", &label);
+			/* and so on */
+		}
+	}
+
+Note that you still need proper error handling which is omitted in the
+above example.
+
+4. Existing Device Tree enabled drivers
+---------------------------------------
+At the time of writing this, there are ~250 existing DT enabled drivers.
+Allocating _HID/_CID for each would not be feasible. To make sure that
+those drivers can still be used on ACPI systems, we provide an
+alternative way to get these matched.
+
+There is a special _HID "PRP0001" which means that use the DT bindings
+for matching this device to a driver. The driver needs to have
+.of_match_table filled in even when !CONFIG_OF.
+
+An example device would be leds that can be controlled via GPIOs. This
+is represented as "leds-gpio" device and looks like this in the ACPI
+namespace:
+
+	Device (LEDS)
+	{
+		Name (_DSD, Package () {
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package () {
+				Package () {"compatible", Package () {"gpio-leds"}},
+			}
+		})
+		...
+	}
+
+Once ACPI core sees "PRP0001" and that the device has "compatible"
+property it will do the match using .of_match_table instead if the
+driver does not have .acpi_match_table.
+
+It is preferred that new devices get a proper _HID allocated for them
+instead of inventing new DT "compatible" devices.