dm: core: Allow parents to have platform data for their children

For buses it is common for parents to need to know the address of the child
on the bus, the bus speed to use for that child, and other information. This
can be provided in platform data attached to each child.

Add driver model support for this, including auto-allocation which can be
requested using a new property to specify the size of the data.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
This commit is contained in:
Simon Glass 2015-01-25 08:27:01 -07:00
parent f8a85449ef
commit cdc133bde9
4 changed files with 132 additions and 2 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_PARENT_PDATA) {
free(dev->parent_platdata);
dev->parent_platdata = NULL;
}
ret = uclass_unbind_device(dev);
if (ret)
return ret;

View file

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