Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+9 -7
+9 -7
drivers/base/regmap/regmap.c
··· 1620 1620 } 1621 1621 1622 1622 if (!map->cache_bypass && map->format.parse_val) { 1623 - unsigned int ival; 1623 + unsigned int ival, offset; 1624 1624 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); 1630 1632 if (ret) { 1631 1633 dev_err(map->dev, 1632 1634 "Error in caching of register: %x ret: %d\n", 1633 - reg + regmap_get_offset(map, i), ret); 1635 + reg + offset, ret); 1634 1636 return ret; 1635 1637 } 1636 1638 }