summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorYousef Alhouseen <alhouseenyousef@gmail.com>2026-06-30 12:50:15 +0200
committerHans Verkuil <hverkuil+cisco@kernel.org>2026-07-27 14:22:07 +0200
commit59dc14a6cb5ff1ae5ce2f6ebf51fe0139e1c0623 (patch)
tree3a5a2a3e7fbe578e00a5a3a58fe7237ae555bb4a /drivers/media
parente260d1d7713b92f7156f5de7716c68438f49ae37 (diff)
downloadlinux-next-59dc14a6cb5ff1ae5ce2f6ebf51fe0139e1c0623.tar.gz
linux-next-59dc14a6cb5ff1ae5ce2f6ebf51fe0139e1c0623.zip
media: go7007: s2250: propagate control I/O failures
The brightness and contrast paths use oldvalue after read_reg_fp() without checking whether the read succeeded. A failed read leaves oldvalue uninitialized and can write arbitrary reserved register bits. Return read and write errors from every control path so failed hardware access cannot be reported as a successful control update. Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/usb/go7007/s2250-board.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c
index 0901d79e827d..d11f8e723624 100644
--- a/drivers/media/usb/go7007/s2250-board.c
+++ b/drivers/media/usb/go7007/s2250-board.c
@@ -365,36 +365,48 @@ static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
u16 oldvalue;
+ int ret;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
- ctrl->val | (oldvalue & ~0xff));
- read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
- ctrl->val | (oldvalue & ~0xff));
- write_reg_fp(client, 0x140, 0x60);
- break;
+ ret = read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
+ ctrl->val | (oldvalue & ~0xff));
+ if (ret)
+ return ret;
+ ret = read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
+ ctrl->val | (oldvalue & ~0xff));
+ if (ret)
+ return ret;
+ return write_reg_fp(client, 0x140, 0x60);
case V4L2_CID_CONTRAST:
- read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_CONTRAST0,
- ctrl->val | (oldvalue & ~0x3f));
- read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_CONTRAST1,
- ctrl->val | (oldvalue & ~0x3f));
- write_reg_fp(client, 0x140, 0x60);
- break;
+ ret = read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_CONTRAST0,
+ ctrl->val | (oldvalue & ~0x3f));
+ if (ret)
+ return ret;
+ ret = read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_CONTRAST1,
+ ctrl->val | (oldvalue & ~0x3f));
+ if (ret)
+ return ret;
+ return write_reg_fp(client, 0x140, 0x60);
case V4L2_CID_SATURATION:
- write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
- break;
+ return write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
case V4L2_CID_HUE:
- write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
- break;
+ return write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
default:
return -EINVAL;
}
- return 0;
}
static int s2250_set_fmt(struct v4l2_subdev *sd,