regmap: Lock the sync path, ensure we use the lockless _regmap_write()
[pandora-kernel.git] / drivers / base / regmap / regcache.c
1 /*
2  * Register cache access API
3  *
4  * Copyright 2011 Wolfson Microelectronics plc
5  *
6  * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/slab.h>
14 #include <trace/events/regmap.h>
15
16 #include "internal.h"
17
18 static const struct regcache_ops *cache_types[] = {
19         &regcache_indexed_ops,
20         &regcache_rbtree_ops,
21         &regcache_lzo_ops,
22 };
23
24 static int regcache_hw_init(struct regmap *map)
25 {
26         int i, j;
27         int ret;
28         int count;
29         unsigned int val;
30         void *tmp_buf;
31
32         if (!map->num_reg_defaults_raw)
33                 return -EINVAL;
34
35         if (!map->reg_defaults_raw) {
36                 dev_warn(map->dev, "No cache defaults, reading back from HW\n");
37                 tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL);
38                 if (!tmp_buf)
39                         return -EINVAL;
40                 ret = regmap_bulk_read(map, 0, tmp_buf,
41                                        map->num_reg_defaults_raw);
42                 if (ret < 0) {
43                         kfree(tmp_buf);
44                         return ret;
45                 }
46                 map->reg_defaults_raw = tmp_buf;
47                 map->cache_free = 1;
48         }
49
50         /* calculate the size of reg_defaults */
51         for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
52                 val = regcache_get_val(map->reg_defaults_raw,
53                                        i, map->cache_word_size);
54                 if (!val)
55                         continue;
56                 count++;
57         }
58
59         map->reg_defaults = kmalloc(count * sizeof(struct reg_default),
60                                       GFP_KERNEL);
61         if (!map->reg_defaults)
62                 return -ENOMEM;
63
64         /* fill the reg_defaults */
65         map->num_reg_defaults = count;
66         for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
67                 val = regcache_get_val(map->reg_defaults_raw,
68                                        i, map->cache_word_size);
69                 if (!val)
70                         continue;
71                 map->reg_defaults[j].reg = i;
72                 map->reg_defaults[j].def = val;
73                 j++;
74         }
75
76         return 0;
77 }
78
79 int regcache_init(struct regmap *map)
80 {
81         int ret;
82         int i;
83         void *tmp_buf;
84
85         if (map->cache_type == REGCACHE_NONE) {
86                 map->cache_bypass = true;
87                 return 0;
88         }
89
90         for (i = 0; i < ARRAY_SIZE(cache_types); i++)
91                 if (cache_types[i]->type == map->cache_type)
92                         break;
93
94         if (i == ARRAY_SIZE(cache_types)) {
95                 dev_err(map->dev, "Could not match compress type: %d\n",
96                         map->cache_type);
97                 return -EINVAL;
98         }
99
100         map->cache = NULL;
101         map->cache_ops = cache_types[i];
102
103         if (!map->cache_ops->read ||
104             !map->cache_ops->write ||
105             !map->cache_ops->name)
106                 return -EINVAL;
107
108         /* We still need to ensure that the reg_defaults
109          * won't vanish from under us.  We'll need to make
110          * a copy of it.
111          */
112         if (map->reg_defaults) {
113                 if (!map->num_reg_defaults)
114                         return -EINVAL;
115                 tmp_buf = kmemdup(map->reg_defaults, map->num_reg_defaults *
116                                   sizeof(struct reg_default), GFP_KERNEL);
117                 if (!tmp_buf)
118                         return -ENOMEM;
119                 map->reg_defaults = tmp_buf;
120         } else {
121                 /* Some devices such as PMICs don't have cache defaults,
122                  * we cope with this by reading back the HW registers and
123                  * crafting the cache defaults by hand.
124                  */
125                 ret = regcache_hw_init(map);
126                 if (ret < 0)
127                         return ret;
128         }
129
130         if (!map->max_register)
131                 map->max_register = map->num_reg_defaults_raw;
132
133         if (map->cache_ops->init) {
134                 dev_dbg(map->dev, "Initializing %s cache\n",
135                         map->cache_ops->name);
136                 return map->cache_ops->init(map);
137         }
138         return 0;
139 }
140
141 void regcache_exit(struct regmap *map)
142 {
143         if (map->cache_type == REGCACHE_NONE)
144                 return;
145
146         BUG_ON(!map->cache_ops);
147
148         kfree(map->reg_defaults);
149         if (map->cache_free)
150                 kfree(map->reg_defaults_raw);
151
152         if (map->cache_ops->exit) {
153                 dev_dbg(map->dev, "Destroying %s cache\n",
154                         map->cache_ops->name);
155                 map->cache_ops->exit(map);
156         }
157 }
158
159 /**
160  * regcache_read: Fetch the value of a given register from the cache.
161  *
162  * @map: map to configure.
163  * @reg: The register index.
164  * @value: The value to be returned.
165  *
166  * Return a negative value on failure, 0 on success.
167  */
168 int regcache_read(struct regmap *map,
169                   unsigned int reg, unsigned int *value)
170 {
171         if (map->cache_type == REGCACHE_NONE)
172                 return -ENOSYS;
173
174         BUG_ON(!map->cache_ops);
175
176         if (!regmap_readable(map, reg))
177                 return -EIO;
178
179         if (!regmap_volatile(map, reg))
180                 return map->cache_ops->read(map, reg, value);
181
182         return -EINVAL;
183 }
184 EXPORT_SYMBOL_GPL(regcache_read);
185
186 /**
187  * regcache_write: Set the value of a given register in the cache.
188  *
189  * @map: map to configure.
190  * @reg: The register index.
191  * @value: The new register value.
192  *
193  * Return a negative value on failure, 0 on success.
194  */
195 int regcache_write(struct regmap *map,
196                    unsigned int reg, unsigned int value)
197 {
198         if (map->cache_type == REGCACHE_NONE)
199                 return 0;
200
201         BUG_ON(!map->cache_ops);
202
203         if (!regmap_writeable(map, reg))
204                 return -EIO;
205
206         if (!regmap_volatile(map, reg))
207                 return map->cache_ops->write(map, reg, value);
208
209         return 0;
210 }
211 EXPORT_SYMBOL_GPL(regcache_write);
212
213 /**
214  * regcache_sync: Sync the register cache with the hardware.
215  *
216  * @map: map to configure.
217  *
218  * Any registers that should not be synced should be marked as
219  * volatile.  In general drivers can choose not to use the provided
220  * syncing functionality if they so require.
221  *
222  * Return a negative value on failure, 0 on success.
223  */
224 int regcache_sync(struct regmap *map)
225 {
226         int ret = 0;
227         unsigned int val;
228         unsigned int i;
229         const char *name;
230
231         BUG_ON(!map->cache_ops);
232
233         mutex_lock(&map->lock);
234         dev_dbg(map->dev, "Syncing %s cache\n",
235                 map->cache_ops->name);
236         name = map->cache_ops->name;
237         trace_regcache_sync(map->dev, name, "start");
238         if (map->cache_ops->sync) {
239                 ret = map->cache_ops->sync(map);
240         } else {
241                 for (i = 0; i < map->num_reg_defaults; i++) {
242                         ret = regcache_read(map, i, &val);
243                         if (ret < 0)
244                                 goto out;
245                         map->cache_bypass = 1;
246                         ret = _regmap_write(map, i, val);
247                         map->cache_bypass = 0;
248                         if (ret < 0)
249                                 goto out;
250                         dev_dbg(map->dev, "Synced register %#x, value %#x\n",
251                                 map->reg_defaults[i].reg,
252                                 map->reg_defaults[i].def);
253                 }
254
255         }
256 out:
257         trace_regcache_sync(map->dev, name, "stop");
258         mutex_unlock(&map->lock);
259
260         return ret;
261 }
262 EXPORT_SYMBOL_GPL(regcache_sync);
263
264 /**
265  * regcache_cache_only: Put a register map into cache only mode
266  *
267  * @map: map to configure
268  * @cache_only: flag if changes should be written to the hardware
269  *
270  * When a register map is marked as cache only writes to the register
271  * map API will only update the register cache, they will not cause
272  * any hardware changes.  This is useful for allowing portions of
273  * drivers to act as though the device were functioning as normal when
274  * it is disabled for power saving reasons.
275  */
276 void regcache_cache_only(struct regmap *map, bool enable)
277 {
278         mutex_lock(&map->lock);
279         map->cache_only = enable;
280         mutex_unlock(&map->lock);
281 }
282 EXPORT_SYMBOL_GPL(regcache_cache_only);
283
284 bool regcache_set_val(void *base, unsigned int idx,
285                       unsigned int val, unsigned int word_size)
286 {
287         switch (word_size) {
288         case 1: {
289                 u8 *cache = base;
290                 if (cache[idx] == val)
291                         return true;
292                 cache[idx] = val;
293                 break;
294         }
295         case 2: {
296                 u16 *cache = base;
297                 if (cache[idx] == val)
298                         return true;
299                 cache[idx] = val;
300                 break;
301         }
302         default:
303                 BUG();
304         }
305         /* unreachable */
306         return false;
307 }
308
309 unsigned int regcache_get_val(const void *base, unsigned int idx,
310                               unsigned int word_size)
311 {
312         if (!base)
313                 return -EINVAL;
314
315         switch (word_size) {
316         case 1: {
317                 const u8 *cache = base;
318                 return cache[idx];
319         }
320         case 2: {
321                 const u16 *cache = base;
322                 return cache[idx];
323         }
324         default:
325                 BUG();
326         }
327         /* unreachable */
328         return -1;
329 }
330
331 int regcache_lookup_reg(struct regmap *map, unsigned int reg)
332 {
333         unsigned int i;
334
335         for (i = 0; i < map->num_reg_defaults; i++)
336                 if (map->reg_defaults[i].reg == reg)
337                         return i;
338         return -1;
339 }
340
341 int regcache_insert_reg(struct regmap *map, unsigned int reg,
342                         unsigned int val)
343 {
344         void *tmp;
345
346         tmp = krealloc(map->reg_defaults,
347                        (map->num_reg_defaults + 1) * sizeof(struct reg_default),
348                        GFP_KERNEL);
349         if (!tmp)
350                 return -ENOMEM;
351         map->reg_defaults = tmp;
352         map->num_reg_defaults++;
353         map->reg_defaults[map->num_reg_defaults - 1].reg = reg;
354         map->reg_defaults[map->num_reg_defaults - 1].def = val;
355         return 0;
356 }