summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrashant Laddha <prladdha@cisco.com>2015-05-05 10:16:27 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-05-18 16:27:29 -0300
commitc9bc9f50753d20d24836831d40e1efe74c21b0ef (patch)
tree3c2222d564c150a359f951a5f21ebc7e477a4f6e
parented1bc664daf58af7da47581fe43d42b95a1de65a (diff)
downloadop-kernel-dev-c9bc9f50753d20d24836831d40e1efe74c21b0ef.zip
op-kernel-dev-c9bc9f50753d20d24836831d40e1efe74c21b0ef.tar.gz
[media] v4l2-dv-timings: fix overflow in gtf timings calculation
The intermediate calculation in the expression for hblank can exceed 32 bit signed range. This overflow can lead to negative values for hblank. Typecasting intermediate variable to higher precision. Cc: Martin Bugge <marbugge@cisco.com> Signed-off-by: Prashant Laddha <prladdha@cisco.com> [hans.verkuil@cisco.com: made the denominator u32, since that's what div_u64 expects] Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 37f0d6f..5792192 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -25,6 +25,7 @@
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-dv-timings.h>
+#include <linux/math64.h>
MODULE_AUTHOR("Hans Verkuil");
MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
@@ -554,16 +555,23 @@ bool v4l2_detect_gtf(unsigned frame_height,
image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1);
/* Horizontal */
- if (default_gtf)
- h_blank = ((image_width * GTF_D_C_PRIME * hfreq) -
- (image_width * GTF_D_M_PRIME * 1000) +
- (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) /
- (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000);
- else
- h_blank = ((image_width * GTF_S_C_PRIME * hfreq) -
- (image_width * GTF_S_M_PRIME * 1000) +
- (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) /
- (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000);
+ if (default_gtf) {
+ u64 num;
+ u32 den;
+
+ num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) -
+ ((u64)image_width * GTF_D_M_PRIME * 1000));
+ den = hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000;
+ h_blank = div_u64((num + (den >> 1)), den);
+ } else {
+ u64 num;
+ u32 den;
+
+ num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) -
+ ((u64)image_width * GTF_S_M_PRIME * 1000));
+ den = hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000;
+ h_blank = div_u64((num + (den >> 1)), den);
+ }
h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) *
(2 * GTF_CELL_GRAN);
OpenPOWER on IntegriCloud