History

Merge tag 'regmap-fix-v6.7-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

Pull regmap fix from Mark Brown: "One fix here, for an interaction between noinc registers and caches. If a device uses noinc registers (which is rare) then we could corrupt registers after the noinc register in the cache" * tag 'regmap-fix-v6.7-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: prevent noinc writes from clobbering cache

Linus Torvalds committed 3 years ago

Commit eaec7c92 parents b8dd631 984a4af1 file · +9 −7Browse files

Unified · Split

drivers/base/regmap/regmap.c+9−7
@@ -1620,17 +1620,19 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, · 1619 unmodified lines
16201620 }
16211621
16221622 if (!map->cache_bypass && map->format.parse_val) {
1623− unsigned int ival;
1623+ unsigned int ival, offset;
16241624 int val_bytes = map->format.val_bytes;
1625− for (i = 0; i < val_len / val_bytes; i++) {
1626− ival = map->format.parse_val(val + (i * val_bytes));
1627− ret = regcache_write(map,
1628− reg + regmap_get_offset(map, i),
1629− ival);
1625+
1626+ /* Cache the last written value for noinc writes */
1627+ i = noinc ? val_len - val_bytes : 0;
1628+ for (; i < val_len; i += val_bytes) {
1629+ ival = map->format.parse_val(val + i);
1630+ offset = noinc ? 0 : regmap_get_offset(map, i / val_bytes);
1631+ ret = regcache_write(map, reg + offset, ival);
16301632 if (ret) {
16311633 dev_err(map->dev,
16321634 "Error in caching of register: %x ret: %d\n",
1633− reg + regmap_get_offset(map, i), ret);
1635+ reg + offset, ret);
16341636 return ret;
16351637 }
16361638 }