aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
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 /include/linux
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 'include/linux')
-rw-r--r--include/linux/regmap.h83
1 files changed, 72 insertions, 11 deletions
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 0e819e3cebce..3bdb1f9a5b43 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -53,6 +53,36 @@ enum regmap_endian {
53 REGMAP_ENDIAN_NATIVE, 53 REGMAP_ENDIAN_NATIVE,
54}; 54};
55 55
56/**
57 * A register range, used for access related checks
58 * (readable/writeable/volatile/precious checks)
59 *
60 * @range_min: address of first register
61 * @range_max: address of last register
62 */
63struct regmap_range {
64 unsigned int range_min;
65 unsigned int range_max;
66};
67
68/*
69 * A table of ranges including some yes ranges and some no ranges.
70 * If a register belongs to a no_range, the corresponding check function
71 * will return false. If a register belongs to a yes range, the corresponding
72 * check function will return true. "no_ranges" are searched first.
73 *
74 * @yes_ranges : pointer to an array of regmap ranges used as "yes ranges"
75 * @n_yes_ranges: size of the above array
76 * @no_ranges: pointer to an array of regmap ranges used as "no ranges"
77 * @n_no_ranges: size of the above array
78 */
79struct regmap_access_table {
80 const struct regmap_range *yes_ranges;
81 unsigned int n_yes_ranges;
82 const struct regmap_range *no_ranges;
83 unsigned int n_no_ranges;
84};
85
56typedef void (*regmap_lock)(void *); 86typedef void (*regmap_lock)(void *);
57typedef void (*regmap_unlock)(void *); 87typedef void (*regmap_unlock)(void *);
58 88
@@ -70,22 +100,39 @@ typedef void (*regmap_unlock)(void *);
70 * @val_bits: Number of bits in a register value, mandatory. 100 * @val_bits: Number of bits in a register value, mandatory.
71 * 101 *
72 * @writeable_reg: Optional callback returning true if the register 102 * @writeable_reg: Optional callback returning true if the register
73 * can be written to. 103 * can be written to. If this field is NULL but wr_table
104 * (see below) is not, the check is performed on such table
105 * (a register is writeable if it belongs to one of the ranges
106 * specified by wr_table).
74 * @readable_reg: Optional callback returning true if the register 107 * @readable_reg: Optional callback returning true if the register
75 * can be read from. 108 * can be read from. If this field is NULL but rd_table
109 * (see below) is not, the check is performed on such table
110 * (a register is readable if it belongs to one of the ranges
111 * specified by rd_table).
76 * @volatile_reg: Optional callback returning true if the register 112 * @volatile_reg: Optional callback returning true if the register
77 * value can't be cached. 113 * value can't be cached. If this field is NULL but
114 * volatile_table (see below) is not, the check is performed on
115 * such table (a register is volatile if it belongs to one of
116 * the ranges specified by volatile_table).
78 * @precious_reg: Optional callback returning true if the rgister 117 * @precious_reg: Optional callback returning true if the rgister
79 * should not be read outside of a call from the driver 118 * should not be read outside of a call from the driver
80 * (eg, a clear on read interrupt status register). 119 * (eg, a clear on read interrupt status register). If this
81 * @lock: Optional lock callback (overrides regmap's default lock 120 * field is NULL but precious_table (see below) is not, the
82 * function, based on spinlock or mutex). 121 * check is performed on such table (a register is precious if
83 * @unlock: As above for unlocking. 122 * it belongs to one of the ranges specified by precious_table).
84 * @lock_arg: this field is passed as the only argument of lock/unlock 123 * @lock: Optional lock callback (overrides regmap's default lock
85 * functions (ignored in case regular lock/unlock functions 124 * function, based on spinlock or mutex).
86 * are not overridden). 125 * @unlock: As above for unlocking.
126 * @lock_arg: this field is passed as the only argument of lock/unlock
127 * functions (ignored in case regular lock/unlock functions
128 * are not overridden).
87 * 129 *
88 * @max_register: Optional, specifies the maximum valid register index. 130 * @max_register: Optional, specifies the maximum valid register index.
131 * @wr_table: Optional, points to a struct regmap_access_table specifying
132 * valid ranges for write access.
133 * @rd_table: As above, for read access.
134 * @volatile_table: As above, for volatile registers.
135 * @precious_table: As above, for precious registers.
89 * @reg_defaults: Power on reset values for registers (for use with 136 * @reg_defaults: Power on reset values for registers (for use with
90 * register cache support). 137 * register cache support).
91 * @num_reg_defaults: Number of elements in reg_defaults. 138 * @num_reg_defaults: Number of elements in reg_defaults.
@@ -130,6 +177,10 @@ struct regmap_config {
130 void *lock_arg; 177 void *lock_arg;
131 178
132 unsigned int max_register; 179 unsigned int max_register;
180 const struct regmap_access_table *wr_table;
181 const struct regmap_access_table *rd_table;
182 const struct regmap_access_table *volatile_table;
183 const struct regmap_access_table *precious_table;
133 const struct reg_default *reg_defaults; 184 const struct reg_default *reg_defaults;
134 unsigned int num_reg_defaults; 185 unsigned int num_reg_defaults;
135 enum regcache_type cache_type; 186 enum regcache_type cache_type;
@@ -280,6 +331,16 @@ void regcache_mark_dirty(struct regmap *map);
280int regmap_register_patch(struct regmap *map, const struct reg_default *regs, 331int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
281 int num_regs); 332 int num_regs);
282 333
334static inline bool regmap_reg_in_range(unsigned int reg,
335 const struct regmap_range *range)
336{
337 return reg >= range->range_min && reg <= range->range_max;
338}
339
340bool regmap_reg_in_ranges(unsigned int reg,
341 const struct regmap_range *ranges,
342 unsigned int nranges);
343
283/** 344/**
284 * Description of an IRQ for the generic regmap irq_chip. 345 * Description of an IRQ for the generic regmap irq_chip.
285 * 346 *