aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-10-17 18:13:58 +0300
committerGraeme Gregory <graeme.gregory@linaro.org>2014-06-03 09:24:29 +0100
commit331f5103b4d3aa39e705dc35e61a9f6582eb7875 (patch)
treef320faf23f2bbba48c73b2d1227908656aeddd26
parentfa5075f70217fabaf1fb0c53ae31e8d267bfea5a (diff)
downloadleg-kernel-331f5103b4d3aa39e705dc35e61a9f6582eb7875.tar.gz
ACPICA: Add acpi_get_properties() public interface
In order to support extracting Device Tree style properties from ACPI devices a new method _PRP was introduced. This method, when present, is expected to return a package containing packages with name-value pairs analogous to their Device Tree counterparts. A sample _PRP method migh look like this: Method (_PRP, 0, NotSerialized) { Return (Package () { Package () { "integer-property", 10 }, Package () { "string-property", "mystring" }, }) } Calling acpi_get_properties() will evaluate the _PRP method, validate the result and return it to the caller if everything went fine. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-rw-r--r--drivers/acpi/acpica/Makefile2
-rw-r--r--drivers/acpi/acpica/prxface.c217
-rw-r--r--include/acpi/acnames.h1
-rw-r--r--include/acpi/acpixf.h6
4 files changed, 226 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index b7ed86a20427..4a0d60deb082 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -176,3 +176,5 @@ acpi-y += \
acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o
+acpi-y += \
+ prxface.o
diff --git a/drivers/acpi/acpica/prxface.c b/drivers/acpi/acpica/prxface.c
new file mode 100644
index 000000000000..4e52b5143374
--- /dev/null
+++ b/drivers/acpi/acpica/prxface.c
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ *
+ * Module Name: prxface - Public interface to ACPI device properties
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <linux/export.h>
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+
+#define _COMPONENT ACPI_RESOURCES
+ACPI_MODULE_NAME("prxface")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_pr_validate_parameters
+ *
+ * PARAMETERS: device_handle - Handle to a device
+ * buffer - Pointer to a data buffer
+ * return_node - Pointer to where the device node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Checks validity of the parameters passed to
+ * acpi_get_device_properties().
+ *
+ ******************************************************************************/
+static acpi_status
+acpi_pr_validate_parameters(acpi_handle device_handle,
+ struct acpi_buffer *buffer,
+ struct acpi_namespace_node **return_node)
+{
+ struct acpi_namespace_node *node;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_pr_validate_parameters);
+
+ if (!device_handle) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ node = acpi_ns_validate_handle(device_handle);
+ if (!node) {
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+ }
+
+ if (node->type != ACPI_TYPE_DEVICE) {
+ return_ACPI_STATUS(AE_TYPE);
+ }
+
+ /* Make sure the buffer is valid */
+ status = acpi_ut_validate_buffer(buffer);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ *return_node = node;
+ return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_get_prp_method_data
+ *
+ * PARAMETERS: node - Device node
+ * ret_buffer - Pointer to a buffer structure where the
+ * resulting properties are stored
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to evaluate _PRP method for a given
+ * device. In case of success resulting package is stored in
+ * ret_buffer.
+ *
+ * If the function fails an appropriate status will be returned and
+ * the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+static acpi_status
+acpi_pr_get_prp_method_data(struct acpi_namespace_node *node,
+ struct acpi_buffer *ret_buffer)
+{
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object **properties;
+ acpi_status status;
+ acpi_size size;
+ int i;
+
+ ACPI_FUNCTION_TRACE(acpi_pr_get_prp_method_data);
+
+ status = acpi_ut_evaluate_object(node, METHOD_NAME__PRP,
+ ACPI_BTYPE_PACKAGE, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * Validate that the returned package is in correct format:
+ * 1) Each property is a package itself holding { key, value }
+ * 2) Key is mandatory
+ * 3) Key must be string.
+ */
+ properties = obj_desc->package.elements;
+ for (i = 0; i < obj_desc->package.count; i++) {
+ union acpi_operand_object **property;
+
+ if (properties[i]->common.type != ACPI_TYPE_PACKAGE) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
+ if (properties[i]->package.count < 1) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
+
+ property = properties[i]->package.elements;
+ if (property[0]->common.type != ACPI_TYPE_STRING) {
+ status = AE_BAD_DATA;
+ goto out;
+ }
+ }
+
+ /* Copy the internal buffer to ret_buffer */
+ status = acpi_ut_get_object_size(obj_desc, &size);
+ if (ACPI_FAILURE(status)) {
+ goto out;
+ }
+
+ status = acpi_ut_initialize_buffer(ret_buffer, size);
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_ut_copy_iobject_to_eobject(obj_desc, ret_buffer);
+ }
+
+ out:
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_get_properties
+ *
+ * PARAMETERS: device_handle - Handle to the device object for the
+ * device we are querying
+ * ret_buffer - Pointer to a buffer to receive the
+ * properties for the device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get properties for
+ * a specific device The caller must first acquire a handle for the
+ * desired device The property data is placed in the buffer pointed
+ * to by the ret_buffer variable parameter.
+ *
+ * If the function fails an appropriate status will be returned
+ * and the value of ret_buffer is undefined.
+ *
+ * This function attempts to execute the _PRP method contained in
+ * the object indicated by the passed device_handle.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_properties(acpi_handle device_handle, struct acpi_buffer *ret_buffer)
+{
+ struct acpi_namespace_node *node;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_get_device_properties);
+
+ status = acpi_pr_validate_parameters(device_handle, ret_buffer, &node);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ status = acpi_pr_get_prp_method_data(node, ret_buffer);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_properties)
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index 3dd6e838dc30..ac7e598c8b43 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -65,6 +65,7 @@
#define METHOD_NAME__STA "_STA"
#define METHOD_NAME__SUB "_SUB"
#define METHOD_NAME__UID "_UID"
+#define METHOD_NAME__PRP "_PRP"
/* Method names - these methods must appear at the namespace root */
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 44f5e9749601..c8c0748887b5 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -478,6 +478,12 @@ acpi_buffer_to_resource(u8 *aml_buffer,
struct acpi_resource **resource_ptr);
/*
+ * ACPI device properties
+ */
+acpi_status
+acpi_get_properties(acpi_handle device_handle, struct acpi_buffer *ret_buffer);
+
+/*
* Hardware (ACPI device) interfaces
*/
acpi_status acpi_reset(void);