aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/Makefile3
-rw-r--r--drivers/base/regmap/internal.h1
-rw-r--r--drivers/base/regmap/regcache-lzo.c17
-rw-r--r--drivers/base/regmap/regcache.c19
-rw-r--r--drivers/base/regmap/regmap.c6
-rw-r--r--include/linux/regmap.h3
6 files changed, 38 insertions, 11 deletions
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index ce2d18a6465b..3dbe5d3ff227 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_REGMAP) += regmap.o regcache.o regcache-indexed.o regcache-rbtree.o regcache-lzo.o 1obj-$(CONFIG_REGMAP) += regmap.o regcache.o regcache-indexed.o
2obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o
2obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o 3obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
3obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o 4obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
4obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o 5obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 348ff02eb93e..6483e0bda0cf 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -74,6 +74,7 @@ struct regmap {
74 struct reg_default *reg_defaults; 74 struct reg_default *reg_defaults;
75 const void *reg_defaults_raw; 75 const void *reg_defaults_raw;
76 void *cache; 76 void *cache;
77 bool cache_dirty;
77}; 78};
78 79
79struct regcache_ops { 80struct regcache_ops {
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c
index 066aeece3626..226ffc13bc25 100644
--- a/drivers/base/regmap/regcache-lzo.c
+++ b/drivers/base/regmap/regcache-lzo.c
@@ -27,7 +27,7 @@ struct regcache_lzo_ctx {
27}; 27};
28 28
29#define LZO_BLOCK_NUM 8 29#define LZO_BLOCK_NUM 8
30static int regcache_lzo_block_count(void) 30static int regcache_lzo_block_count(struct regmap *map)
31{ 31{
32 return LZO_BLOCK_NUM; 32 return LZO_BLOCK_NUM;
33} 33}
@@ -106,19 +106,22 @@ static inline int regcache_lzo_get_blkindex(struct regmap *map,
106 unsigned int reg) 106 unsigned int reg)
107{ 107{
108 return (reg * map->cache_word_size) / 108 return (reg * map->cache_word_size) /
109 DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count()); 109 DIV_ROUND_UP(map->cache_size_raw,
110 regcache_lzo_block_count(map));
110} 111}
111 112
112static inline int regcache_lzo_get_blkpos(struct regmap *map, 113static inline int regcache_lzo_get_blkpos(struct regmap *map,
113 unsigned int reg) 114 unsigned int reg)
114{ 115{
115 return reg % (DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count()) / 116 return reg % (DIV_ROUND_UP(map->cache_size_raw,
117 regcache_lzo_block_count(map)) /
116 map->cache_word_size); 118 map->cache_word_size);
117} 119}
118 120
119static inline int regcache_lzo_get_blksize(struct regmap *map) 121static inline int regcache_lzo_get_blksize(struct regmap *map)
120{ 122{
121 return DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count()); 123 return DIV_ROUND_UP(map->cache_size_raw,
124 regcache_lzo_block_count(map));
122} 125}
123 126
124static int regcache_lzo_init(struct regmap *map) 127static int regcache_lzo_init(struct regmap *map)
@@ -131,7 +134,7 @@ static int regcache_lzo_init(struct regmap *map)
131 134
132 ret = 0; 135 ret = 0;
133 136
134 blkcount = regcache_lzo_block_count(); 137 blkcount = regcache_lzo_block_count(map);
135 map->cache = kzalloc(blkcount * sizeof *lzo_blocks, 138 map->cache = kzalloc(blkcount * sizeof *lzo_blocks,
136 GFP_KERNEL); 139 GFP_KERNEL);
137 if (!map->cache) 140 if (!map->cache)
@@ -203,7 +206,7 @@ static int regcache_lzo_exit(struct regmap *map)
203 if (!lzo_blocks) 206 if (!lzo_blocks)
204 return 0; 207 return 0;
205 208
206 blkcount = regcache_lzo_block_count(); 209 blkcount = regcache_lzo_block_count(map);
207 /* 210 /*
208 * the pointer to the bitmap used for syncing the cache 211 * the pointer to the bitmap used for syncing the cache
209 * is shared amongst all lzo_blocks. Ensure it is freed 212 * is shared amongst all lzo_blocks. Ensure it is freed
@@ -351,7 +354,7 @@ static int regcache_lzo_sync(struct regmap *map)
351} 354}
352 355
353struct regcache_ops regcache_lzo_ops = { 356struct regcache_ops regcache_lzo_ops = {
354 .type = REGCACHE_LZO, 357 .type = REGCACHE_COMPRESSED,
355 .name = "lzo", 358 .name = "lzo",
356 .init = regcache_lzo_init, 359 .init = regcache_lzo_init,
357 .exit = regcache_lzo_exit, 360 .exit = regcache_lzo_exit,
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 666f6f5011dc..6ab9f0384d82 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -241,6 +241,8 @@ int regcache_sync(struct regmap *map)
241 map->cache_ops->name); 241 map->cache_ops->name);
242 name = map->cache_ops->name; 242 name = map->cache_ops->name;
243 trace_regcache_sync(map->dev, name, "start"); 243 trace_regcache_sync(map->dev, name, "start");
244 if (!map->cache_dirty)
245 goto out;
244 if (map->cache_ops->sync) { 246 if (map->cache_ops->sync) {
245 ret = map->cache_ops->sync(map); 247 ret = map->cache_ops->sync(map);
246 } else { 248 } else {
@@ -291,6 +293,23 @@ void regcache_cache_only(struct regmap *map, bool enable)
291EXPORT_SYMBOL_GPL(regcache_cache_only); 293EXPORT_SYMBOL_GPL(regcache_cache_only);
292 294
293/** 295/**
296 * regcache_mark_dirty: Mark the register cache as dirty
297 *
298 * @map: map to mark
299 *
300 * Mark the register cache as dirty, for example due to the device
301 * having been powered down for suspend. If the cache is not marked
302 * as dirty then the cache sync will be suppressed.
303 */
304void regcache_mark_dirty(struct regmap *map)
305{
306 mutex_lock(&map->lock);
307 map->cache_dirty = true;
308 mutex_unlock(&map->lock);
309}
310EXPORT_SYMBOL_GPL(regcache_mark_dirty);
311
312/**
294 * regcache_cache_bypass: Put a register map into cache bypass mode 313 * regcache_cache_bypass: Put a register map into cache bypass mode
295 * 314 *
296 * @map: map to configure 315 * @map: map to configure
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index bf441db1ee90..f7cfff2b8714 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -306,8 +306,10 @@ int _regmap_write(struct regmap *map, unsigned int reg,
306 ret = regcache_write(map, reg, val); 306 ret = regcache_write(map, reg, val);
307 if (ret != 0) 307 if (ret != 0)
308 return ret; 308 return ret;
309 if (map->cache_only) 309 if (map->cache_only) {
310 map->cache_dirty = true;
310 return 0; 311 return 0;
312 }
311 } 313 }
312 314
313 trace_regmap_reg_write(map->dev, reg, val); 315 trace_regmap_reg_write(map->dev, reg, val);
@@ -547,7 +549,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
547EXPORT_SYMBOL_GPL(regmap_bulk_read); 549EXPORT_SYMBOL_GPL(regmap_bulk_read);
548 550
549/** 551/**
550 * remap_update_bits: Perform a read/modify/write cycle on the register map 552 * regmap_update_bits: Perform a read/modify/write cycle on the register map
551 * 553 *
552 * @map: Register map to update 554 * @map: Register map to update
553 * @reg: Register to update 555 * @reg: Register to update
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index bd54cecdfdf8..1e4ec2b6c2ea 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -25,7 +25,7 @@ enum regcache_type {
25 REGCACHE_NONE, 25 REGCACHE_NONE,
26 REGCACHE_INDEXED, 26 REGCACHE_INDEXED,
27 REGCACHE_RBTREE, 27 REGCACHE_RBTREE,
28 REGCACHE_LZO 28 REGCACHE_COMPRESSED
29}; 29};
30 30
31/** 31/**
@@ -143,6 +143,7 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
143int regcache_sync(struct regmap *map); 143int regcache_sync(struct regmap *map);
144void regcache_cache_only(struct regmap *map, bool enable); 144void regcache_cache_only(struct regmap *map, bool enable);
145void regcache_cache_bypass(struct regmap *map, bool enable); 145void regcache_cache_bypass(struct regmap *map, bool enable);
146void regcache_mark_dirty(struct regmap *map);
146 147
147/** 148/**
148 * Description of an IRQ for the generic regmap irq_chip. 149 * Description of an IRQ for the generic regmap irq_chip.