From 5eaed880282480a5a0a2b555c5f98a11252ed94e Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Wed, 15 Apr 2015 13:07:18 +0200 Subject: dm: core: Extend struct udevice by '.uclass_platdata' field. This commit adds 'uclass_platdata' field to 'struct udevice', which can be automatically allocated at bind. The allocation size is defined in 'struct uclass_driver' as 'per_device_platdata_auto_alloc_size'. New device's flag is added: DM_FLAG_ALLOC_UCLASS_PDATA, which is used for memory freeing at device unbind method. As for other udevice's fields, a complementary function is added: - dev_get_uclass_platdata() Signed-off-by: Przemyslaw Marczak Cc: Simon Glass Acked-by: Simon Glass --- drivers/core/device-remove.c | 4 ++++ drivers/core/device.c | 33 +++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) (limited to 'drivers/core') diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 7fee1c001e4..6a16b4f690f 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_UCLASS_PDATA) { + free(dev->uclass_platdata); + dev->uclass_platdata = NULL; + } if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { free(dev->parent_platdata); dev->parent_platdata = NULL; diff --git a/drivers/core/device.c b/drivers/core/device.c index ccaa99ca63f..80eb55bb3b8 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -30,7 +30,7 @@ int device_bind(struct udevice *parent, const struct driver *drv, { struct udevice *dev; struct uclass *uc; - int ret = 0; + int size, ret = 0; *devp = NULL; if (!name) @@ -79,9 +79,19 @@ int device_bind(struct udevice *parent, const struct driver *drv, goto fail_alloc1; } } - if (parent) { - int size = parent->driver->per_child_platdata_auto_alloc_size; + size = uc->uc_drv->per_device_platdata_auto_alloc_size; + if (size) { + dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA; + dev->uclass_platdata = calloc(1, size); + if (!dev->uclass_platdata) { + ret = -ENOMEM; + goto fail_alloc2; + } + } + + if (parent) { + size = parent->driver->per_child_platdata_auto_alloc_size; if (!size) { size = parent->uclass->uc_drv-> per_child_platdata_auto_alloc_size; @@ -91,7 +101,7 @@ int device_bind(struct udevice *parent, const struct driver *drv, dev->parent_platdata = calloc(1, size); if (!dev->parent_platdata) { ret = -ENOMEM; - goto fail_alloc2; + goto fail_alloc3; } } } @@ -139,6 +149,11 @@ fail_uclass_bind: free(dev->parent_platdata); dev->parent_platdata = NULL; } +fail_alloc3: + if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) { + free(dev->uclass_platdata); + dev->uclass_platdata = NULL; + } fail_alloc2: if (dev->flags & DM_FLAG_ALLOC_PDATA) { free(dev->platdata); @@ -314,6 +329,16 @@ void *dev_get_parent_platdata(struct udevice *dev) return dev->parent_platdata; } +void *dev_get_uclass_platdata(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device", __func__); + return NULL; + } + + return dev->uclass_platdata; +} + void *dev_get_priv(struct udevice *dev) { if (!dev) { -- cgit v1.2.3