dm: regmap: Add a dummy implementation for of-platdata
[platform/kernel/u-boot.git] / drivers / core / regmap.c
1 /*
2  * Copyright (c) 2015 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <libfdt.h>
12 #include <malloc.h>
13 #include <mapmem.h>
14 #include <regmap.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 #if CONFIG_IS_ENABLED(OF_PLATDATA)
19 int regmap_init_mem_platdata(struct udevice *dev, fdt32_t *reg, int size,
20                              struct regmap **mapp)
21 {
22         /* TODO(sjg@chromium.org): Implement this when needed */
23         return 0;
24 }
25 #else
26 int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
27 {
28         const void *blob = gd->fdt_blob;
29         struct regmap_range *range;
30         const fdt32_t *cell;
31         struct regmap *map;
32         int count;
33         int addr_len, size_len, both_len;
34         int parent;
35         int len;
36
37         parent = dev->parent->of_offset;
38         addr_len = fdt_address_cells(blob, parent);
39         size_len = fdt_size_cells(blob, parent);
40         both_len = addr_len + size_len;
41
42         cell = fdt_getprop(blob, dev->of_offset, "reg", &len);
43         len /= sizeof(*cell);
44         count = len / both_len;
45         if (!cell || !count)
46                 return -EINVAL;
47
48         map = malloc(sizeof(struct regmap));
49         if (!map)
50                 return -ENOMEM;
51
52         if (count <= 1) {
53                 map->range = &map->base_range;
54         } else {
55                 map->range = malloc(count * sizeof(struct regmap_range));
56                 if (!map->range) {
57                         free(map);
58                         return -ENOMEM;
59                 }
60         }
61
62         map->base = fdtdec_get_number(cell, addr_len);
63         map->range_count = count;
64
65         for (range = map->range; count > 0;
66              count--, cell += both_len, range++) {
67                 range->start = fdtdec_get_number(cell, addr_len);
68                 range->size = fdtdec_get_number(cell + addr_len, size_len);
69         }
70
71         *mapp = map;
72
73         return 0;
74 }
75 #endif
76
77 void *regmap_get_range(struct regmap *map, unsigned int range_num)
78 {
79         struct regmap_range *range;
80
81         if (range_num >= map->range_count)
82                 return NULL;
83         range = &map->range[range_num];
84
85         return map_sysmem(range->start, range->size);
86 }
87
88 int regmap_uninit(struct regmap *map)
89 {
90         if (map->range_count > 1)
91                 free(map->range);
92         free(map);
93
94         return 0;
95 }