diff options
author | Davide Ciminaghi <ciminaghi@gnudd.com> | 2012-11-20 09:20:30 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-11-20 21:10:31 -0500 |
commit | 76aad392f75e6ce5be3f106554e16f7ff96543e5 (patch) | |
tree | 00d1ef2dad497331dca8860e7ecc9474d0bab7b5 /drivers/base/regmap | |
parent | 3afa24f7ad0a1ab5478f1e9a6c4df1acf52171d1 (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.h | 4 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 46 |
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 | ||
37 | bool 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 | } | ||
49 | EXPORT_SYMBOL_GPL(regmap_reg_in_ranges); | ||
50 | |||
51 | static 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 | |||
37 | bool regmap_writeable(struct regmap *map, unsigned int reg) | 67 | bool 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; |