diff mbox

[v7,04/17] core/device: Introduce device node counter

Message ID 1433398749-15096-5-git-send-email-gwshan@linux.vnet.ibm.com
State Changes Requested
Delegated to: Benjamin Herrenschmidt
Headers show

Commit Message

Gavin Shan June 4, 2015, 6:18 a.m. UTC
It's impossible to pick those device nodes added to current live
device tree during PCI hotplugging time because we don't know
when the device node is added. Ben proposed simple, but effective
mechanism: There is global counter for device tree and each one
device node maintains a counter, which is the copy of the global
one. The global counter is increased with one on the events (e.g.
PCI hot plugging). We know when one particular device node is
created.

Suggested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 core/device.c    | 17 +++++++++++++++++
 include/device.h |  4 ++++
 2 files changed, 21 insertions(+)
diff mbox

Patch

diff --git a/core/device.c b/core/device.c
index 09f76d7..dde95aa 100644
--- a/core/device.c
+++ b/core/device.c
@@ -25,9 +25,25 @@ 
 /* Used to give unique handles. */
 u32 last_phandle = 0;
 
+/* Device tree counter, which is used to trace the changes to the
+ * device tree. Every device node has unique counter that tells
+ * when the device node is added. So the counter could be regarded
+ * as ID of events changing the device tree, like PCI hotplug.
+ */
+static u64 dt_counter = 0;
+
 struct dt_node *dt_root;
 struct dt_node *dt_chosen;
 
+u64 dt_update_counter(u64 *counter)
+{
+	u64 tmp = dt_counter;
+
+	if (*counter)
+		dt_counter = *counter;
+	return tmp;
+}
+
 static const char *take_name(const char *name)
 {
 	if (!is_rodata(name) && !(name = strdup(name))) {
@@ -57,6 +73,7 @@  static struct dt_node *new_node(const char *name)
 	list_head_init(&node->children);
 	/* FIXME: locking? */
 	node->phandle = ++last_phandle;
+	node->counter = dt_counter;
 	return node;
 }
 
diff --git a/include/device.h b/include/device.h
index b301958..6457d79 100644
--- a/include/device.h
+++ b/include/device.h
@@ -45,6 +45,7 @@  struct dt_node {
 	struct list_head children;
 	struct dt_node *parent;
 	u32 phandle;
+	u64 counter;
 };
 
 /* This is shared with device_tree.c .. make it static when
@@ -55,6 +56,9 @@  extern u32 last_phandle;
 extern struct dt_node *dt_root;
 extern struct dt_node *dt_chosen;
 
+/* Get or set the global counter */
+u64 dt_update_counter(u64 *counter);
+
 /* Create a root node: ie. a parentless one. */
 struct dt_node *dt_new_root(const char *name);