[U-Boot] [PATCH 11/22] dm: core: Allow binding a device from a live tree
Simon Glass
sjg at chromium.org
Wed Jan 18 06:51:47 CET 2017
When a live tree is being used we need to record the node that was used to
create the device. Add a function to support this, and a new field to the
udevice structure.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
drivers/core/device.c | 27 +++++++++++++++++++++++----
include/dm/device-internal.h | 6 ++++++
include/dm/device.h | 19 ++++++++++++++++++-
3 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 70fcfc23e0c..52b8715a4ae 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -30,6 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int device_bind_common(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata,
ulong driver_data, int of_offset,
+ struct device_node *of_node,
uint of_platdata_size, struct udevice **devp)
{
struct udevice *dev;
@@ -60,7 +61,14 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
dev->platdata = platdata;
dev->driver_data = driver_data;
dev->name = name;
+#ifdef CONFIG_OF_LIVE
+ if (of_use_livetree())
+ dev->node_ref = of_node_to_ref(of_node);
+ else
+ dev->node_ref = of_offset_to_ref(of_offset);
+#else
dev->of_offset = of_offset;
+#endif
dev->parent = parent;
dev->driver = drv;
dev->uclass = uc;
@@ -219,15 +227,25 @@ int device_bind_with_driver_data(struct udevice *parent,
struct udevice **devp)
{
return device_bind_common(parent, drv, name, NULL, driver_data,
- of_offset, 0, devp);
+ of_offset, NULL, 0, devp);
+}
+
+int device_bind_node_with_driver_data(struct udevice *parent,
+ const struct driver *drv,
+ const char *name, ulong driver_data,
+ struct device_node *np,
+ struct udevice **devp)
+{
+ return device_bind_common(parent, drv, name, NULL, driver_data,
+ -1, np, 0, devp);
}
int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp)
{
- return device_bind_common(parent, drv, name, platdata, 0, of_offset, 0,
- devp);
+ return device_bind_common(parent, drv, name, platdata, 0, of_offset,
+ NULL, 0, devp);
}
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
@@ -246,7 +264,8 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
platdata_size = info->platdata_size;
#endif
return device_bind_common(parent, drv, info->name,
- (void *)info->platdata, 0, -1, platdata_size, devp);
+ (void *)info->platdata, 0, -1, NULL,
+ platdata_size, devp);
}
static void *alloc_priv(int size, uint flags)
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 0bf8707493a..5bc80e64aae 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -11,6 +11,7 @@
#ifndef _DM_DEVICE_INTERNAL_H
#define _DM_DEVICE_INTERNAL_H
+struct device_node;
struct udevice;
/**
@@ -62,6 +63,11 @@ int device_bind_with_driver_data(struct udevice *parent,
ulong driver_data, int of_offset,
struct udevice **devp);
+int device_bind_node_with_driver_data(struct udevice *parent,
+ const struct driver *drv,
+ const char *name, ulong driver_data,
+ struct device_node *np,
+ struct udevice **devp);
/**
* device_bind_by_name: Create a device and bind it to a driver
*
diff --git a/include/dm/device.h b/include/dm/device.h
index 4e95fb7773d..94248eccee7 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -18,6 +18,10 @@
#include <linux/kernel.h>
#include <linux/list.h>
+#ifdef CONFIG_OF_LIVE
+#include <dm/of_ref.h>
+#endif
+
struct driver_info;
/* Driver is active (probed). Cleared when it is removed */
@@ -68,7 +72,8 @@ struct driver_info;
* @platdata: Configuration data for this device
* @parent_platdata: The parent bus's configuration data for this device
* @uclass_platdata: The uclass's configuration data for this device
- * @of_offset: Device tree node offset for this device (- for none)
+ * @of_noderef: Reference to device tree node for this devide)
+ * @of_offset: Device tree node offset for this device (-1 for none)
* @driver_data: Driver data word for the entry that matched this device with
* its driver
* @parent: Parent of this device, or NULL for the top level device
@@ -94,7 +99,11 @@ struct udevice {
void *platdata;
void *parent_platdata;
void *uclass_platdata;
+#ifdef CONFIG_OF_LIVE
+ of_node_ref node_ref;
+#else
int of_offset;
+#endif
ulong driver_data;
struct udevice *parent;
void *priv;
@@ -123,12 +132,20 @@ struct udevice {
static inline int dev_of_offset(const struct udevice *dev)
{
+#ifdef CONFIG_OF_LIVE
+ return of_ref_to_offset(dev->node_ref);
+#else
return dev->of_offset;
+#endif
}
static inline void dev_set_of_offset(struct udevice *dev, int of_offset)
{
+#ifdef CONFIG_OF_LIVE
+ dev->node_ref = of_offset_to_ref(of_offset);
+#else
dev->of_offset = of_offset;
+#endif
}
/**
--
2.11.0.483.g087da7b7c-goog
More information about the U-Boot
mailing list