diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/core/device-remove.c | 4 | ||||
-rw-r--r-- | drivers/core/device.c | 30 |
2 files changed, 32 insertions, 2 deletions
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 2c82577..56c358a 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -92,6 +92,10 @@ int device_unbind(struct udevice *dev) free(dev->platdata); dev->platdata = NULL; } + if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev->parent_platdata); + dev->parent_platdata = NULL; + } ret = uclass_unbind_device(dev); if (ret) return ret; diff --git a/drivers/core/device.c b/drivers/core/device.c index 366cffe..ee97cc8 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -80,6 +80,18 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, goto fail_alloc1; } } + if (parent) { + int size = parent->driver->per_child_platdata_auto_alloc_size; + + if (size) { + dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA; + dev->parent_platdata = calloc(1, size); + if (!dev->parent_platdata) { + ret = -ENOMEM; + goto fail_alloc2; + } + } + } /* put dev into parent's successor list */ if (parent) @@ -107,8 +119,12 @@ fail_bind: dev->name); } fail_uclass_bind: - if (parent) - list_del(&dev->sibling_node); + list_del(&dev->sibling_node); + if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev->parent_platdata); + dev->parent_platdata = NULL; + } +fail_alloc2: if (dev->flags & DM_FLAG_ALLOC_PDATA) { free(dev->platdata); dev->platdata = NULL; @@ -247,6 +263,16 @@ void *dev_get_platdata(struct udevice *dev) return dev->platdata; } +void *dev_get_parent_platdata(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device", __func__); + return NULL; + } + + return dev->parent_platdata; +} + void *dev_get_priv(struct udevice *dev) { if (!dev) { |