Merge remote-tracking branch 'regmap/topic/drivers' into regmap-next

Resolved simple add/add conflicts:
	drivers/base/regmap/internal.h
	drivers/base/regmap/regmap.c
This commit is contained in:
Mark Brown
2012-03-14 13:13:25 +00:00
1249 changed files with 11279 additions and 53556 deletions

View File

@@ -76,6 +76,9 @@ struct regmap {
const void *reg_defaults_raw;
void *cache;
u32 cache_dirty;
struct reg_default *patch;
int patch_regs;
};
struct regcache_ops {

View File

@@ -53,7 +53,7 @@ static int regcache_hw_init(struct regmap *map)
for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
val = regcache_get_val(map->reg_defaults_raw,
i, map->cache_word_size);
if (!val)
if (regmap_volatile(map, i))
continue;
count++;
}
@@ -70,7 +70,7 @@ static int regcache_hw_init(struct regmap *map)
for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
val = regcache_get_val(map->reg_defaults_raw,
i, map->cache_word_size);
if (!val)
if (regmap_volatile(map, i))
continue;
map->reg_defaults[j].reg = i;
map->reg_defaults[j].def = val;
@@ -266,8 +266,22 @@ int regcache_sync(struct regmap *map)
map->cache_ops->name);
name = map->cache_ops->name;
trace_regcache_sync(map->dev, name, "start");
if (!map->cache_dirty)
goto out;
/* Apply any patch first */
map->cache_bypass = 1;
for (i = 0; i < map->patch_regs; i++) {
ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
if (ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
map->patch[i].reg, map->patch[i].def, ret);
goto out;
}
}
map->cache_bypass = 0;
if (map->cache_ops->sync) {
ret = map->cache_ops->sync(map);
} else {

View File

@@ -374,6 +374,9 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
regmap_debugfs_init(map);
map->cache_bypass = false;
map->cache_only = false;
ret = regcache_init(map, config);
mutex_unlock(&map->lock);
@@ -783,6 +786,64 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
}
EXPORT_SYMBOL_GPL(regmap_update_bits_check);
/**
* regmap_register_patch: Register and apply register updates to be applied
* on device initialistion
*
* @map: Register map to apply updates to.
* @regs: Values to update.
* @num_regs: Number of entries in regs.
*
* Register a set of register updates to be applied to the device
* whenever the device registers are synchronised with the cache and
* apply them immediately. Typically this is used to apply
* corrections to be applied to the device defaults on startup, such
* as the updates some vendors provide to undocumented registers.
*/
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
int num_regs)
{
int i, ret;
bool bypass;
/* If needed the implementation can be extended to support this */
if (map->patch)
return -EBUSY;
mutex_lock(&map->lock);
bypass = map->cache_bypass;
map->cache_bypass = true;
/* Write out first; it's useful to apply even if we fail later. */
for (i = 0; i < num_regs; i++) {
ret = _regmap_write(map, regs[i].reg, regs[i].def);
if (ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
regs[i].reg, regs[i].def, ret);
goto out;
}
}
map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL);
if (map->patch != NULL) {
memcpy(map->patch, regs,
num_regs * sizeof(struct reg_default));
map->patch_regs = num_regs;
} else {
ret = -ENOMEM;
}
out:
map->cache_bypass = bypass;
mutex_unlock(&map->lock);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_register_patch);
static int __init regmap_initcall(void)
{
regmap_debugfs_initcall();