aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2014-07-17 11:31:23 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-17 11:44:38 -0400
commit0d5e8c4313c83dc2d60519a219d517a13ba8a432 (patch)
tree5a9f6581e1cc493f7dc624e51e7b65598a419005 /drivers/media/v4l2-core
parent028e2b4fb69f03a294a69b27c99f05002b8ac021 (diff)
[media] Fix 64-bit division fall-out from 64-bit control ranges
Commit 0ba2aeb6dab80920edd9cf5b93b1ea4d6913b8f3 increased the internal control ranges to 64 bit, but that caused problems in drivers that use the minimum/maximum/step/default_value control values in a division or modulus operations since not all architectures support those natively. Luckily, in almost all cases it is possible to just cast to 32 bits (the control value is known to be 32 bits, so it is safe to cast). Only in v4l2-ctrls.c was it necessary to use do_div in one function. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 5c3b8de82e35..8552c832074a 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1303,7 +1303,7 @@ static void std_log(const struct v4l2_ctrl *ctrl)
1303 val = clamp_t(typeof(val), val, \ 1303 val = clamp_t(typeof(val), val, \
1304 (ctrl)->minimum, (ctrl)->maximum); \ 1304 (ctrl)->minimum, (ctrl)->maximum); \
1305 offset = (val) - (ctrl)->minimum; \ 1305 offset = (val) - (ctrl)->minimum; \
1306 offset = (ctrl)->step * (offset / (ctrl)->step); \ 1306 offset = (ctrl)->step * (offset / (s32)(ctrl)->step); \
1307 val = (ctrl)->minimum + offset; \ 1307 val = (ctrl)->minimum + offset; \
1308 0; \ 1308 0; \
1309}) 1309})
@@ -1313,12 +1313,24 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
1313 union v4l2_ctrl_ptr ptr) 1313 union v4l2_ctrl_ptr ptr)
1314{ 1314{
1315 size_t len; 1315 size_t len;
1316 u64 offset;
1317 s64 val;
1316 1318
1317 switch (ctrl->type) { 1319 switch (ctrl->type) {
1318 case V4L2_CTRL_TYPE_INTEGER: 1320 case V4L2_CTRL_TYPE_INTEGER:
1319 return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl); 1321 return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl);
1320 case V4L2_CTRL_TYPE_INTEGER64: 1322 case V4L2_CTRL_TYPE_INTEGER64:
1321 return ROUND_TO_RANGE(ptr.p_s64[idx], u64, ctrl); 1323 /*
1324 * We can't use the ROUND_TO_RANGE define here due to
1325 * the u64 divide that needs special care.
1326 */
1327 val = ptr.p_s64[idx];
1328 val += ctrl->step / 2;
1329 val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum);
1330 offset = val - ctrl->minimum;
1331 do_div(offset, ctrl->step);
1332 ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step;
1333 return 0;
1322 case V4L2_CTRL_TYPE_U8: 1334 case V4L2_CTRL_TYPE_U8:
1323 return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl); 1335 return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl);
1324 case V4L2_CTRL_TYPE_U16: 1336 case V4L2_CTRL_TYPE_U16:
@@ -1353,7 +1365,7 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
1353 len = strlen(ptr.p_char + idx); 1365 len = strlen(ptr.p_char + idx);
1354 if (len < ctrl->minimum) 1366 if (len < ctrl->minimum)
1355 return -ERANGE; 1367 return -ERANGE;
1356 if ((len - ctrl->minimum) % ctrl->step) 1368 if ((len - (u32)ctrl->minimum) % (u32)ctrl->step)
1357 return -ERANGE; 1369 return -ERANGE;
1358 return 0; 1370 return 0;
1359 1371