aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r--drivers/base/regmap/Kconfig3
-rw-r--r--drivers/base/regmap/Makefile1
-rw-r--r--drivers/base/regmap/internal.h21
-rw-r--r--drivers/base/regmap/regcache-rbtree.c4
-rw-r--r--drivers/base/regmap/regcache.c20
-rw-r--r--drivers/base/regmap/regmap-debugfs.c14
-rw-r--r--drivers/base/regmap/regmap-i2c.c13
-rw-r--r--drivers/base/regmap/regmap-mmio.c211
-rw-r--r--drivers/base/regmap/regmap-spi.c13
-rw-r--r--drivers/base/regmap/regmap.c139
10 files changed, 373 insertions, 66 deletions
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 0f6c7fb418e8..9ef0a5326f17 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -14,5 +14,8 @@ config REGMAP_I2C
14config REGMAP_SPI 14config REGMAP_SPI
15 tristate 15 tristate
16 16
17config REGMAP_MMIO
18 tristate
19
17config REGMAP_IRQ 20config REGMAP_IRQ
18 bool 21 bool
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index defd57963c84..5e75d1b683e2 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o
3obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o 3obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
4obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o 4obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
5obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o 5obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
6obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
6obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o 7obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index fcafc5b2e651..99b28fffbd0e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -26,21 +26,29 @@ struct regmap_format {
26 size_t val_bytes; 26 size_t val_bytes;
27 void (*format_write)(struct regmap *map, 27 void (*format_write)(struct regmap *map,
28 unsigned int reg, unsigned int val); 28 unsigned int reg, unsigned int val);
29 void (*format_reg)(void *buf, unsigned int reg); 29 void (*format_reg)(void *buf, unsigned int reg, unsigned int shift);
30 void (*format_val)(void *buf, unsigned int val); 30 void (*format_val)(void *buf, unsigned int val, unsigned int shift);
31 unsigned int (*parse_val)(void *buf); 31 unsigned int (*parse_val)(void *buf);
32}; 32};
33 33
34typedef void (*regmap_lock)(struct regmap *map);
35typedef void (*regmap_unlock)(struct regmap *map);
36
34struct regmap { 37struct regmap {
35 struct mutex lock; 38 struct mutex mutex;
39 spinlock_t spinlock;
40 regmap_lock lock;
41 regmap_unlock unlock;
36 42
37 struct device *dev; /* Device we do I/O on */ 43 struct device *dev; /* Device we do I/O on */
38 void *work_buf; /* Scratch buffer used to format I/O */ 44 void *work_buf; /* Scratch buffer used to format I/O */
39 struct regmap_format format; /* Buffer format */ 45 struct regmap_format format; /* Buffer format */
40 const struct regmap_bus *bus; 46 const struct regmap_bus *bus;
47 void *bus_context;
41 48
42#ifdef CONFIG_DEBUG_FS 49#ifdef CONFIG_DEBUG_FS
43 struct dentry *debugfs; 50 struct dentry *debugfs;
51 const char *debugfs_name;
44#endif 52#endif
45 53
46 unsigned int max_register; 54 unsigned int max_register;
@@ -52,6 +60,9 @@ struct regmap {
52 u8 read_flag_mask; 60 u8 read_flag_mask;
53 u8 write_flag_mask; 61 u8 write_flag_mask;
54 62
63 /* number of bits to (left) shift the reg value when formatting*/
64 int reg_shift;
65
55 /* regcache specific members */ 66 /* regcache specific members */
56 const struct regcache_ops *cache_ops; 67 const struct regcache_ops *cache_ops;
57 enum regcache_type cache_type; 68 enum regcache_type cache_type;
@@ -101,11 +112,11 @@ int _regmap_write(struct regmap *map, unsigned int reg,
101 112
102#ifdef CONFIG_DEBUG_FS 113#ifdef CONFIG_DEBUG_FS
103extern void regmap_debugfs_initcall(void); 114extern void regmap_debugfs_initcall(void);
104extern void regmap_debugfs_init(struct regmap *map); 115extern void regmap_debugfs_init(struct regmap *map, const char *name);
105extern void regmap_debugfs_exit(struct regmap *map); 116extern void regmap_debugfs_exit(struct regmap *map);
106#else 117#else
107static inline void regmap_debugfs_initcall(void) { } 118static inline void regmap_debugfs_initcall(void) { }
108static inline void regmap_debugfs_init(struct regmap *map) { } 119static inline void regmap_debugfs_init(struct regmap *map, const char *name) { }
109static inline void regmap_debugfs_exit(struct regmap *map) { } 120static inline void regmap_debugfs_exit(struct regmap *map) { }
110#endif 121#endif
111 122
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 92b779ee002b..e49e71fab184 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -140,7 +140,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
140 int registers = 0; 140 int registers = 0;
141 int average; 141 int average;
142 142
143 mutex_lock(&map->lock); 143 map->lock(map);
144 144
145 for (node = rb_first(&rbtree_ctx->root); node != NULL; 145 for (node = rb_first(&rbtree_ctx->root); node != NULL;
146 node = rb_next(node)) { 146 node = rb_next(node)) {
@@ -161,7 +161,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
161 seq_printf(s, "%d nodes, %d registers, average %d registers\n", 161 seq_printf(s, "%d nodes, %d registers, average %d registers\n",
162 nodes, registers, average); 162 nodes, registers, average);
163 163
164 mutex_unlock(&map->lock); 164 map->unlock(map);
165 165
166 return 0; 166 return 0;
167} 167}
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 74b69095def6..d4368e8b6f9d 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -264,7 +264,7 @@ int regcache_sync(struct regmap *map)
264 264
265 BUG_ON(!map->cache_ops || !map->cache_ops->sync); 265 BUG_ON(!map->cache_ops || !map->cache_ops->sync);
266 266
267 mutex_lock(&map->lock); 267 map->lock(map);
268 /* Remember the initial bypass state */ 268 /* Remember the initial bypass state */
269 bypass = map->cache_bypass; 269 bypass = map->cache_bypass;
270 dev_dbg(map->dev, "Syncing %s cache\n", 270 dev_dbg(map->dev, "Syncing %s cache\n",
@@ -296,7 +296,7 @@ out:
296 trace_regcache_sync(map->dev, name, "stop"); 296 trace_regcache_sync(map->dev, name, "stop");
297 /* Restore the bypass state */ 297 /* Restore the bypass state */
298 map->cache_bypass = bypass; 298 map->cache_bypass = bypass;
299 mutex_unlock(&map->lock); 299 map->unlock(map);
300 300
301 return ret; 301 return ret;
302} 302}
@@ -323,7 +323,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
323 323
324 BUG_ON(!map->cache_ops || !map->cache_ops->sync); 324 BUG_ON(!map->cache_ops || !map->cache_ops->sync);
325 325
326 mutex_lock(&map->lock); 326 map->lock(map);
327 327
328 /* Remember the initial bypass state */ 328 /* Remember the initial bypass state */
329 bypass = map->cache_bypass; 329 bypass = map->cache_bypass;
@@ -342,7 +342,7 @@ out:
342 trace_regcache_sync(map->dev, name, "stop region"); 342 trace_regcache_sync(map->dev, name, "stop region");
343 /* Restore the bypass state */ 343 /* Restore the bypass state */
344 map->cache_bypass = bypass; 344 map->cache_bypass = bypass;
345 mutex_unlock(&map->lock); 345 map->unlock(map);
346 346
347 return ret; 347 return ret;
348} 348}
@@ -362,11 +362,11 @@ EXPORT_SYMBOL_GPL(regcache_sync_region);
362 */ 362 */
363void regcache_cache_only(struct regmap *map, bool enable) 363void regcache_cache_only(struct regmap *map, bool enable)
364{ 364{
365 mutex_lock(&map->lock); 365 map->lock(map);
366 WARN_ON(map->cache_bypass && enable); 366 WARN_ON(map->cache_bypass && enable);
367 map->cache_only = enable; 367 map->cache_only = enable;
368 trace_regmap_cache_only(map->dev, enable); 368 trace_regmap_cache_only(map->dev, enable);
369 mutex_unlock(&map->lock); 369 map->unlock(map);
370} 370}
371EXPORT_SYMBOL_GPL(regcache_cache_only); 371EXPORT_SYMBOL_GPL(regcache_cache_only);
372 372
@@ -381,9 +381,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only);
381 */ 381 */
382void regcache_mark_dirty(struct regmap *map) 382void regcache_mark_dirty(struct regmap *map)
383{ 383{
384 mutex_lock(&map->lock); 384 map->lock(map);
385 map->cache_dirty = true; 385 map->cache_dirty = true;
386 mutex_unlock(&map->lock); 386 map->unlock(map);
387} 387}
388EXPORT_SYMBOL_GPL(regcache_mark_dirty); 388EXPORT_SYMBOL_GPL(regcache_mark_dirty);
389 389
@@ -400,11 +400,11 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty);
400 */ 400 */
401void regcache_cache_bypass(struct regmap *map, bool enable) 401void regcache_cache_bypass(struct regmap *map, bool enable)
402{ 402{
403 mutex_lock(&map->lock); 403 map->lock(map);
404 WARN_ON(map->cache_only && enable); 404 WARN_ON(map->cache_only && enable);
405 map->cache_bypass = enable; 405 map->cache_bypass = enable;
406 trace_regmap_cache_bypass(map->dev, enable); 406 trace_regmap_cache_bypass(map->dev, enable);
407 mutex_unlock(&map->lock); 407 map->unlock(map);
408} 408}
409EXPORT_SYMBOL_GPL(regcache_cache_bypass); 409EXPORT_SYMBOL_GPL(regcache_cache_bypass);
410 410
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 251eb70f83e7..df97c93efa8e 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -242,10 +242,17 @@ static const struct file_operations regmap_access_fops = {
242 .llseek = default_llseek, 242 .llseek = default_llseek,
243}; 243};
244 244
245void regmap_debugfs_init(struct regmap *map) 245void regmap_debugfs_init(struct regmap *map, const char *name)
246{ 246{
247 map->debugfs = debugfs_create_dir(dev_name(map->dev), 247 if (name) {
248 regmap_debugfs_root); 248 map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
249 dev_name(map->dev), name);
250 name = map->debugfs_name;
251 } else {
252 name = dev_name(map->dev);
253 }
254
255 map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
249 if (!map->debugfs) { 256 if (!map->debugfs) {
250 dev_warn(map->dev, "Failed to create debugfs directory\n"); 257 dev_warn(map->dev, "Failed to create debugfs directory\n");
251 return; 258 return;
@@ -274,6 +281,7 @@ void regmap_debugfs_init(struct regmap *map)
274void regmap_debugfs_exit(struct regmap *map) 281void regmap_debugfs_exit(struct regmap *map)
275{ 282{
276 debugfs_remove_recursive(map->debugfs); 283 debugfs_remove_recursive(map->debugfs);
284 kfree(map->debugfs_name);
277} 285}
278 286
279void regmap_debugfs_initcall(void) 287void regmap_debugfs_initcall(void)
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 9a3a8c564389..5f6b2478bf17 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -15,8 +15,9 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18static int regmap_i2c_write(struct device *dev, const void *data, size_t count) 18static int regmap_i2c_write(void *context, const void *data, size_t count)
19{ 19{
20 struct device *dev = context;
20 struct i2c_client *i2c = to_i2c_client(dev); 21 struct i2c_client *i2c = to_i2c_client(dev);
21 int ret; 22 int ret;
22 23
@@ -29,10 +30,11 @@ static int regmap_i2c_write(struct device *dev, const void *data, size_t count)
29 return -EIO; 30 return -EIO;
30} 31}
31 32
32static int regmap_i2c_gather_write(struct device *dev, 33static int regmap_i2c_gather_write(void *context,
33 const void *reg, size_t reg_size, 34 const void *reg, size_t reg_size,
34 const void *val, size_t val_size) 35 const void *val, size_t val_size)
35{ 36{
37 struct device *dev = context;
36 struct i2c_client *i2c = to_i2c_client(dev); 38 struct i2c_client *i2c = to_i2c_client(dev);
37 struct i2c_msg xfer[2]; 39 struct i2c_msg xfer[2];
38 int ret; 40 int ret;
@@ -62,10 +64,11 @@ static int regmap_i2c_gather_write(struct device *dev,
62 return -EIO; 64 return -EIO;
63} 65}
64 66
65static int regmap_i2c_read(struct device *dev, 67static int regmap_i2c_read(void *context,
66 const void *reg, size_t reg_size, 68 const void *reg, size_t reg_size,
67 void *val, size_t val_size) 69 void *val, size_t val_size)
68{ 70{
71 struct device *dev = context;
69 struct i2c_client *i2c = to_i2c_client(dev); 72 struct i2c_client *i2c = to_i2c_client(dev);
70 struct i2c_msg xfer[2]; 73 struct i2c_msg xfer[2];
71 int ret; 74 int ret;
@@ -107,7 +110,7 @@ static struct regmap_bus regmap_i2c = {
107struct regmap *regmap_init_i2c(struct i2c_client *i2c, 110struct regmap *regmap_init_i2c(struct i2c_client *i2c,
108 const struct regmap_config *config) 111 const struct regmap_config *config)
109{ 112{
110 return regmap_init(&i2c->dev, &regmap_i2c, config); 113 return regmap_init(&i2c->dev, &regmap_i2c, &i2c->dev, config);
111} 114}
112EXPORT_SYMBOL_GPL(regmap_init_i2c); 115EXPORT_SYMBOL_GPL(regmap_init_i2c);
113 116
@@ -124,7 +127,7 @@ EXPORT_SYMBOL_GPL(regmap_init_i2c);
124struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, 127struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
125 const struct regmap_config *config) 128 const struct regmap_config *config)
126{ 129{
127 return devm_regmap_init(&i2c->dev, &regmap_i2c, config); 130 return devm_regmap_init(&i2c->dev, &regmap_i2c, &i2c->dev, config);
128} 131}
129EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); 132EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
130 133
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c
new file mode 100644
index 000000000000..bdf4dc865293
--- /dev/null
+++ b/drivers/base/regmap/regmap-mmio.c
@@ -0,0 +1,211 @@
1/*
2 * Register map access API - MMIO support
3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/err.h>
20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/module.h>
23#include <linux/regmap.h>
24#include <linux/slab.h>
25
26struct regmap_mmio_context {
27 void __iomem *regs;
28 unsigned val_bytes;
29};
30
31static int regmap_mmio_gather_write(void *context,
32 const void *reg, size_t reg_size,
33 const void *val, size_t val_size)
34{
35 struct regmap_mmio_context *ctx = context;
36 u32 offset;
37
38 BUG_ON(reg_size != 4);
39
40 offset = be32_to_cpup(reg);
41
42 while (val_size) {
43 switch (ctx->val_bytes) {
44 case 1:
45 writeb(*(u8 *)val, ctx->regs + offset);
46 break;
47 case 2:
48 writew(be16_to_cpup(val), ctx->regs + offset);
49 break;
50 case 4:
51 writel(be32_to_cpup(val), ctx->regs + offset);
52 break;
53#ifdef CONFIG_64BIT
54 case 8:
55 writeq(be64_to_cpup(val), ctx->regs + offset);
56 break;
57#endif
58 default:
59 /* Should be caught by regmap_mmio_check_config */
60 BUG();
61 }
62 val_size -= ctx->val_bytes;
63 val += ctx->val_bytes;
64 offset += ctx->val_bytes;
65 }
66
67 return 0;
68}
69
70static int regmap_mmio_write(void *context, const void *data, size_t count)
71{
72 BUG_ON(count < 4);
73
74 return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4);
75}
76
77static int regmap_mmio_read(void *context,
78 const void *reg, size_t reg_size,
79 void *val, size_t val_size)
80{
81 struct regmap_mmio_context *ctx = context;
82 u32 offset;
83
84 BUG_ON(reg_size != 4);
85
86 offset = be32_to_cpup(reg);
87
88 while (val_size) {
89 switch (ctx->val_bytes) {
90 case 1:
91 *(u8 *)val = readb(ctx->regs + offset);
92 break;
93 case 2:
94 *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset));
95 break;
96 case 4:
97 *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset));
98 break;
99#ifdef CONFIG_64BIT
100 case 8:
101 *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset));
102 break;
103#endif
104 default:
105 /* Should be caught by regmap_mmio_check_config */
106 BUG();
107 }
108 val_size -= ctx->val_bytes;
109 val += ctx->val_bytes;
110 offset += ctx->val_bytes;
111 }
112
113 return 0;
114}
115
116static void regmap_mmio_free_context(void *context)
117{
118 kfree(context);
119}
120
121static struct regmap_bus regmap_mmio = {
122 .fast_io = true,
123 .write = regmap_mmio_write,
124 .gather_write = regmap_mmio_gather_write,
125 .read = regmap_mmio_read,
126 .free_context = regmap_mmio_free_context,
127};
128
129struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs,
130 const struct regmap_config *config)
131{
132 struct regmap_mmio_context *ctx;
133
134 if (config->reg_bits != 32)
135 return ERR_PTR(-EINVAL);
136
137 if (config->pad_bits)
138 return ERR_PTR(-EINVAL);
139
140 switch (config->val_bits) {
141 case 8:
142 case 16:
143 case 32:
144#ifdef CONFIG_64BIT
145 case 64:
146#endif
147 break;
148 default:
149 return ERR_PTR(-EINVAL);
150 }
151
152 ctx = kzalloc(GFP_KERNEL, sizeof(*ctx));
153 if (!ctx)
154 return ERR_PTR(-ENOMEM);
155
156 ctx->regs = regs;
157 ctx->val_bytes = config->val_bits / 8;
158
159 return ctx;
160}
161
162/**
163 * regmap_init_mmio(): Initialise register map
164 *
165 * @dev: Device that will be interacted with
166 * @regs: Pointer to memory-mapped IO region
167 * @config: Configuration for register map
168 *
169 * The return value will be an ERR_PTR() on error or a valid pointer to
170 * a struct regmap.
171 */
172struct regmap *regmap_init_mmio(struct device *dev,
173 void __iomem *regs,
174 const struct regmap_config *config)
175{
176 struct regmap_mmio_context *ctx;
177
178 ctx = regmap_mmio_gen_context(regs, config);
179 if (IS_ERR(ctx))
180 return ERR_CAST(ctx);
181
182 return regmap_init(dev, &regmap_mmio, ctx, config);
183}
184EXPORT_SYMBOL_GPL(regmap_init_mmio);
185
186/**
187 * devm_regmap_init_mmio(): Initialise managed register map
188 *
189 * @dev: Device that will be interacted with
190 * @regs: Pointer to memory-mapped IO region
191 * @config: Configuration for register map
192 *
193 * The return value will be an ERR_PTR() on error or a valid pointer
194 * to a struct regmap. The regmap will be automatically freed by the
195 * device management code.
196 */
197struct regmap *devm_regmap_init_mmio(struct device *dev,
198 void __iomem *regs,
199 const struct regmap_config *config)
200{
201 struct regmap_mmio_context *ctx;
202
203 ctx = regmap_mmio_gen_context(regs, config);
204 if (IS_ERR(ctx))
205 return ERR_CAST(ctx);
206
207 return devm_regmap_init(dev, &regmap_mmio, ctx, config);
208}
209EXPORT_SYMBOL_GPL(devm_regmap_init_mmio);
210
211MODULE_LICENSE("GPL v2");
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c
index 7c0c35a39c33..ffa46a92ad33 100644
--- a/drivers/base/regmap/regmap-spi.c
+++ b/drivers/base/regmap/regmap-spi.c
@@ -15,17 +15,19 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17 17
18static int regmap_spi_write(struct device *dev, const void *data, size_t count) 18static int regmap_spi_write(void *context, const void *data, size_t count)
19{ 19{
20 struct device *dev = context;
20 struct spi_device *spi = to_spi_device(dev); 21 struct spi_device *spi = to_spi_device(dev);
21 22
22 return spi_write(spi, data, count); 23 return spi_write(spi, data, count);
23} 24}
24 25
25static int regmap_spi_gather_write(struct device *dev, 26static int regmap_spi_gather_write(void *context,
26 const void *reg, size_t reg_len, 27 const void *reg, size_t reg_len,
27 const void *val, size_t val_len) 28 const void *val, size_t val_len)
28{ 29{
30 struct device *dev = context;
29 struct spi_device *spi = to_spi_device(dev); 31 struct spi_device *spi = to_spi_device(dev);
30 struct spi_message m; 32 struct spi_message m;
31 struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, 33 struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, },
@@ -38,10 +40,11 @@ static int regmap_spi_gather_write(struct device *dev,
38 return spi_sync(spi, &m); 40 return spi_sync(spi, &m);
39} 41}
40 42
41static int regmap_spi_read(struct device *dev, 43static int regmap_spi_read(void *context,
42 const void *reg, size_t reg_size, 44 const void *reg, size_t reg_size,
43 void *val, size_t val_size) 45 void *val, size_t val_size)
44{ 46{
47 struct device *dev = context;
45 struct spi_device *spi = to_spi_device(dev); 48 struct spi_device *spi = to_spi_device(dev);
46 49
47 return spi_write_then_read(spi, reg, reg_size, val, val_size); 50 return spi_write_then_read(spi, reg, reg_size, val, val_size);
@@ -66,7 +69,7 @@ static struct regmap_bus regmap_spi = {
66struct regmap *regmap_init_spi(struct spi_device *spi, 69struct regmap *regmap_init_spi(struct spi_device *spi,
67 const struct regmap_config *config) 70 const struct regmap_config *config)
68{ 71{
69 return regmap_init(&spi->dev, &regmap_spi, config); 72 return regmap_init(&spi->dev, &regmap_spi, &spi->dev, config);
70} 73}
71EXPORT_SYMBOL_GPL(regmap_init_spi); 74EXPORT_SYMBOL_GPL(regmap_init_spi);
72 75
@@ -83,7 +86,7 @@ EXPORT_SYMBOL_GPL(regmap_init_spi);
83struct regmap *devm_regmap_init_spi(struct spi_device *spi, 86struct regmap *devm_regmap_init_spi(struct spi_device *spi,
84 const struct regmap_config *config) 87 const struct regmap_config *config)
85{ 88{
86 return devm_regmap_init(&spi->dev, &regmap_spi, config); 89 return devm_regmap_init(&spi->dev, &regmap_spi, &spi->dev, config);
87} 90}
88EXPORT_SYMBOL_GPL(devm_regmap_init_spi); 91EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
89 92
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7a3f535e481c..40f910162781 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -112,25 +112,36 @@ static void regmap_format_10_14_write(struct regmap *map,
112 out[0] = reg >> 2; 112 out[0] = reg >> 2;
113} 113}
114 114
115static void regmap_format_8(void *buf, unsigned int val) 115static void regmap_format_8(void *buf, unsigned int val, unsigned int shift)
116{ 116{
117 u8 *b = buf; 117 u8 *b = buf;
118 118
119 b[0] = val; 119 b[0] = val << shift;
120} 120}
121 121
122static void regmap_format_16(void *buf, unsigned int val) 122static void regmap_format_16(void *buf, unsigned int val, unsigned int shift)
123{ 123{
124 __be16 *b = buf; 124 __be16 *b = buf;
125 125
126 b[0] = cpu_to_be16(val); 126 b[0] = cpu_to_be16(val << shift);
127} 127}
128 128
129static void regmap_format_32(void *buf, unsigned int val) 129static void regmap_format_24(void *buf, unsigned int val, unsigned int shift)
130{
131 u8 *b = buf;
132
133 val <<= shift;
134
135 b[0] = val >> 16;
136 b[1] = val >> 8;
137 b[2] = val;
138}
139
140static void regmap_format_32(void *buf, unsigned int val, unsigned int shift)
130{ 141{
131 __be32 *b = buf; 142 __be32 *b = buf;
132 143
133 b[0] = cpu_to_be32(val); 144 b[0] = cpu_to_be32(val << shift);
134} 145}
135 146
136static unsigned int regmap_parse_8(void *buf) 147static unsigned int regmap_parse_8(void *buf)
@@ -149,6 +160,16 @@ static unsigned int regmap_parse_16(void *buf)
149 return b[0]; 160 return b[0];
150} 161}
151 162
163static unsigned int regmap_parse_24(void *buf)
164{
165 u8 *b = buf;
166 unsigned int ret = b[2];
167 ret |= ((unsigned int)b[1]) << 8;
168 ret |= ((unsigned int)b[0]) << 16;
169
170 return ret;
171}
172
152static unsigned int regmap_parse_32(void *buf) 173static unsigned int regmap_parse_32(void *buf)
153{ 174{
154 __be32 *b = buf; 175 __be32 *b = buf;
@@ -158,11 +179,32 @@ static unsigned int regmap_parse_32(void *buf)
158 return b[0]; 179 return b[0];
159} 180}
160 181
182static void regmap_lock_mutex(struct regmap *map)
183{
184 mutex_lock(&map->mutex);
185}
186
187static void regmap_unlock_mutex(struct regmap *map)
188{
189 mutex_unlock(&map->mutex);
190}
191
192static void regmap_lock_spinlock(struct regmap *map)
193{
194 spin_lock(&map->spinlock);
195}
196
197static void regmap_unlock_spinlock(struct regmap *map)
198{
199 spin_unlock(&map->spinlock);
200}
201
161/** 202/**
162 * regmap_init(): Initialise register map 203 * regmap_init(): Initialise register map
163 * 204 *
164 * @dev: Device that will be interacted with 205 * @dev: Device that will be interacted with
165 * @bus: Bus-specific callbacks to use with device 206 * @bus: Bus-specific callbacks to use with device
207 * @bus_context: Data passed to bus-specific callbacks
166 * @config: Configuration for register map 208 * @config: Configuration for register map
167 * 209 *
168 * The return value will be an ERR_PTR() on error or a valid pointer to 210 * The return value will be an ERR_PTR() on error or a valid pointer to
@@ -171,6 +213,7 @@ static unsigned int regmap_parse_32(void *buf)
171 */ 213 */
172struct regmap *regmap_init(struct device *dev, 214struct regmap *regmap_init(struct device *dev,
173 const struct regmap_bus *bus, 215 const struct regmap_bus *bus,
216 void *bus_context,
174 const struct regmap_config *config) 217 const struct regmap_config *config)
175{ 218{
176 struct regmap *map; 219 struct regmap *map;
@@ -185,14 +228,24 @@ struct regmap *regmap_init(struct device *dev,
185 goto err; 228 goto err;
186 } 229 }
187 230
188 mutex_init(&map->lock); 231 if (bus->fast_io) {
232 spin_lock_init(&map->spinlock);
233 map->lock = regmap_lock_spinlock;
234 map->unlock = regmap_unlock_spinlock;
235 } else {
236 mutex_init(&map->mutex);
237 map->lock = regmap_lock_mutex;
238 map->unlock = regmap_unlock_mutex;
239 }
189 map->format.buf_size = (config->reg_bits + config->val_bits) / 8; 240 map->format.buf_size = (config->reg_bits + config->val_bits) / 8;
190 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); 241 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
191 map->format.pad_bytes = config->pad_bits / 8; 242 map->format.pad_bytes = config->pad_bits / 8;
192 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); 243 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
193 map->format.buf_size += map->format.pad_bytes; 244 map->format.buf_size += map->format.pad_bytes;
245 map->reg_shift = config->pad_bits % 8;
194 map->dev = dev; 246 map->dev = dev;
195 map->bus = bus; 247 map->bus = bus;
248 map->bus_context = bus_context;
196 map->max_register = config->max_register; 249 map->max_register = config->max_register;
197 map->writeable_reg = config->writeable_reg; 250 map->writeable_reg = config->writeable_reg;
198 map->readable_reg = config->readable_reg; 251 map->readable_reg = config->readable_reg;
@@ -207,7 +260,7 @@ struct regmap *regmap_init(struct device *dev,
207 map->read_flag_mask = bus->read_flag_mask; 260 map->read_flag_mask = bus->read_flag_mask;
208 } 261 }
209 262
210 switch (config->reg_bits) { 263 switch (config->reg_bits + map->reg_shift) {
211 case 2: 264 case 2:
212 switch (config->val_bits) { 265 switch (config->val_bits) {
213 case 6: 266 case 6:
@@ -273,6 +326,10 @@ struct regmap *regmap_init(struct device *dev,
273 map->format.format_val = regmap_format_16; 326 map->format.format_val = regmap_format_16;
274 map->format.parse_val = regmap_parse_16; 327 map->format.parse_val = regmap_parse_16;
275 break; 328 break;
329 case 24:
330 map->format.format_val = regmap_format_24;
331 map->format.parse_val = regmap_parse_24;
332 break;
276 case 32: 333 case 32:
277 map->format.format_val = regmap_format_32; 334 map->format.format_val = regmap_format_32;
278 map->format.parse_val = regmap_parse_32; 335 map->format.parse_val = regmap_parse_32;
@@ -289,7 +346,7 @@ struct regmap *regmap_init(struct device *dev,
289 goto err_map; 346 goto err_map;
290 } 347 }
291 348
292 regmap_debugfs_init(map); 349 regmap_debugfs_init(map, config->name);
293 350
294 ret = regcache_init(map, config); 351 ret = regcache_init(map, config);
295 if (ret < 0) 352 if (ret < 0)
@@ -316,6 +373,7 @@ static void devm_regmap_release(struct device *dev, void *res)
316 * 373 *
317 * @dev: Device that will be interacted with 374 * @dev: Device that will be interacted with
318 * @bus: Bus-specific callbacks to use with device 375 * @bus: Bus-specific callbacks to use with device
376 * @bus_context: Data passed to bus-specific callbacks
319 * @config: Configuration for register map 377 * @config: Configuration for register map
320 * 378 *
321 * The return value will be an ERR_PTR() on error or a valid pointer 379 * The return value will be an ERR_PTR() on error or a valid pointer
@@ -325,6 +383,7 @@ static void devm_regmap_release(struct device *dev, void *res)
325 */ 383 */
326struct regmap *devm_regmap_init(struct device *dev, 384struct regmap *devm_regmap_init(struct device *dev,
327 const struct regmap_bus *bus, 385 const struct regmap_bus *bus,
386 void *bus_context,
328 const struct regmap_config *config) 387 const struct regmap_config *config)
329{ 388{
330 struct regmap **ptr, *regmap; 389 struct regmap **ptr, *regmap;
@@ -333,7 +392,7 @@ struct regmap *devm_regmap_init(struct device *dev,
333 if (!ptr) 392 if (!ptr)
334 return ERR_PTR(-ENOMEM); 393 return ERR_PTR(-ENOMEM);
335 394
336 regmap = regmap_init(dev, bus, config); 395 regmap = regmap_init(dev, bus, bus_context, config);
337 if (!IS_ERR(regmap)) { 396 if (!IS_ERR(regmap)) {
338 *ptr = regmap; 397 *ptr = regmap;
339 devres_add(dev, ptr); 398 devres_add(dev, ptr);
@@ -360,7 +419,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
360{ 419{
361 int ret; 420 int ret;
362 421
363 mutex_lock(&map->lock); 422 map->lock(map);
364 423
365 regcache_exit(map); 424 regcache_exit(map);
366 regmap_debugfs_exit(map); 425 regmap_debugfs_exit(map);
@@ -372,14 +431,14 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
372 map->precious_reg = config->precious_reg; 431 map->precious_reg = config->precious_reg;
373 map->cache_type = config->cache_type; 432 map->cache_type = config->cache_type;
374 433
375 regmap_debugfs_init(map); 434 regmap_debugfs_init(map, config->name);
376 435
377 map->cache_bypass = false; 436 map->cache_bypass = false;
378 map->cache_only = false; 437 map->cache_only = false;
379 438
380 ret = regcache_init(map, config); 439 ret = regcache_init(map, config);
381 440
382 mutex_unlock(&map->lock); 441 map->unlock(map);
383 442
384 return ret; 443 return ret;
385} 444}
@@ -391,6 +450,8 @@ void regmap_exit(struct regmap *map)
391{ 450{
392 regcache_exit(map); 451 regcache_exit(map);
393 regmap_debugfs_exit(map); 452 regmap_debugfs_exit(map);
453 if (map->bus->free_context)
454 map->bus->free_context(map->bus_context);
394 kfree(map->work_buf); 455 kfree(map->work_buf);
395 kfree(map); 456 kfree(map);
396} 457}
@@ -431,7 +492,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
431 } 492 }
432 } 493 }
433 494
434 map->format.format_reg(map->work_buf, reg); 495 map->format.format_reg(map->work_buf, reg, map->reg_shift);
435 496
436 u8[0] |= map->write_flag_mask; 497 u8[0] |= map->write_flag_mask;
437 498
@@ -444,12 +505,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
444 */ 505 */
445 if (val == (map->work_buf + map->format.pad_bytes + 506 if (val == (map->work_buf + map->format.pad_bytes +
446 map->format.reg_bytes)) 507 map->format.reg_bytes))
447 ret = map->bus->write(map->dev, map->work_buf, 508 ret = map->bus->write(map->bus_context, map->work_buf,
448 map->format.reg_bytes + 509 map->format.reg_bytes +
449 map->format.pad_bytes + 510 map->format.pad_bytes +
450 val_len); 511 val_len);
451 else if (map->bus->gather_write) 512 else if (map->bus->gather_write)
452 ret = map->bus->gather_write(map->dev, map->work_buf, 513 ret = map->bus->gather_write(map->bus_context, map->work_buf,
453 map->format.reg_bytes + 514 map->format.reg_bytes +
454 map->format.pad_bytes, 515 map->format.pad_bytes,
455 val, val_len); 516 val, val_len);
@@ -464,7 +525,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
464 memcpy(buf, map->work_buf, map->format.reg_bytes); 525 memcpy(buf, map->work_buf, map->format.reg_bytes);
465 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, 526 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
466 val, val_len); 527 val, val_len);
467 ret = map->bus->write(map->dev, buf, len); 528 ret = map->bus->write(map->bus_context, buf, len);
468 529
469 kfree(buf); 530 kfree(buf);
470 } 531 }
@@ -498,7 +559,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
498 559
499 trace_regmap_hw_write_start(map->dev, reg, 1); 560 trace_regmap_hw_write_start(map->dev, reg, 1);
500 561
501 ret = map->bus->write(map->dev, map->work_buf, 562 ret = map->bus->write(map->bus_context, map->work_buf,
502 map->format.buf_size); 563 map->format.buf_size);
503 564
504 trace_regmap_hw_write_done(map->dev, reg, 1); 565 trace_regmap_hw_write_done(map->dev, reg, 1);
@@ -506,7 +567,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
506 return ret; 567 return ret;
507 } else { 568 } else {
508 map->format.format_val(map->work_buf + map->format.reg_bytes 569 map->format.format_val(map->work_buf + map->format.reg_bytes
509 + map->format.pad_bytes, val); 570 + map->format.pad_bytes, val, 0);
510 return _regmap_raw_write(map, reg, 571 return _regmap_raw_write(map, reg,
511 map->work_buf + 572 map->work_buf +
512 map->format.reg_bytes + 573 map->format.reg_bytes +
@@ -529,11 +590,11 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
529{ 590{
530 int ret; 591 int ret;
531 592
532 mutex_lock(&map->lock); 593 map->lock(map);
533 594
534 ret = _regmap_write(map, reg, val); 595 ret = _regmap_write(map, reg, val);
535 596
536 mutex_unlock(&map->lock); 597 map->unlock(map);
537 598
538 return ret; 599 return ret;
539} 600}
@@ -560,11 +621,14 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
560{ 621{
561 int ret; 622 int ret;
562 623
563 mutex_lock(&map->lock); 624 if (val_len % map->format.val_bytes)
625 return -EINVAL;
626
627 map->lock(map);
564 628
565 ret = _regmap_raw_write(map, reg, val, val_len); 629 ret = _regmap_raw_write(map, reg, val, val_len);
566 630
567 mutex_unlock(&map->lock); 631 map->unlock(map);
568 632
569 return ret; 633 return ret;
570} 634}
@@ -594,7 +658,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
594 if (!map->format.parse_val) 658 if (!map->format.parse_val)
595 return -EINVAL; 659 return -EINVAL;
596 660
597 mutex_lock(&map->lock); 661 map->lock(map);
598 662
599 /* No formatting is require if val_byte is 1 */ 663 /* No formatting is require if val_byte is 1 */
600 if (val_bytes == 1) { 664 if (val_bytes == 1) {
@@ -615,7 +679,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
615 kfree(wval); 679 kfree(wval);
616 680
617out: 681out:
618 mutex_unlock(&map->lock); 682 map->unlock(map);
619 return ret; 683 return ret;
620} 684}
621EXPORT_SYMBOL_GPL(regmap_bulk_write); 685EXPORT_SYMBOL_GPL(regmap_bulk_write);
@@ -626,7 +690,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
626 u8 *u8 = map->work_buf; 690 u8 *u8 = map->work_buf;
627 int ret; 691 int ret;
628 692
629 map->format.format_reg(map->work_buf, reg); 693 map->format.format_reg(map->work_buf, reg, map->reg_shift);
630 694
631 /* 695 /*
632 * Some buses or devices flag reads by setting the high bits in the 696 * Some buses or devices flag reads by setting the high bits in the
@@ -639,7 +703,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
639 trace_regmap_hw_read_start(map->dev, reg, 703 trace_regmap_hw_read_start(map->dev, reg,
640 val_len / map->format.val_bytes); 704 val_len / map->format.val_bytes);
641 705
642 ret = map->bus->read(map->dev, map->work_buf, 706 ret = map->bus->read(map->bus_context, map->work_buf,
643 map->format.reg_bytes + map->format.pad_bytes, 707 map->format.reg_bytes + map->format.pad_bytes,
644 val, val_len); 708 val, val_len);
645 709
@@ -689,11 +753,11 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
689{ 753{
690 int ret; 754 int ret;
691 755
692 mutex_lock(&map->lock); 756 map->lock(map);
693 757
694 ret = _regmap_read(map, reg, val); 758 ret = _regmap_read(map, reg, val);
695 759
696 mutex_unlock(&map->lock); 760 map->unlock(map);
697 761
698 return ret; 762 return ret;
699} 763}
@@ -718,7 +782,10 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
718 unsigned int v; 782 unsigned int v;
719 int ret, i; 783 int ret, i;
720 784
721 mutex_lock(&map->lock); 785 if (val_len % map->format.val_bytes)
786 return -EINVAL;
787
788 map->lock(map);
722 789
723 if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || 790 if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
724 map->cache_type == REGCACHE_NONE) { 791 map->cache_type == REGCACHE_NONE) {
@@ -734,12 +801,12 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
734 if (ret != 0) 801 if (ret != 0)
735 goto out; 802 goto out;
736 803
737 map->format.format_val(val + (i * val_bytes), v); 804 map->format.format_val(val + (i * val_bytes), v, 0);
738 } 805 }
739 } 806 }
740 807
741 out: 808 out:
742 mutex_unlock(&map->lock); 809 map->unlock(map);
743 810
744 return ret; 811 return ret;
745} 812}
@@ -792,7 +859,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
792 int ret; 859 int ret;
793 unsigned int tmp, orig; 860 unsigned int tmp, orig;
794 861
795 mutex_lock(&map->lock); 862 map->lock(map);
796 863
797 ret = _regmap_read(map, reg, &orig); 864 ret = _regmap_read(map, reg, &orig);
798 if (ret != 0) 865 if (ret != 0)
@@ -809,7 +876,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
809 } 876 }
810 877
811out: 878out:
812 mutex_unlock(&map->lock); 879 map->unlock(map);
813 880
814 return ret; 881 return ret;
815} 882}
@@ -876,7 +943,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
876 if (map->patch) 943 if (map->patch)
877 return -EBUSY; 944 return -EBUSY;
878 945
879 mutex_lock(&map->lock); 946 map->lock(map);
880 947
881 bypass = map->cache_bypass; 948 bypass = map->cache_bypass;
882 949
@@ -904,7 +971,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
904out: 971out:
905 map->cache_bypass = bypass; 972 map->cache_bypass = bypass;
906 973
907 mutex_unlock(&map->lock); 974 map->unlock(map);
908 975
909 return ret; 976 return ret;
910} 977}