summaryrefslogtreecommitdiff
path: root/drivers/core/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/core/device.c')
-rw-r--r--drivers/core/device.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 6967c3d..5bb1d77 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -30,7 +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 udevice **devp)
+ uint of_platdata_size, struct udevice **devp)
{
struct udevice *dev;
struct uclass *uc;
@@ -84,12 +84,29 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
}
}
- if (!dev->platdata && drv->platdata_auto_alloc_size) {
- dev->flags |= DM_FLAG_ALLOC_PDATA;
- dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
- if (!dev->platdata) {
- ret = -ENOMEM;
- goto fail_alloc1;
+ if (drv->platdata_auto_alloc_size) {
+ bool alloc = !platdata;
+
+ if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+ if (of_platdata_size) {
+ dev->flags |= DM_FLAG_OF_PLATDATA;
+ if (of_platdata_size <
+ drv->platdata_auto_alloc_size)
+ alloc = true;
+ }
+ }
+ if (alloc) {
+ dev->flags |= DM_FLAG_ALLOC_PDATA;
+ dev->platdata = calloc(1,
+ drv->platdata_auto_alloc_size);
+ if (!dev->platdata) {
+ ret = -ENOMEM;
+ goto fail_alloc1;
+ }
+ if (CONFIG_IS_ENABLED(OF_PLATDATA) && platdata) {
+ memcpy(dev->platdata, platdata,
+ of_platdata_size);
+ }
}
}
@@ -202,14 +219,14 @@ int device_bind_with_driver_data(struct udevice *parent,
struct udevice **devp)
{
return device_bind_common(parent, drv, name, NULL, driver_data,
- of_offset, devp);
+ of_offset, 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,
+ return device_bind_common(parent, drv, name, platdata, 0, of_offset, 0,
devp);
}
@@ -217,6 +234,7 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
const struct driver_info *info, struct udevice **devp)
{
struct driver *drv;
+ uint platdata_size = 0;
drv = lists_driver_lookup_name(info->name);
if (!drv)
@@ -224,8 +242,11 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
return -EPERM;
- return device_bind(parent, drv, info->name, (void *)info->platdata,
- -1, devp);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ platdata_size = info->platdata_size;
+#endif
+ return device_bind_common(parent, drv, info->name,
+ (void *)info->platdata, 0, -1, platdata_size, devp);
}
static void *alloc_priv(int size, uint flags)