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 <p.marczak@samsung.com>
Cc: Simon Glass <sjg@chromium.org>
Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Przemyslaw Marczak 2015-04-15 13:07:18 +02:00 committed by Simon Glass
parent c1d6f91952
commit 5eaed88028
4 changed files with 53 additions and 5 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -30,8 +30,11 @@ struct driver_info;
/* DM is responsible for allocating and freeing parent_platdata */
#define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3)
/* DM is responsible for allocating and freeing uclass_platdata */
#define DM_FLAG_ALLOC_UCLASS_PDATA (1 << 4)
/* Allocate driver private data on a DMA boundary */
#define DM_FLAG_ALLOC_PRIV_DMA (1 << 4)
#define DM_FLAG_ALLOC_PRIV_DMA (1 << 5)
/**
* struct udevice - An instance of a driver
@ -54,6 +57,7 @@ struct driver_info;
* @name: Name of device, typically the FDT node name
* @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)
* @driver_data: Driver data word for the entry that matched this device with
* its driver
@ -75,6 +79,7 @@ struct udevice {
const char *name;
void *platdata;
void *parent_platdata;
void *uclass_platdata;
int of_offset;
ulong driver_data;
struct udevice *parent;
@ -209,6 +214,16 @@ void *dev_get_platdata(struct udevice *dev);
*/
void *dev_get_parent_platdata(struct udevice *dev);
/**
* dev_get_uclass_platdata() - Get the uclass platform data for a device
*
* This checks that dev is not NULL, but no other checks for now
*
* @dev Device to check
* @return uclass's platform data, or NULL if none
*/
void *dev_get_uclass_platdata(struct udevice *dev);
/**
* dev_get_parentdata() - Get the parent data for a device
*

View file

@ -65,6 +65,9 @@ struct udevice;
* @per_device_auto_alloc_size: Each device can hold private data owned
* by the uclass. If required this will be automatically allocated if this
* value is non-zero.
* @per_device_platdata_auto_alloc_size: Each device can hold platform data
* owned by the uclass as 'dev->uclass_platdata'. If the value is non-zero,
* then this will be automatically allocated.
* @per_child_auto_alloc_size: Each child device (of a parent in this
* uclass) can hold parent data for the device/uclass. This value is only
* used as a falback if this member is 0 in the driver.
@ -90,6 +93,7 @@ struct uclass_driver {
int (*destroy)(struct uclass *class);
int priv_auto_alloc_size;
int per_device_auto_alloc_size;
int per_device_platdata_auto_alloc_size;
int per_child_auto_alloc_size;
int per_child_platdata_auto_alloc_size;
const void *ops;