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
Unified · Split
| @@ -1620,17 +1620,19 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, · 1619 unmodified lines | |||
| 1620 | } | 1620 | } |
| 1621 | 1621 | ||
| 1622 | if (!map->cache_bypass && map->format.parse_val) { | 1622 | if (!map->cache_bypass && map->format.parse_val) { |
| 1623 | unsigned int ival; | 1623 | unsigned int ival, offset; |
| 1624 | int val_bytes = map->format.val_bytes; | 1624 | int val_bytes = map->format.val_bytes; |
| 1625 | for (i = 0; i < val_len / val_bytes; i++) { | 1625 | |
| 1626 | ival = map->format.parse_val(val + (i * val_bytes)); | 1626 | /* Cache the last written value for noinc writes */ |
| 1627 | ret = regcache_write(map, | 1627 | i = noinc ? val_len - val_bytes : 0; |
| 1628 | reg + regmap_get_offset(map, i), | 1628 | for (; i < val_len; i += val_bytes) { |
| 1629 | ival); | 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 | if (ret) { | 1632 | if (ret) { |
| 1631 | dev_err(map->dev, | 1633 | dev_err(map->dev, |
| 1632 | "Error in caching of register: %x ret: %d\n", | 1634 | "Error in caching of register: %x ret: %d\n", |
| 1633 | reg + regmap_get_offset(map, i), ret); | 1635 | reg + offset, ret); |
| 1634 | return ret; | 1636 | return ret; |
| 1635 | } | 1637 | } |
| 1636 | } | 1638 | } |