提交 e3684585 编写于 作者: H Haibo Chen 提交者: Zheng Zengkai

gpio: pca953x: use the correct range when do regmap sync

stable inclusion
from stable-v5.10.134
commit a941e6d5ba3bf989b48490abed9e68d135b44c9b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5ZVR7

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=a941e6d5ba3bf989b48490abed9e68d135b44c9b

--------------------------------

[ Upstream commit 2abc17a9 ]

regmap will sync a range of registers, here use the correct range
to make sure the sync do not touch other unexpected registers.

Find on pca9557pw on imx8qxp/dxl evk board, this device support
8 pin, so only need one register(8 bits) to cover all the 8 pins's
property setting. But when sync the output, we find it actually
update two registers, output register and the following register.

Fixes: b7657430 ("gpio: pca953x: Restore registers after suspend/resume cycle")
Fixes: ec82d1eb ("gpio: pca953x: Zap ad-hoc reg_output cache")
Fixes: 0f25fda8 ("gpio: pca953x: Zap ad-hoc reg_direction cache")
Signed-off-by: NHaibo Chen <haibo.chen@nxp.com>
Reviewed-by: NAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: NBartosz Golaszewski <brgl@bgdev.pl>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: NWei Li <liwei391@huawei.com>
上级 af332cdb
...@@ -899,12 +899,12 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) ...@@ -899,12 +899,12 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
int ret; int ret;
ret = regcache_sync_region(chip->regmap, chip->regs->output, ret = regcache_sync_region(chip->regmap, chip->regs->output,
chip->regs->output + NBANK(chip)); chip->regs->output + NBANK(chip) - 1);
if (ret) if (ret)
goto out; goto out;
ret = regcache_sync_region(chip->regmap, chip->regs->direction, ret = regcache_sync_region(chip->regmap, chip->regs->direction,
chip->regs->direction + NBANK(chip)); chip->regs->direction + NBANK(chip) - 1);
if (ret) if (ret)
goto out; goto out;
...@@ -1117,14 +1117,14 @@ static int pca953x_regcache_sync(struct device *dev) ...@@ -1117,14 +1117,14 @@ static int pca953x_regcache_sync(struct device *dev)
* sync these registers first and only then sync the rest. * sync these registers first and only then sync the rest.
*/ */
regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0); regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0);
ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip)); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1);
if (ret) { if (ret) {
dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret); dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret);
return ret; return ret;
} }
regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0); regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0);
ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip)); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1);
if (ret) { if (ret) {
dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret); dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret);
return ret; return ret;
...@@ -1134,7 +1134,7 @@ static int pca953x_regcache_sync(struct device *dev) ...@@ -1134,7 +1134,7 @@ static int pca953x_regcache_sync(struct device *dev)
if (chip->driver_data & PCA_PCAL) { if (chip->driver_data & PCA_PCAL) {
regaddr = pca953x_recalc_addr(chip, PCAL953X_IN_LATCH, 0); regaddr = pca953x_recalc_addr(chip, PCAL953X_IN_LATCH, 0);
ret = regcache_sync_region(chip->regmap, regaddr, ret = regcache_sync_region(chip->regmap, regaddr,
regaddr + NBANK(chip)); regaddr + NBANK(chip) - 1);
if (ret) { if (ret) {
dev_err(dev, "Failed to sync INT latch registers: %d\n", dev_err(dev, "Failed to sync INT latch registers: %d\n",
ret); ret);
...@@ -1143,7 +1143,7 @@ static int pca953x_regcache_sync(struct device *dev) ...@@ -1143,7 +1143,7 @@ static int pca953x_regcache_sync(struct device *dev)
regaddr = pca953x_recalc_addr(chip, PCAL953X_INT_MASK, 0); regaddr = pca953x_recalc_addr(chip, PCAL953X_INT_MASK, 0);
ret = regcache_sync_region(chip->regmap, regaddr, ret = regcache_sync_region(chip->regmap, regaddr,
regaddr + NBANK(chip)); regaddr + NBANK(chip) - 1);
if (ret) { if (ret) {
dev_err(dev, "Failed to sync INT mask registers: %d\n", dev_err(dev, "Failed to sync INT mask registers: %d\n",
ret); ret);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册