From 76aad392f75e6ce5be3f106554e16f7ff96543e5 Mon Sep 17 00:00:00 2001 From: Davide Ciminaghi Date: Tue, 20 Nov 2012 15:20:30 +0100 Subject: regmap: introduce tables for readable/writeable/volatile/precious checks Many of the regmap enabled drivers implementing one or more of the readable, writeable, volatile and precious methods use the same code pattern: return ((reg >= X && reg <= Y) || (reg >= W && reg <= Z) || ...) Switch to a data driven approach, using tables to describe readable/writeable/volatile and precious registers ranges instead. The table based check can still be overridden by passing the usual function pointers via struct regmap_config. Signed-off-by: Davide Ciminaghi Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 4 ++++ drivers/base/regmap/regmap.c | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 2cd01b57b1c4..288e135fd5f8 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -55,6 +55,10 @@ struct regmap { bool (*readable_reg)(struct device *dev, unsigned int reg); bool (*volatile_reg)(struct device *dev, unsigned int reg); bool (*precious_reg)(struct device *dev, unsigned int reg); + const struct regmap_access_table *wr_table; + const struct regmap_access_table *rd_table; + const struct regmap_access_table *volatile_table; + const struct regmap_access_table *precious_table; u8 read_flag_mask; u8 write_flag_mask; diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 64eb8350a074..96f7e8523ee8 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -34,6 +34,36 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change); +bool regmap_reg_in_ranges(unsigned int reg, + const struct regmap_range *ranges, + unsigned int nranges) +{ + const struct regmap_range *r; + int i; + + for (i = 0, r = ranges; i < nranges; i++, r++) + if (regmap_reg_in_range(reg, r)) + return true; + return false; +} +EXPORT_SYMBOL_GPL(regmap_reg_in_ranges); + +static bool _regmap_check_range_table(struct regmap *map, + unsigned int reg, + const struct regmap_access_table *table) +{ + /* Check "no ranges" first */ + if (regmap_reg_in_ranges(reg, table->no_ranges, table->n_no_ranges)) + return false; + + /* In case zero "yes ranges" are supplied, any reg is OK */ + if (!table->n_yes_ranges) + return true; + + return regmap_reg_in_ranges(reg, table->yes_ranges, + table->n_yes_ranges); +} + bool regmap_writeable(struct regmap *map, unsigned int reg) { if (map->max_register && reg > map->max_register) @@ -42,6 +72,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg) if (map->writeable_reg) return map->writeable_reg(map->dev, reg); + if (map->wr_table) + return _regmap_check_range_table(map, reg, map->wr_table); + return true; } @@ -56,6 +89,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg) if (map->readable_reg) return map->readable_reg(map->dev, reg); + if (map->rd_table) + return _regmap_check_range_table(map, reg, map->rd_table); + return true; } @@ -67,6 +103,9 @@ bool regmap_volatile(struct regmap *map, unsigned int reg) if (map->volatile_reg) return map->volatile_reg(map->dev, reg); + if (map->volatile_table) + return _regmap_check_range_table(map, reg, map->volatile_table); + return true; } @@ -78,6 +117,9 @@ bool regmap_precious(struct regmap *map, unsigned int reg) if (map->precious_reg) return map->precious_reg(map->dev, reg); + if (map->precious_table) + return _regmap_check_range_table(map, reg, map->precious_table); + return false; } @@ -370,6 +412,10 @@ struct regmap *regmap_init(struct device *dev, map->bus = bus; map->bus_context = bus_context; map->max_register = config->max_register; + map->wr_table = config->wr_table; + map->rd_table = config->rd_table; + map->volatile_table = config->volatile_table; + map->precious_table = config->precious_table; map->writeable_reg = config->writeable_reg; map->readable_reg = config->readable_reg; map->volatile_reg = config->volatile_reg; -- cgit v1.2.1