@@ -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;
}
@@ -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);
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(+)