aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:32:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:32:44 -0400
commitae82a8282031e3c31a4f68c5381ee459e42908f8 (patch)
treeb44f69623afe44d57d5c0fa83f000ec1edda408f
parent3bb07f1b73ea6313b843807063e183e168c9182a (diff)
parentc948ef3ae71c18c1079333b65d6887ceb4577618 (diff)
Merge tag 'regmap-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown: "A surprisingly large series of updates for regmap this time, mostly due to all the work Stephen Warren has done to add support for MMIO buses. This wasn't really the target for the framework but it turns out that there's a reasonable number of cases where it's very helpful to use the register cache support to allow the register map to remain available while the device is suspended. - A MMIO bus implementation, contributed by Stephen Warren. Currently this is limited to 32 bit systems and native endian registers. - Support for naming register maps, mainly intended for MMIO devices with multiple register banks. This was also contributed by Stephen Warren. - Support for register striding, again contributed by Stephen Warren and mainly intended for use with MMIO as typically the registers will be a fixed size but byte addressed. - irqdomain support for the generic regmap irq_chip, including support for dynamically allocate interrupt numbers. - A function dev_get_regmap() which allows frameworks using regmap to obtain the regmap for a device from the struct device, making life a little simpler for them. - Updates to regmap-irq to support more chips (contributed by Graeme Gregory) and to use irqdomains. - Support for devices with 24 bit register addresses. The striding support collided with all the topic branches so the branches look a bit messy and eventually I just gave up. There's also the TI Palmas driver and a couple of other isolated MFD patches that all depend on new regmap features so are being merged here." * tag 'regmap-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: (24 commits) mfd: palmas PMIC device support Kconfig mfd: palmas PMIC device support regmap: Fix typo in IRQ register striding mfd: wm8994: Update to fully use irq_domain regmap: add support for non contiguous status to regmap-irq regmap: Convert regmap_irq to use irq_domain regmap: Pass back the allocated regmap IRQ controller data mfd: da9052: Fix genirq abuse regmap: Implement dev_get_regmap() regmap: Devices using format_write don't support bulk operations regmap: Converts group operation into single read write operations regmap: Cache single values read from the chip regmap: fix compile errors in regmap-irq.c due to stride changes regmap: implement register striding regmap: fix compilation when !CONFIG_DEBUG_FS regmap: allow regmap instances to be named regmap: validate regmap_raw_read/write val_len regmap: mmio: remove some error checks now in the core regmap: mmio: convert some error returns to BUG() regmap: add MMIO bus support ...
-rw-r--r--drivers/base/regmap/Kconfig3
-rw-r--r--drivers/base/regmap/Makefile1
-rw-r--r--drivers/base/regmap/internal.h26
-rw-r--r--drivers/base/regmap/regcache-lzo.c11
-rw-r--r--drivers/base/regmap/regcache-rbtree.c44
-rw-r--r--drivers/base/regmap/regcache.c34
-rw-r--r--drivers/base/regmap/regmap-debugfs.c18
-rw-r--r--drivers/base/regmap/regmap-i2c.c13
-rw-r--r--drivers/base/regmap/regmap-irq.c184
-rw-r--r--drivers/base/regmap/regmap-mmio.c224
-rw-r--r--drivers/base/regmap/regmap-spi.c13
-rw-r--r--drivers/base/regmap/regmap.c276
-rw-r--r--drivers/mfd/Kconfig13
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/da9052-core.c8
-rw-r--r--drivers/mfd/palmas.c509
-rw-r--r--drivers/mfd/wm8994-irq.c6
-rw-r--r--include/linux/mfd/da9052/da9052.h1
-rw-r--r--include/linux/mfd/palmas.h2620
-rw-r--r--include/linux/mfd/wm8994/core.h12
-rw-r--r--include/linux/regmap.h44
21 files changed, 3872 insertions, 190 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..b986b8660b0c 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -26,21 +26,30 @@ 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;
48 const char *name;
41 49
42#ifdef CONFIG_DEBUG_FS 50#ifdef CONFIG_DEBUG_FS
43 struct dentry *debugfs; 51 struct dentry *debugfs;
52 const char *debugfs_name;
44#endif 53#endif
45 54
46 unsigned int max_register; 55 unsigned int max_register;
@@ -52,6 +61,10 @@ struct regmap {
52 u8 read_flag_mask; 61 u8 read_flag_mask;
53 u8 write_flag_mask; 62 u8 write_flag_mask;
54 63
64 /* number of bits to (left) shift the reg value when formatting*/
65 int reg_shift;
66 int reg_stride;
67
55 /* regcache specific members */ 68 /* regcache specific members */
56 const struct regcache_ops *cache_ops; 69 const struct regcache_ops *cache_ops;
57 enum regcache_type cache_type; 70 enum regcache_type cache_type;
@@ -79,6 +92,9 @@ struct regmap {
79 92
80 struct reg_default *patch; 93 struct reg_default *patch;
81 int patch_regs; 94 int patch_regs;
95
96 /* if set, converts bulk rw to single rw */
97 bool use_single_rw;
82}; 98};
83 99
84struct regcache_ops { 100struct regcache_ops {
@@ -101,11 +117,11 @@ int _regmap_write(struct regmap *map, unsigned int reg,
101 117
102#ifdef CONFIG_DEBUG_FS 118#ifdef CONFIG_DEBUG_FS
103extern void regmap_debugfs_initcall(void); 119extern void regmap_debugfs_initcall(void);
104extern void regmap_debugfs_init(struct regmap *map); 120extern void regmap_debugfs_init(struct regmap *map, const char *name);
105extern void regmap_debugfs_exit(struct regmap *map); 121extern void regmap_debugfs_exit(struct regmap *map);
106#else 122#else
107static inline void regmap_debugfs_initcall(void) { } 123static inline void regmap_debugfs_initcall(void) { }
108static inline void regmap_debugfs_init(struct regmap *map) { } 124static inline void regmap_debugfs_init(struct regmap *map, const char *name) { }
109static inline void regmap_debugfs_exit(struct regmap *map) { } 125static inline void regmap_debugfs_exit(struct regmap *map) { }
110#endif 126#endif
111 127
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c
index 483b06d4a380..afd6aa91a0df 100644
--- a/drivers/base/regmap/regcache-lzo.c
+++ b/drivers/base/regmap/regcache-lzo.c
@@ -108,7 +108,7 @@ static int regcache_lzo_decompress_cache_block(struct regmap *map,
108static inline int regcache_lzo_get_blkindex(struct regmap *map, 108static inline int regcache_lzo_get_blkindex(struct regmap *map,
109 unsigned int reg) 109 unsigned int reg)
110{ 110{
111 return (reg * map->cache_word_size) / 111 return ((reg / map->reg_stride) * map->cache_word_size) /
112 DIV_ROUND_UP(map->cache_size_raw, 112 DIV_ROUND_UP(map->cache_size_raw,
113 regcache_lzo_block_count(map)); 113 regcache_lzo_block_count(map));
114} 114}
@@ -116,9 +116,10 @@ static inline int regcache_lzo_get_blkindex(struct regmap *map,
116static inline int regcache_lzo_get_blkpos(struct regmap *map, 116static inline int regcache_lzo_get_blkpos(struct regmap *map,
117 unsigned int reg) 117 unsigned int reg)
118{ 118{
119 return reg % (DIV_ROUND_UP(map->cache_size_raw, 119 return (reg / map->reg_stride) %
120 regcache_lzo_block_count(map)) / 120 (DIV_ROUND_UP(map->cache_size_raw,
121 map->cache_word_size); 121 regcache_lzo_block_count(map)) /
122 map->cache_word_size);
122} 123}
123 124
124static inline int regcache_lzo_get_blksize(struct regmap *map) 125static inline int regcache_lzo_get_blksize(struct regmap *map)
@@ -322,7 +323,7 @@ static int regcache_lzo_write(struct regmap *map,
322 } 323 }
323 324
324 /* set the bit so we know we have to sync this register */ 325 /* set the bit so we know we have to sync this register */
325 set_bit(reg, lzo_block->sync_bmp); 326 set_bit(reg / map->reg_stride, lzo_block->sync_bmp);
326 kfree(tmp_dst); 327 kfree(tmp_dst);
327 kfree(lzo_block->src); 328 kfree(lzo_block->src);
328 return 0; 329 return 0;
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 92b779ee002b..e6732cf7c06e 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -39,11 +39,12 @@ struct regcache_rbtree_ctx {
39}; 39};
40 40
41static inline void regcache_rbtree_get_base_top_reg( 41static inline void regcache_rbtree_get_base_top_reg(
42 struct regmap *map,
42 struct regcache_rbtree_node *rbnode, 43 struct regcache_rbtree_node *rbnode,
43 unsigned int *base, unsigned int *top) 44 unsigned int *base, unsigned int *top)
44{ 45{
45 *base = rbnode->base_reg; 46 *base = rbnode->base_reg;
46 *top = rbnode->base_reg + rbnode->blklen - 1;