[PATCH v10 11/15] media: ov2740: release group hold after gain write errors

From: Maurizio Casciano via B4 Relay

Date: Fri Oct 02 2026 - 05:02:07 EST


From: Maurizio Casciano <mauriziocasciano7@xxxxxxxxx>

Digital-gain updates start a register group before writing the red, green
and blue gains. The current error paths return immediately when one of
those writes fails, leaving the group open and never issuing its end and
launch commands. Later control updates can then be accumulated in an
unfinished group instead of taking effect.

Once group hold has started, always attempt both commands needed to end
and launch the group. Preserve the first gain-write error; report an end
or launch error only when all gain writes succeeded.

Fixes: 84363509c725 ("media: ov2740: use group write for digital gain")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Maurizio Casciano <mauriziocasciano7@xxxxxxxxx>
Assisted-by: LLM sparse
---
drivers/media/i2c/ov2740.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index ca33ef30267d..4479666f17f7 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -696,7 +696,7 @@ static int ov2740_identify_module(struct ov2740 *ov2740)

static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain)
{
- int ret;
+ int end_ret, launch_ret, ret;

ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
OV2740_GROUP_HOLD_START);
@@ -705,24 +705,21 @@ static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain)

ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_R_GAIN, 2, d_gain);
if (ret)
- return ret;
+ goto release_group;

ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_G_GAIN, 2, d_gain);
if (ret)
- return ret;
+ goto release_group;

ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_B_GAIN, 2, d_gain);
- if (ret)
- return ret;

- ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
- OV2740_GROUP_HOLD_END);
- if (ret)
- return ret;
+release_group:
+ end_ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
+ OV2740_GROUP_HOLD_END);
+ launch_ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
+ OV2740_GROUP_HOLD_LAUNCH);

- ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
- OV2740_GROUP_HOLD_LAUNCH);
- return ret;
+ return ret ?: end_ret ?: launch_ret;
}

static int ov2740_test_pattern(struct ov2740 *ov2740, u32 pattern)

--
2.53.0