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 /include/linux | |
| 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 'include/linux')
| -rw-r--r-- | include/linux/regmap.h | 83 |
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 | */ | ||
| 63 | struct 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 | */ | ||
| 79 | struct 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 | |||
| 56 | typedef void (*regmap_lock)(void *); | 86 | typedef void (*regmap_lock)(void *); |
| 57 | typedef void (*regmap_unlock)(void *); | 87 | typedef 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); | |||
| 280 | int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | 331 | int regmap_register_patch(struct regmap *map, const struct reg_default *regs, |
| 281 | int num_regs); | 332 | int num_regs); |
| 282 | 333 | ||
| 334 | static 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 | |||
| 340 | bool 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 | * |
