aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap
diff options
context:
space:
mode:
authorDavide Ciminaghi <ciminaghi@gnudd.com>2012-11-20 09:20:30 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-20 21:10:31 -0500
commit76aad392f75e6ce5be3f106554e16f7ff96543e5 (patch)
tree00d1ef2dad497331dca8860e7ecc9474d0bab7b5 /drivers/base/regmap
parent3afa24f7ad0a1ab5478f1e9a6c4df1acf52171d1 (diff)
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 <ciminaghi@gnudd.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r--drivers/base/regmap/internal.h4
-rw-r--r--drivers/base/regmap/regmap.c46
2 files changed, 50 insertions, 0 deletions
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 {
55 bool (*readable_reg)(struct device *dev, unsigned int reg); 55 bool (*readable_reg)(struct device *dev, unsigned int reg);
56 bool (*volatile_reg)(struct device *dev, unsigned int reg); 56 bool (*volatile_reg)(struct device *dev, unsigned int reg);
57 bool (*precious_reg)(struct device *dev, unsigned int reg); 57 bool (*precious_reg)(struct device *dev, unsigned int reg);
58 const struct regmap_access_table *wr_table;
59 const struct regmap_access_table *rd_table;
60 const struct regmap_access_table *volatile_table;
61 const struct regmap_access_table *precious_table;
58 62
59 u8 read_flag_mask; 63 u8 read_flag_mask;
60 u8 write_flag_mask; 64 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,
34 unsigned int mask, unsigned int val, 34 unsigned int mask, unsigned int val,
35 bool *change); 35 bool *change);
36 36
37bool regmap_reg_in_ranges(unsigned int reg,
38 const struct regmap_range *ranges,
39 unsigned int nranges)
40{
41 const struct regmap_range *r;
42 int i;
43
44 for (i = 0, r = ranges; i < nranges; i++, r++)
45 if (regmap_reg_in_range(reg, r))
46 return true;
47 return false;
48}
49EXPORT_SYMBOL_GPL(regmap_reg_in_ranges);
50
51static bool _regmap_check_range_table(struct regmap *map,
52 unsigned int reg,
53 const struct regmap_access_table *table)
54{
55 /* Check "no ranges" first */
56 if (regmap_reg_in_ranges(reg, table->no_ranges, table->n_no_ranges))
57 return false;
58
59 /* In case zero "yes ranges" are supplied, any reg is OK */
60 if (!table->n_yes_ranges)
61 return true;
62
63 return regmap_reg_in_ranges(reg, table->yes_ranges,
64 table->n_yes_ranges);
65}
66
37bool regmap_writeable(struct regmap *map, unsigned int reg) 67bool regmap_writeable(struct regmap *map, unsigned int reg)
38{ 68{
39 if (map->max_register && reg > map->max_register) 69 if (map->max_register && reg > map->max_register)
@@ -42,6 +72,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
42 if (map->writeable_reg) 72 if (map->writeable_reg)
43 return map->writeable_reg(map->dev, reg); 73 return map->writeable_reg(map->dev, reg);
44 74
75 if (map->wr_table)
76 return _regmap_check_range_table(map, reg, map->wr_table);
77
45 return true; 78 return true;
46} 79}
47 80
@@ -56,6 +89,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
56 if (map->readable_reg) 89 if (map->readable_reg)
57 return map->readable_reg(map->dev, reg); 90 return map->readable_reg(map->dev, reg);
58 91
92 if (map->rd_table)
93 return _regmap_check_range_table(map, reg, map->rd_table);
94
59 return true; 95 return true;
60} 96}
61 97
@@ -67,6 +103,9 @@ bool regmap_volatile(struct regmap *map, unsigned int reg)
67 if (map->volatile_reg) 103 if (map->volatile_reg)
68 return map->volatile_reg(map->dev, reg); 104 return map->volatile_reg(map->dev, reg);
69 105
106 if (map->volatile_table)
107 return _regmap_check_range_table(map, reg, map->volatile_table);
108
70 return true; 109 return true;
71} 110}
72 111
@@ -78,6 +117,9 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
78 if (map->precious_reg) 117 if (map->precious_reg)
79 return map->precious_reg(map->dev, reg); 118 return map->precious_reg(map->dev, reg);
80 119
120 if (map->precious_table)
121 return _regmap_check_range_table(map, reg, map->precious_table);
122
81 return false; 123 return false;
82} 124}
83 125
@@ -370,6 +412,10 @@ struct regmap *regmap_init(struct device *dev,
370 map->bus = bus; 412 map->bus = bus;
371 map->bus_context = bus_context; 413 map->bus_context = bus_context;
372 map->max_register = config->max_register; 414 map->max_register = config->max_register;
415 map->wr_table = config->wr_table;
416 map->rd_table = config->rd_table;
417 map->volatile_table = config->volatile_table;
418 map->precious_table = config->precious_table;
373 map->writeable_reg = config->writeable_reg; 419 map->writeable_reg = config->writeable_reg;
374 map->readable_reg = config->readable_reg; 420 map->readable_reg = config->readable_reg;
375 map->volatile_reg = config->volatile_reg; 421 map->volatile_reg = config->volatile_reg;