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);
+ int (*reg_volatile_set)(struct device *dev, unsigned int reg,
+ bool is_volatile);
const struct regmap_access_table *wr_table;
const struct regmap_access_table *rd_table;
const struct regmap_access_table *volatile_table;
int regcache_lookup_reg(struct regmap *map, unsigned int reg);
int regcache_set_reg_present(struct regmap *map, unsigned int reg);
+static inline void regcache_clear_reg_present(struct regmap *map,
+ unsigned int reg)
+{
+ if ((map->cache_present) && (reg < map->cache_present_nbits))
+ clear_bit(reg, map->cache_present);
+}
+
static inline bool regcache_reg_present(struct regmap *map, unsigned int reg)
{
if (!map->cache_present)
}
EXPORT_SYMBOL_GPL(regcache_cache_bypass);
+static int _regcache_volatile_set(struct regmap *map, unsigned int reg,
+ bool is_volatile)
+{
+ int ret;
+
+ if (is_volatile == regmap_volatile(map, reg))
+ return 0;
+
+ if (!map->reg_volatile_set)
+ return -ENOSYS;
+
+ if (!map->cache_present)
+ return -ENOENT;
+
+ ret = map->reg_volatile_set(map->dev, reg, is_volatile);
+ if (ret)
+ return ret;
+
+ regcache_clear_reg_present(map, reg);
+ return 0;
+}
+
+/**
+ * regcache_volatile_set: Set single register as volatile or cached
+ *
+ * @map: map to apply change to
+ * @reg: register to be set as volatile or cached
+ * @is_volatile: if true, register is set as volatile, otherwise as cached
+ *
+ * Set access attribute to the specified register as volatile or cached. Clear
+ * cache_present bit (i.e., invalidate cache) on successful exit.
+ *
+ * Return a negative value on failure, 0 on success.
+ */
+int regcache_volatile_set(struct regmap *map, unsigned int reg,
+ bool is_volatile)
+{
+ int ret;
+
+ map->lock(map->lock_arg);
+ ret = _regcache_volatile_set(map, reg, is_volatile);
+ map->unlock(map->lock_arg);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regcache_volatile_set);
+
int regcache_set_reg_present(struct regmap *map, unsigned int reg)
{
unsigned long *cache_present;
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+ map->reg_volatile_set = config->reg_volatile_set;
map->cache_type = config->cache_type;
map->name = config->name;
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+ map->reg_volatile_set = config->reg_volatile_set;
map->cache_type = config->cache_type;
regmap_debugfs_init(map, config->name);
* field is NULL but precious_table (see below) is not, the
* check is performed on such table (a register is precious if
* it belongs to one of the ranges specified by precious_table).
+ * @reg_volatile_set: Optional callback to change access mode for the register
+ * between volatile and cached.
* @lock: Optional lock callback (overrides regmap's default lock
* function, based on spinlock or mutex).
* @unlock: As above for unlocking.
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);
+ int (*reg_volatile_set)(struct device *dev, unsigned int reg,
+ bool is_volatile);
regmap_lock lock;
regmap_unlock unlock;
void *lock_arg;
void regcache_cache_only(struct regmap *map, bool enable);
void regcache_cache_bypass(struct regmap *map, bool enable);
void regcache_mark_dirty(struct regmap *map);
+int regcache_volatile_set(struct regmap *map, unsigned int reg,
+ bool is_volatile);
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
int num_regs);
WARN_ONCE(1, "regmap API is disabled");
}
+static int regcache_volatile_set(struct regmap *map, unsigned int reg,
+ bool is_volatile)
+{
+ WARN_ONCE(1, "regmap API is disabled");
+ return -EINVAL;
+}
+
static inline void regmap_async_complete(struct regmap *map)
{
WARN_ONCE(1, "regmap API is disabled");