summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/internal.h3
-rw-r--r--drivers/base/regmap/regmap.c15
-rw-r--r--include/linux/regmap.h9
3 files changed, 24 insertions, 3 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 5ab3fefa4b05..7e14d5a6f53e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -46,6 +46,9 @@ 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);
+
+ u8 read_flag_mask;
+ u8 write_flag_mask;
};
bool regmap_writeable(struct regmap *map, unsigned int reg);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 86b184776199..e7adfe70e425 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -147,6 +147,13 @@ struct regmap *regmap_init(struct device *dev,
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+ if (config->read_flag_mask || config->write_flag_mask) {
+ map->read_flag_mask = config->read_flag_mask;
+ map->write_flag_mask = config->write_flag_mask;
+ } else {
+ map->read_flag_mask = bus->read_flag_mask;
+ }
+
switch (config->reg_bits) {
case 4:
switch (config->val_bits) {
@@ -226,6 +233,7 @@ EXPORT_SYMBOL_GPL(regmap_exit);
static int _regmap_raw_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_len)
{
+ u8 *u8 = map->work_buf;
void *buf;
int ret = -ENOTSUPP;
size_t len;
@@ -239,6 +247,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
map->format.format_reg(map->work_buf, reg);
+ u8[0] |= map->write_flag_mask;
+
trace_regmap_hw_write_start(map->dev, reg,
val_len / map->format.val_bytes);
@@ -366,13 +376,12 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
map->format.format_reg(map->work_buf, reg);
/*
- * Some buses flag reads by setting the high bits in the
+ * Some buses or devices flag reads by setting the high bits in the
* register addresss; since it's always the high bits for all
* current formats we can do this here rather than in
* formatting. This may break if we get interesting formats.
*/
- if (map->bus->read_flag_mask)
- u8[0] |= map->bus->read_flag_mask;
+ u8[0] |= map->read_flag_mask;
trace_regmap_hw_read_start(map->dev, reg,
val_len / map->format.val_bytes);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 9438a89e1573..18d4afaac166 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -53,6 +53,12 @@ struct reg_default {
* @reg_defaults: Power on reset values for registers (for use with
* register cache support).
* @num_reg_defaults: Number of elements in reg_defaults.
+ *
+ * @read_flag_mask: Mask to be set in the top byte of the register when doing
+ * a read.
+ * @write_flag_mask: Mask to be set in the top byte of the register when doing
+ * a write. If both read_flag_mask and write_flag_mask are
+ * empty the regmap_bus default masks are used.
*/
struct regmap_config {
int reg_bits;
@@ -66,6 +72,9 @@ struct regmap_config {
unsigned int max_register;
struct reg_default *reg_defaults;
int num_reg_defaults;
+
+ u8 read_flag_mask;
+ u8 write_flag_mask;
};
typedef int (*regmap_hw_write)(struct device *dev, const void *data,