Skip to content

Commit

Permalink
regmap: flat: Add flat cache type
Browse files Browse the repository at this point in the history
While for I2C and SPI devices the overhead of using rbtree for devices with
only one block of registers is negligible the same isn't always going to
be true for MMIO devices where the I/O costs are very much lower. Cater
for these devices by adding a simple flat array type for them where the
lookups are simple array accesses, taking us right back to the original
ASoC cache implementation.

Thanks to Magnus Damm for the discussion which prompted this.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Jan 2, 2013
1 parent a49f0d1 commit 2ac902c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 2 deletions.
2 changes: 1 addition & 1 deletion drivers/base/regmap/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
obj-$(CONFIG_REGMAP) += regmap.o regcache.o
obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o
obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.o
obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
Expand Down
1 change: 1 addition & 0 deletions drivers/base/regmap/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,6 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg);

extern struct regcache_ops regcache_rbtree_ops;
extern struct regcache_ops regcache_lzo_ops;
extern struct regcache_ops regcache_flat_ops;

#endif
72 changes: 72 additions & 0 deletions drivers/base/regmap/regcache-flat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Register cache access API - flat caching support
*
* Copyright 2012 Wolfson Microelectronics plc
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/slab.h>
#include <linux/device.h>
#include <linux/seq_file.h>

#include "internal.h"

static int regcache_flat_init(struct regmap *map)
{
int i;
unsigned int *cache;

map->cache = kzalloc(sizeof(unsigned int) * (map->max_register + 1),
GFP_KERNEL);
if (!map->cache)
return -ENOMEM;

cache = map->cache;

for (i = 0; i < map->num_reg_defaults; i++)
cache[map->reg_defaults[i].reg] = map->reg_defaults[i].def;

return 0;
}

static int regcache_flat_exit(struct regmap *map)
{
kfree(map->cache);
map->cache = NULL;

return 0;
}

static int regcache_flat_read(struct regmap *map,
unsigned int reg, unsigned int *value)
{
unsigned int *cache = map->cache;

*value = cache[reg];

return 0;
}

static int regcache_flat_write(struct regmap *map, unsigned int reg,
unsigned int value)
{
unsigned int *cache = map->cache;

cache[reg] = value;

return 0;
}

struct regcache_ops regcache_flat_ops = {
.type = REGCACHE_FLAT,
.name = "flat",
.init = regcache_flat_init,
.exit = regcache_flat_exit,
.read = regcache_flat_read,
.write = regcache_flat_write,
};
1 change: 1 addition & 0 deletions drivers/base/regmap/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
static const struct regcache_ops *cache_types[] = {
&regcache_rbtree_ops,
&regcache_lzo_ops,
&regcache_flat_ops,
};

static int regcache_hw_init(struct regmap *map)
Expand Down
3 changes: 2 additions & 1 deletion include/linux/regmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ struct regmap_range_cfg;
enum regcache_type {
REGCACHE_NONE,
REGCACHE_RBTREE,
REGCACHE_COMPRESSED
REGCACHE_COMPRESSED,
REGCACHE_FLAT,
};

/**
Expand Down

0 comments on commit 2ac902c

Please sign in to comment.