aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/regmap/regmap.c')
-rw-r--r--drivers/base/regmap/regmap.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e0d0c7d8a5c5..7d689a15c500 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -303,6 +303,7 @@ static void regmap_unlock_mutex(void *__map)
303} 303}
304 304
305static void regmap_lock_spinlock(void *__map) 305static void regmap_lock_spinlock(void *__map)
306__acquires(&map->spinlock)
306{ 307{
307 struct regmap *map = __map; 308 struct regmap *map = __map;
308 unsigned long flags; 309 unsigned long flags;
@@ -312,6 +313,7 @@ static void regmap_lock_spinlock(void *__map)
312} 313}
313 314
314static void regmap_unlock_spinlock(void *__map) 315static void regmap_unlock_spinlock(void *__map)
316__releases(&map->spinlock)
315{ 317{
316 struct regmap *map = __map; 318 struct regmap *map = __map;
317 spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags); 319 spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags);
@@ -687,6 +689,10 @@ skip_format_initialization:
687 unsigned win_max = win_min + 689 unsigned win_max = win_min +
688 config->ranges[j].window_len - 1; 690 config->ranges[j].window_len - 1;
689 691
692 /* Allow data window inside its own virtual range */
693 if (j == i)
694 continue;
695
690 if (range_cfg->range_min <= sel_reg && 696 if (range_cfg->range_min <= sel_reg &&
691 sel_reg <= range_cfg->range_max) { 697 sel_reg <= range_cfg->range_max) {
692 dev_err(map->dev, 698 dev_err(map->dev,
@@ -1261,6 +1267,9 @@ int _regmap_write(struct regmap *map, unsigned int reg,
1261 int ret; 1267 int ret;
1262 void *context = _regmap_map_get_context(map); 1268 void *context = _regmap_map_get_context(map);
1263 1269
1270 if (!regmap_writeable(map, reg))
1271 return -EIO;
1272
1264 if (!map->cache_bypass && !map->defer_caching) { 1273 if (!map->cache_bypass && !map->defer_caching) {
1265 ret = regcache_write(map, reg, val); 1274 ret = regcache_write(map, reg, val);
1266 if (ret != 0) 1275 if (ret != 0)
@@ -1888,13 +1897,10 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
1888int regmap_register_patch(struct regmap *map, const struct reg_default *regs, 1897int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
1889 int num_regs) 1898 int num_regs)
1890{ 1899{
1900 struct reg_default *p;
1891 int i, ret; 1901 int i, ret;
1892 bool bypass; 1902 bool bypass;
1893 1903
1894 /* If needed the implementation can be extended to support this */
1895 if (map->patch)
1896 return -EBUSY;
1897
1898 map->lock(map->lock_arg); 1904 map->lock(map->lock_arg);
1899 1905
1900 bypass = map->cache_bypass; 1906 bypass = map->cache_bypass;
@@ -1911,11 +1917,13 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
1911 } 1917 }
1912 } 1918 }
1913 1919
1914 map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL); 1920 p = krealloc(map->patch,
1915 if (map->patch != NULL) { 1921 sizeof(struct reg_default) * (map->patch_regs + num_regs),
1916 memcpy(map->patch, regs, 1922 GFP_KERNEL);
1917 num_regs * sizeof(struct reg_default)); 1923 if (p) {
1918 map->patch_regs = num_regs; 1924 memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
1925 map->patch = p;
1926 map->patch_regs += num_regs;
1919 } else { 1927 } else {
1920 ret = -ENOMEM; 1928 ret = -ENOMEM;
1921 } 1929 }