summaryrefslogtreecommitdiff
path: root/drivers/core
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2016-07-15 08:06:22 -0400
committerTom Rini <trini@konsulko.com>2016-07-15 08:06:22 -0400
commitebe621d5fb2f5c15aff50e0610372f2751fd152f (patch)
tree12985b43f1a8500332de8e20274cc2dd26f5a040 /drivers/core
parent36b898b6bea839de7141b65df6ec02a97615c467 (diff)
parent1269625177f120d659f66b18de4b532b16c44561 (diff)
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'drivers/core')
-rw-r--r--drivers/core/device-remove.c2
-rw-r--r--drivers/core/device.c47
-rw-r--r--drivers/core/lists.c2
-rw-r--r--drivers/core/regmap.c57
-rw-r--r--drivers/core/root.c4
-rw-r--r--drivers/core/syscon-uclass.c13
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)