13 #include <linux/slab.h>
14 #include <linux/device.h>
19 static int regcache_lzo_exit(
struct regmap *
map);
32 #define LZO_BLOCK_NUM 8
33 static int regcache_lzo_block_count(
struct regmap *
map)
52 lzo_ctx->
dst, &compress_size, lzo_ctx->
wmem);
55 lzo_ctx->
dst_len = compress_size;
66 lzo_ctx->
dst, &dst_len);
72 static int regcache_lzo_compress_cache_block(
struct regmap *
map,
84 ret = regcache_lzo_compress(lzo_ctx);
90 static int regcache_lzo_decompress_cache_block(
struct regmap *map,
102 ret = regcache_lzo_decompress(lzo_ctx);
108 static inline int regcache_lzo_get_blkindex(
struct regmap *map,
113 regcache_lzo_block_count(map));
116 static inline int regcache_lzo_get_blkpos(
struct regmap *map,
121 regcache_lzo_block_count(map)) /
125 static inline int regcache_lzo_get_blksize(
struct regmap *map)
128 regcache_lzo_block_count(map));
131 static int regcache_lzo_init(
struct regmap *map)
135 int ret,
i, blksize, blkcount;
141 blkcount = regcache_lzo_block_count(map);
142 map->
cache = kzalloc(blkcount *
sizeof *lzo_blocks,
146 lzo_blocks = map->
cache;
161 bitmap_zero(sync_bmp, bmp_size);
164 for (i = 0; i < blkcount; i++) {
165 lzo_blocks[
i] = kzalloc(
sizeof **lzo_blocks,
167 if (!lzo_blocks[i]) {
175 ret = regcache_lzo_prepare(lzo_blocks[i]);
180 blksize = regcache_lzo_get_blksize(map);
184 for (i = 0; i < blkcount; i++, p += blksize) {
185 lzo_blocks[
i]->
src =
p;
186 if (p + blksize > end)
190 ret = regcache_lzo_compress_cache_block(map,
200 regcache_lzo_exit(map);
204 static int regcache_lzo_exit(
struct regmap *map)
209 lzo_blocks = map->
cache;
213 blkcount = regcache_lzo_block_count(map);
220 kfree(lzo_blocks[0]->sync_bmp);
221 for (i = 0; i < blkcount; i++) {
227 kfree(lzo_blocks[i]);
234 static int regcache_lzo_read(
struct regmap *map,
235 unsigned int reg,
unsigned int *
value)
238 int ret, blkindex, blkpos;
239 size_t blksize, tmp_dst_len;
243 blkindex = regcache_lzo_get_blkindex(map, reg);
245 blkpos = regcache_lzo_get_blkpos(map, reg);
247 blksize = regcache_lzo_get_blksize(map);
248 lzo_blocks = map->
cache;
249 lzo_block = lzo_blocks[blkindex];
252 tmp_dst = lzo_block->
dst;
253 tmp_dst_len = lzo_block->
dst_len;
256 lzo_block->
src = lzo_block->
dst;
260 ret = regcache_lzo_decompress_cache_block(map, lzo_block);
268 lzo_block->
dst = tmp_dst;
269 lzo_block->
dst_len = tmp_dst_len;
274 static int regcache_lzo_write(
struct regmap *map,
275 unsigned int reg,
unsigned int value)
278 int ret, blkindex, blkpos;
279 size_t blksize, tmp_dst_len;
283 blkindex = regcache_lzo_get_blkindex(map, reg);
285 blkpos = regcache_lzo_get_blkpos(map, reg);
287 blksize = regcache_lzo_get_blksize(map);
288 lzo_blocks = map->
cache;
289 lzo_block = lzo_blocks[blkindex];
292 tmp_dst = lzo_block->
dst;
293 tmp_dst_len = lzo_block->
dst_len;
296 lzo_block->
src = lzo_block->
dst;
300 ret = regcache_lzo_decompress_cache_block(map, lzo_block);
314 lzo_block->
src = lzo_block->
dst;
318 ret = regcache_lzo_compress_cache_block(map, lzo_block);
331 lzo_block->
dst = tmp_dst;
332 lzo_block->
dst_len = tmp_dst_len;
336 static int regcache_lzo_sync(
struct regmap *map,
unsigned int min,
344 lzo_blocks = map->
cache;
365 dev_dbg(map->
dev,
"Synced register %#x, value %#x\n",
375 .init = regcache_lzo_init,
376 .exit = regcache_lzo_exit,
377 .read = regcache_lzo_read,
378 .write = regcache_lzo_write,
379 .sync = regcache_lzo_sync