diff options
-rw-r--r-- | drivers/base/regmap/Makefile | 3 | ||||
-rw-r--r-- | drivers/base/regmap/internal.h | 1 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-lzo.c | 17 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 19 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 6 | ||||
-rw-r--r-- | include/linux/regmap.h | 3 |
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 @@ | |||
1 | obj-$(CONFIG_REGMAP) += regmap.o regcache.o regcache-indexed.o regcache-rbtree.o regcache-lzo.o | 1 | obj-$(CONFIG_REGMAP) += regmap.o regcache.o regcache-indexed.o |
2 | obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o | ||
2 | obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o | 3 | obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o |
3 | obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o | 4 | obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o |
4 | obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o | 5 | obj-$(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 | ||
79 | struct regcache_ops { | 80 | struct 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 |
30 | static int regcache_lzo_block_count(void) | 30 | static 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 | ||
112 | static inline int regcache_lzo_get_blkpos(struct regmap *map, | 113 | static 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 | ||
119 | static inline int regcache_lzo_get_blksize(struct regmap *map) | 121 | static 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 | ||
124 | static int regcache_lzo_init(struct regmap *map) | 127 | static 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 | ||
353 | struct regcache_ops regcache_lzo_ops = { | 356 | struct 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) | |||
291 | EXPORT_SYMBOL_GPL(regcache_cache_only); | 293 | EXPORT_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 | */ | ||
304 | void regcache_mark_dirty(struct regmap *map) | ||
305 | { | ||
306 | mutex_lock(&map->lock); | ||
307 | map->cache_dirty = true; | ||
308 | mutex_unlock(&map->lock); | ||
309 | } | ||
310 | EXPORT_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, | |||
547 | EXPORT_SYMBOL_GPL(regmap_bulk_read); | 549 | EXPORT_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, | |||
143 | int regcache_sync(struct regmap *map); | 143 | int regcache_sync(struct regmap *map); |
144 | void regcache_cache_only(struct regmap *map, bool enable); | 144 | void regcache_cache_only(struct regmap *map, bool enable); |
145 | void regcache_cache_bypass(struct regmap *map, bool enable); | 145 | void regcache_cache_bypass(struct regmap *map, bool enable); |
146 | void 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. |