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>
master
Przemyslaw Marczak 10 years ago committed by Simon Glass
parent c1d6f91952
commit 5eaed88028
  1. 4
      drivers/core/device-remove.c
  2. 33
      drivers/core/device.c
  3. 17
      include/dm/device.h
  4. 4
      include/dm/uclass.h

@ -92,6 +92,10 @@ int device_unbind(struct udevice *dev)
free(dev->platdata); free(dev->platdata);
dev->platdata = NULL; 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) { if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
free(dev->parent_platdata); free(dev->parent_platdata);
dev->parent_platdata = NULL; dev->parent_platdata = NULL;

@ -30,7 +30,7 @@ int device_bind(struct udevice *parent, const struct driver *drv,
{ {
struct udevice *dev; struct udevice *dev;
struct uclass *uc; struct uclass *uc;
int ret = 0; int size, ret = 0;
*devp = NULL; *devp = NULL;
if (!name) if (!name)
@ -79,9 +79,19 @@ int device_bind(struct udevice *parent, const struct driver *drv,
goto fail_alloc1; 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) { if (!size) {
size = parent->uclass->uc_drv-> size = parent->uclass->uc_drv->
per_child_platdata_auto_alloc_size; 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); dev->parent_platdata = calloc(1, size);
if (!dev->parent_platdata) { if (!dev->parent_platdata) {
ret = -ENOMEM; ret = -ENOMEM;
goto fail_alloc2; goto fail_alloc3;
} }
} }
} }
@ -139,6 +149,11 @@ fail_uclass_bind:
free(dev->parent_platdata); free(dev->parent_platdata);
dev->parent_platdata = NULL; dev->parent_platdata = NULL;
} }
fail_alloc3:
if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
free(dev->uclass_platdata);
dev->uclass_platdata = NULL;
}
fail_alloc2: fail_alloc2:
if (dev->flags & DM_FLAG_ALLOC_PDATA) { if (dev->flags & DM_FLAG_ALLOC_PDATA) {
free(dev->platdata); free(dev->platdata);
@ -314,6 +329,16 @@ void *dev_get_parent_platdata(struct udevice *dev)
return dev->parent_platdata; 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) void *dev_get_priv(struct udevice *dev)
{ {
if (!dev) { if (!dev) {

@ -30,8 +30,11 @@ struct driver_info;
/* DM is responsible for allocating and freeing parent_platdata */ /* DM is responsible for allocating and freeing parent_platdata */
#define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3) #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 */ /* 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 * struct udevice - An instance of a driver
@ -54,6 +57,7 @@ struct driver_info;
* @name: Name of device, typically the FDT node name * @name: Name of device, typically the FDT node name
* @platdata: Configuration data for this device * @platdata: Configuration data for this device
* @parent_platdata: The parent bus's 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_offset: Device tree node offset for this device (- for none)
* @driver_data: Driver data word for the entry that matched this device with * @driver_data: Driver data word for the entry that matched this device with
* its driver * its driver
@ -75,6 +79,7 @@ struct udevice {
const char *name; const char *name;
void *platdata; void *platdata;
void *parent_platdata; void *parent_platdata;
void *uclass_platdata;
int of_offset; int of_offset;
ulong driver_data; ulong driver_data;
struct udevice *parent; struct udevice *parent;
@ -210,6 +215,16 @@ void *dev_get_platdata(struct udevice *dev);
void *dev_get_parent_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 * dev_get_parentdata() - Get the parent data for a device
* *
* The parent data is data stored in the device but owned by the parent. * The parent data is data stored in the device but owned by the parent.

@ -65,6 +65,9 @@ struct udevice;
* @per_device_auto_alloc_size: Each device can hold private data owned * @per_device_auto_alloc_size: Each device can hold private data owned
* by the uclass. If required this will be automatically allocated if this * by the uclass. If required this will be automatically allocated if this
* value is non-zero. * 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 * @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 * 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. * 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 (*destroy)(struct uclass *class);
int priv_auto_alloc_size; int priv_auto_alloc_size;
int per_device_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_auto_alloc_size;
int per_child_platdata_auto_alloc_size; int per_child_platdata_auto_alloc_size;
const void *ops; const void *ops;

Loading…
Cancel
Save