
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@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 }
/**