devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
To: linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: sudeep.holla-5wv7dgnIgG8@public.gmane.org,
	lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org,
	mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
	rafael-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	mark.rutland-5wv7dgnIgG8@public.gmane.org,
	broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	ahs3-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Subject: [PATCH v4 01/16] ACPI / property: Add possiblity to retrieve parent firmware node
Date: Mon,  6 Mar 2017 16:19:15 +0200	[thread overview]
Message-ID: <1488809970-25568-2-git-send-email-sakari.ailus@linux.intel.com> (raw)
In-Reply-To: <1488809970-25568-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

From: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Sometimes it is useful to be able to navigate firmware node hierarchy
upwards toward parent nodes. ACPI device nodes are pretty much already
supported because ACPICA provides acpi_get_parent(). ACPI data nodes,
however, are all below the same parent ACPI device. Their hierarchy is
created by "linking" each other using references in the value field.

Add parent pointer to the parent data node while we create them so it is
easy to navigate the hierarchy backwards. We use this parent pointer in a
new function acpi_node_get_parent() that is able to extract parent of both
ACPI firmware node types.

Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
 drivers/acpi/property.c | 72 ++++++++++++++++++++++++++++++++++++++-----------
 include/acpi/acpi_bus.h |  1 +
 include/linux/acpi.h    |  7 +++++
 3 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 3afddcd..587c9d0 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -37,14 +37,16 @@ static const u8 ads_uuid[16] = {
 
 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
 					   const union acpi_object *desc,
-					   struct acpi_device_data *data);
+					   struct acpi_device_data *data,
+					   struct fwnode_handle *parent);
 static bool acpi_extract_properties(const union acpi_object *desc,
 				    struct acpi_device_data *data);
 
 static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
 					acpi_handle handle,
 					const union acpi_object *link,
-					struct list_head *list)
+					struct list_head *list,
+					struct fwnode_handle *parent)
 {
 	struct acpi_data_node *dn;
 	bool result;
@@ -55,6 +57,7 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
 
 	dn->name = link->package.elements[0].string.pointer;
 	dn->fwnode.type = FWNODE_ACPI_DATA;
+	dn->parent = parent;
 	INIT_LIST_HEAD(&dn->data.subnodes);
 
 	result = acpi_extract_properties(desc, &dn->data);
@@ -71,9 +74,11 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
 		 */
 		status = acpi_get_parent(handle, &scope);
 		if (ACPI_SUCCESS(status)
-		    && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data))
+		    && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data,
+						      &dn->fwnode))
 			result = true;
-	} else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data)) {
+	} else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data,
+						  &dn->fwnode)) {
 		result = true;
 	}
 
@@ -91,7 +96,8 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
 
 static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
 					const union acpi_object *link,
-					struct list_head *list)
+					struct list_head *list,
+					struct fwnode_handle *parent)
 {
 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
 	acpi_status status;
@@ -101,7 +107,8 @@ static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
 	if (ACPI_FAILURE(status))
 		return false;
 
-	if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list))
+	if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list,
+					parent))
 		return true;
 
 	ACPI_FREE(buf.pointer);
@@ -110,7 +117,8 @@ static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
 
 static bool acpi_nondev_subnode_ok(acpi_handle scope,
 				   const union acpi_object *link,
-				   struct list_head *list)
+				   struct list_head *list,
+				   struct fwnode_handle *parent)
 {
 	acpi_handle handle;
 	acpi_status status;
@@ -123,12 +131,13 @@ static bool acpi_nondev_subnode_ok(acpi_handle scope,
 	if (ACPI_FAILURE(status))
 		return false;
 
-	return acpi_nondev_subnode_data_ok(handle, link, list);
+	return acpi_nondev_subnode_data_ok(handle, link, list, parent);
 }
 
 static int acpi_add_nondev_subnodes(acpi_handle scope,
 				    const union acpi_object *links,
-				    struct list_head *list)
+				    struct list_head *list,
+				    struct fwnode_handle *parent)
 {
 	bool ret = false;
 	int i;
@@ -150,15 +159,18 @@ static int acpi_add_nondev_subnodes(acpi_handle scope,
 		/* The second one may be a string, a reference or a package. */
 		switch (link->package.elements[1].type) {
 		case ACPI_TYPE_STRING:
-			result = acpi_nondev_subnode_ok(scope, link, list);
+			result = acpi_nondev_subnode_ok(scope, link, list,
+							 parent);
 			break;
 		case ACPI_TYPE_LOCAL_REFERENCE:
 			handle = link->package.elements[1].reference.handle;
-			result = acpi_nondev_subnode_data_ok(handle, link, list);
+			result = acpi_nondev_subnode_data_ok(handle, link, list,
+							     parent);
 			break;
 		case ACPI_TYPE_PACKAGE:
 			desc = &link->package.elements[1];
-			result = acpi_nondev_subnode_extract(desc, NULL, link, list);
+			result = acpi_nondev_subnode_extract(desc, NULL, link,
+							     list, parent);
 			break;
 		default:
 			result = false;
@@ -172,7 +184,8 @@ static int acpi_add_nondev_subnodes(acpi_handle scope,
 
 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
 					   const union acpi_object *desc,
-					   struct acpi_device_data *data)
+					   struct acpi_device_data *data,
+					   struct fwnode_handle *parent)
 {
 	int i;
 
@@ -194,7 +207,8 @@ static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
 		if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid)))
 			continue;
 
-		return acpi_add_nondev_subnodes(scope, links, &data->subnodes);
+		return acpi_add_nondev_subnodes(scope, links, &data->subnodes,
+						parent);
 	}
 
 	return false;
@@ -345,7 +359,8 @@ void acpi_init_properties(struct acpi_device *adev)
 		if (acpi_of)
 			acpi_init_of_compatible(adev);
 	}
-	if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data))
+	if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer,
+					&adev->data, acpi_fwnode_handle(adev)))
 		adev->data.pointer = buf.pointer;
 
 	if (!adev->data.pointer) {
@@ -920,3 +935,30 @@ struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 	}
 	return NULL;
 }
+
+/**
+ * acpi_node_get_parent - Return parent fwnode of this fwnode
+ * @fwnode: Firmware node whose parent to get
+ *
+ * Returns parent node of an ACPI device or data firmware node or %NULL if
+ * not available.
+ */
+struct fwnode_handle *acpi_node_get_parent(struct fwnode_handle *fwnode)
+{
+	if (is_acpi_data_node(fwnode)) {
+		/* All data nodes have parent pointer so just return that */
+		return to_acpi_data_node(fwnode)->parent;
+	} else if (is_acpi_device_node(fwnode)) {
+		acpi_handle handle, parent_handle;
+
+		handle = to_acpi_device_node(fwnode)->handle;
+		if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) {
+			struct acpi_device *adev;
+
+			if (!acpi_bus_get_device(parent_handle, &adev))
+				return acpi_fwnode_handle(adev);
+		}
+	}
+
+	return NULL;
+}
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ef0ae8a..49cca52 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -386,6 +386,7 @@ struct acpi_data_node {
 	const char *name;
 	acpi_handle handle;
 	struct fwnode_handle fwnode;
+	struct fwnode_handle *parent;
 	struct acpi_device_data data;
 	struct list_head sibling;
 	struct kobject kobj;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 673acda..a6f1b74 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1002,6 +1002,7 @@ int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
 
 struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 					    struct fwnode_handle *subnode);
+struct fwnode_handle *acpi_node_get_parent(struct fwnode_handle *fwnode);
 
 struct acpi_probe_entry;
 typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *,
@@ -1124,6 +1125,12 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 	return NULL;
 }
 
+static inline struct fwnode_handle *
+acpi_node_get_parent(struct fwnode_handle *fwnode)
+{
+	return NULL;
+}
+
 #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn) \
 	static const void * __acpi_table_##name[]			\
 		__attribute__((unused))					\
-- 
2.7.4

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

  parent reply	other threads:[~2017-03-06 14:19 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-06 14:19 [PATCH v4 00/16] Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 02/16] device property: Add fwnode_get_parent() Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 03/16] ACPI / property: Add fwnode_get_next_child_node() Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 04/16] device property: Add fwnode_get_named_child_node() Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 06/16] device property: Add support for remote endpoints Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 08/16] of: Add of_fwnode_handle() to convert device nodes to fwnode_handle Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 10/16] irqchip/gic: Add missing forward declaration for struct device Sakari Ailus
2017-03-13 21:45   ` Rafael J. Wysocki
2017-03-06 14:19 ` [PATCH v4 11/16] of: No need to include linux/property.h, linux/fwnode.h is sufficient Sakari Ailus
2017-03-13 21:46   ` Rafael J. Wysocki
2017-03-15 13:58     ` Sakari Ailus
     [not found] ` <1488809970-25568-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2017-03-06 14:19   ` Sakari Ailus [this message]
2017-03-06 14:19   ` [PATCH v4 05/16] ACPI / property: Add support for remote endpoints Sakari Ailus
2017-03-06 14:19   ` [PATCH v4 07/16] device property: Add fwnode_handle_get() Sakari Ailus
2017-03-06 14:19   ` [PATCH v4 09/16] driver core: Arrange headers alphabetically Sakari Ailus
2017-03-06 14:19   ` [PATCH v4 12/16] device property: Move dev_fwnode() to linux/property.h Sakari Ailus
2017-03-13 21:49     ` Rafael J. Wysocki
     [not found]       ` <5262143.K42JDpMSHF-yvgW3jdyMHm1GS7QM15AGw@public.gmane.org>
2017-03-14  7:28         ` Sakari Ailus
2017-03-06 14:19   ` [PATCH v4 13/16] device property: Add support for fwnode endpoints Sakari Ailus
2017-03-13 21:52     ` Rafael J. Wysocki
2017-03-14  7:46       ` Sakari Ailus
2017-03-06 14:19   ` [PATCH v4 14/16] of: Add nop implementation of of_get_next_parent() Sakari Ailus
2017-03-13 21:55     ` Rafael J. Wysocki
2017-03-17 12:10       ` Sakari Ailus
2017-03-06 14:19   ` [PATCH v4 16/16] ACPI / DSD: Document references, ports and endpoints Sakari Ailus
2017-03-13 22:08     ` Rafael J. Wysocki
2017-03-14  8:08       ` Sakari Ailus
2017-03-14  8:09         ` Sakari Ailus
2017-03-14 17:05           ` Rafael J. Wysocki
     [not found]             ` <CAJZ5v0j1i-tNOdyhhknYCSPbOg7KAQpYgeReH_KwgebO3AcjRA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-14 17:54               ` Sakari Ailus
     [not found]                 ` <cf2ab8be-a351-f1ea-28a9-f5cca57061cd-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2017-03-14 20:43                   ` Rafael J. Wysocki
     [not found]                     ` <CAJZ5v0i4pEKkz+3Ob42x96YHpPWasH2O8VnDCz8aKw_wxywLyQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-14 21:16                       ` Sakari Ailus
2017-03-14 22:11                         ` Rafael J. Wysocki
     [not found]                           ` <CAJZ5v0hCvcPgYYV0Hysfu0pEYCzzHp7KKdW3nYyjm7RGS3bHoQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-14 22:53                             ` Sakari Ailus
2017-03-14 23:13                               ` Rafael J. Wysocki
2017-03-15  8:23                                 ` Sakari Ailus
2017-03-15  9:33                                   ` Sakari Ailus
2017-03-15 11:28                                     ` Rafael J. Wysocki
     [not found]                                       ` <1595427.gxrcIpTbyD-yvgW3jdyMHm1GS7QM15AGw@public.gmane.org>
2017-03-15 11:45                                         ` Sakari Ailus
2017-03-15 11:53                                           ` Rafael J. Wysocki
2017-03-15 12:26                                             ` Sakari Ailus
     [not found]                                               ` <ceae0f71-dbac-36b8-f8df-fa138e6f24b2-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2017-03-15 14:21                                                 ` Rafael J. Wysocki
2017-03-16 11:30                                                   ` Sakari Ailus
2017-03-07  7:49   ` [PATCH v4 00/16] ACPI graph support Sakari Ailus
2017-03-07 13:23     ` Rafael J. Wysocki
2017-03-07 13:49       ` Sakari Ailus
2017-03-09 23:05         ` Rafael J. Wysocki
2017-03-10  8:19           ` Sakari Ailus
2017-03-06 14:19 ` [PATCH v4 15/16] device property: Add fwnode_get_next_parent() Sakari Ailus
2017-03-13 21:58   ` Rafael J. Wysocki
2017-03-14  7:51     ` Sakari Ailus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1488809970-25568-2-git-send-email-sakari.ailus@linux.intel.com \
    --to=sakari.ailus-vuqaysv1563yd54fqh9/ca@public.gmane.org \
    --cc=ahs3-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=rafael-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=sudeep.holla-5wv7dgnIgG8@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).