diff options
author | Tom Rini <trini@konsulko.com> | 2016-07-15 08:06:22 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-07-15 08:06:22 -0400 |
commit | ebe621d5fb2f5c15aff50e0610372f2751fd152f (patch) | |
tree | 12985b43f1a8500332de8e20274cc2dd26f5a040 /drivers/core | |
parent | 36b898b6bea839de7141b65df6ec02a97615c467 (diff) | |
parent | 1269625177f120d659f66b18de4b532b16c44561 (diff) |
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'drivers/core')
-rw-r--r-- | drivers/core/device-remove.c | 2 | ||||
-rw-r--r-- | drivers/core/device.c | 47 | ||||
-rw-r--r-- | drivers/core/lists.c | 2 | ||||
-rw-r--r-- | drivers/core/regmap.c | 57 | ||||
-rw-r--r-- | drivers/core/root.c | 4 | ||||
-rw-r--r-- | drivers/core/syscon-uclass.c | 13 |
6 files changed, 96 insertions, 29 deletions
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 0e56b23fbb..a7f77b4a21 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -112,7 +112,7 @@ int device_unbind(struct udevice *dev) devres_release_all(dev); - if (dev->flags & DM_NAME_ALLOCED) + if (dev->flags & DM_FLAG_NAME_ALLOCED) free((char *)dev->name); free(dev); diff --git a/drivers/core/device.c b/drivers/core/device.c index f7fb0cc0fa..5bb1d7793d 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; static int device_bind_common(struct udevice *parent, const struct driver *drv, const char *name, void *platdata, ulong driver_data, int of_offset, - struct udevice **devp) + uint of_platdata_size, struct udevice **devp) { struct udevice *dev; struct uclass *uc; @@ -84,12 +84,29 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, } } - if (!dev->platdata && drv->platdata_auto_alloc_size) { - dev->flags |= DM_FLAG_ALLOC_PDATA; - dev->platdata = calloc(1, drv->platdata_auto_alloc_size); - if (!dev->platdata) { - ret = -ENOMEM; - goto fail_alloc1; + if (drv->platdata_auto_alloc_size) { + bool alloc = !platdata; + + if (CONFIG_IS_ENABLED(OF_PLATDATA)) { + if (of_platdata_size) { + dev->flags |= DM_FLAG_OF_PLATDATA; + if (of_platdata_size < + drv->platdata_auto_alloc_size) + alloc = true; + } + } + if (alloc) { + dev->flags |= DM_FLAG_ALLOC_PDATA; + dev->platdata = calloc(1, + drv->platdata_auto_alloc_size); + if (!dev->platdata) { + ret = -ENOMEM; + goto fail_alloc1; + } + if (CONFIG_IS_ENABLED(OF_PLATDATA) && platdata) { + memcpy(dev->platdata, platdata, + of_platdata_size); + } } } @@ -202,14 +219,14 @@ int device_bind_with_driver_data(struct udevice *parent, struct udevice **devp) { return device_bind_common(parent, drv, name, NULL, driver_data, - of_offset, devp); + of_offset, 0, devp); } int device_bind(struct udevice *parent, const struct driver *drv, const char *name, void *platdata, int of_offset, struct udevice **devp) { - return device_bind_common(parent, drv, name, platdata, 0, of_offset, + return device_bind_common(parent, drv, name, platdata, 0, of_offset, 0, devp); } @@ -217,6 +234,7 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, const struct driver_info *info, struct udevice **devp) { struct driver *drv; + uint platdata_size = 0; drv = lists_driver_lookup_name(info->name); if (!drv) @@ -224,8 +242,11 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC)) return -EPERM; - return device_bind(parent, drv, info->name, (void *)info->platdata, - -1, devp); +#if CONFIG_IS_ENABLED(OF_PLATDATA) + platdata_size = info->platdata_size; +#endif + return device_bind_common(parent, drv, info->name, + (void *)info->platdata, 0, -1, platdata_size, devp); } static void *alloc_priv(int size, uint flags) @@ -608,7 +629,7 @@ const char *dev_get_uclass_name(struct udevice *dev) fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) { -#if CONFIG_IS_ENABLED(OF_CONTROL) +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) fdt_addr_t addr; if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { @@ -738,7 +759,7 @@ bool device_is_last_sibling(struct udevice *dev) void device_set_name_alloced(struct udevice *dev) { - dev->flags |= DM_NAME_ALLOCED; + dev->flags |= DM_FLAG_NAME_ALLOCED; } int device_set_name(struct udevice *dev, const char *name) diff --git a/drivers/core/lists.c b/drivers/core/lists.c index 0c27717790..6a634e6951 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -99,7 +99,7 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name, return 0; } -#if CONFIG_IS_ENABLED(OF_CONTROL) +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) /** * driver_check_compatible() - Check if a driver is compatible with this node * diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index 519832f173..0299ff0879 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -15,6 +15,49 @@ DECLARE_GLOBAL_DATA_PTR; +static struct regmap *regmap_alloc_count(int count) +{ + struct regmap *map; + + map = malloc(sizeof(struct regmap)); + if (!map) + return NULL; + if (count <= 1) { + map->range = &map->base_range; + } else { + map->range = malloc(count * sizeof(struct regmap_range)); + if (!map->range) { + free(map); + return NULL; + } + } + map->range_count = count; + + return map; +} + +#if CONFIG_IS_ENABLED(OF_PLATDATA) +int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count, + struct regmap **mapp) +{ + struct regmap_range *range; + struct regmap *map; + + map = regmap_alloc_count(count); + if (!map) + return -ENOMEM; + + map->base = *reg; + for (range = map->range; count > 0; reg += 2, range++, count--) { + range->start = *reg; + range->size = reg[1]; + } + + *mapp = map; + + return 0; +} +#else int regmap_init_mem(struct udevice *dev, struct regmap **mapp) { const void *blob = gd->fdt_blob; @@ -37,22 +80,11 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp) if (!cell || !count) return -EINVAL; - map = malloc(sizeof(struct regmap)); + map = regmap_alloc_count(count); if (!map) return -ENOMEM; - if (count <= 1) { - map->range = &map->base_range; - } else { - map->range = malloc(count * sizeof(struct regmap_range)); - if (!map->range) { - free(map); - return -ENOMEM; - } - } - map->base = fdtdec_get_number(cell, addr_len); - map->range_count = count; for (range = map->range; count > 0; count--, cell += both_len, range++) { @@ -64,6 +96,7 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp) return 0; } +#endif void *regmap_get_range(struct regmap *map, unsigned int range_num) { diff --git a/drivers/core/root.c b/drivers/core/root.c index 95886add23..158702406e 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -188,7 +188,7 @@ int dm_scan_platdata(bool pre_reloc_only) return ret; } -#if CONFIG_IS_ENABLED(OF_CONTROL) +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, bool pre_reloc_only) { @@ -244,7 +244,7 @@ int dm_init_and_scan(bool pre_reloc_only) return ret; } - if (CONFIG_IS_ENABLED(OF_CONTROL)) { + if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); if (ret) { debug("dm_scan_fdt() failed: %d\n", ret); diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index e03f46af57..01bd9683a7 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -29,7 +29,20 @@ static int syscon_pre_probe(struct udevice *dev) { struct syscon_uc_info *priv = dev_get_uclass_priv(dev); + /* + * With OF_PLATDATA we really have no way of knowing the format of + * the device-specific platform data. So we assume that it starts with + * a 'reg' member, and this holds a single address and size. Drivers + * using OF_PLATDATA will need to ensure that this is true. + */ +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct syscon_base_platdata *plat = dev_get_platdata(dev); + + return regmap_init_mem_platdata(dev, plat->reg, ARRAY_SIZE(plat->reg), + &priv->regmap); +#else return regmap_init_mem(dev, &priv->regmap); +#endif } int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp) |