mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
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:
parent
c1d6f91952
commit
5eaed88028
4 changed files with 53 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue