kenel nvidia-oot: Fix Static Analysis issues

Jira CAMERASW-29896

Change-Id: Ibe6a81a0ef0e7226acd78a8b42e8ccc05545bed3
Signed-off-by: Shiqi Jiao <shiqij@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3261568
Reviewed-by: Ryan Li <ryanli@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Ankit Gupta (SW-TEGRA) <ankitgu@nvidia.com>
Reviewed-by: Ankur Pawar <ankurp@nvidia.com>
This commit is contained in:
Shiqi Jiao
2024-12-05 08:54:43 +00:00
committed by Jon Hunter
parent 9cdba26d40
commit 821e55ab50
3 changed files with 137 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0-only
/* /*
* SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. * SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -524,6 +524,10 @@ static const struct camera_common_colorfmt *find_matching_color_fmt(
if (cur_props->pixel_format == if (cur_props->pixel_format ==
camera_common_color_fmts[i].pix_fmt && camera_common_color_fmts[i].pix_fmt &&
!matched[i]) { !matched[i]) {
if (match_num == INT_MAX) {
dev_err(s_data->dev, "Number of matched color format exceeds the limit\n");
return NULL;
}
match_num++; match_num++;
match_index = i; match_index = i;
// Found index // Found index
@@ -624,9 +628,14 @@ int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
hdr_control.id = TEGRA_CAMERA_CID_HDR_EN; hdr_control.id = TEGRA_CAMERA_CID_HDR_EN;
/* mode_type can be filled in sensor driver */ /* mode_type can be filled in sensor driver */
if (!(v4l2_g_ctrl(s_data->ctrl_handler, &hdr_control))) if (!(v4l2_g_ctrl(s_data->ctrl_handler, &hdr_control))) {
mode_type |= if ((hdr_control.value < 0) || (hdr_control.value >= ARRAY_SIZE(switch_ctrl_qmenu))) {
switch_ctrl_qmenu[hdr_control.value] ? HDR_ENABLE : 0; dev_err(sd->dev, "Number of tried camera common format exceeds the limit\n");
return -EINVAL;
}
mode_type |= switch_ctrl_qmenu[hdr_control.value] ? HDR_ENABLE : 0;
}
s_data->mode = s_data->def_mode; s_data->mode = s_data->def_mode;
s_data->mode_prop_idx = 0; s_data->mode_prop_idx = 0;
@@ -898,7 +907,15 @@ void camera_common_dpd_disable(struct camera_common_data *s_data)
int i; int i;
int io_idx; int io_idx;
/* 2 lanes per port, divide by two to get numports */ /* 2 lanes per port, divide by two to get numports */
int numports = (s_data->numlanes + 1) >> 1; int result_add1 = 0;
int numports = 0;
if (__builtin_add_overflow(1, s_data->numlanes, &result_add1)) {
dev_err(s_data->dev, "Number of data lanes exceeds the limit\n");
spec_bar();
return;
}
numports = result_add1 >> 1;
/* disable CSI IOs DPD mode to turn on camera */ /* disable CSI IOs DPD mode to turn on camera */
for (i = 0; i < numports; i++) { for (i = 0; i < numports; i++) {
@@ -934,7 +951,15 @@ void camera_common_dpd_enable(struct camera_common_data *s_data)
int i; int i;
int io_idx; int io_idx;
/* 2 lanes per port, divide by two to get numports */ /* 2 lanes per port, divide by two to get numports */
int numports = (s_data->numlanes + 1) >> 1; int result_add1 = 0;
int numports = 0;
if (__builtin_add_overflow(1, s_data->numlanes, &result_add1)) {
dev_err(s_data->dev, "Number of data lanes exceeds the limit\n");
spec_bar();
return;
}
numports = result_add1 >> 1;
/* disable CSI IOs DPD mode to turn on camera */ /* disable CSI IOs DPD mode to turn on camera */
for (i = 0; i < numports; i++) { for (i = 0; i < numports; i++) {

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* /*
* NVIDIA Tegra CSI Device * NVIDIA Tegra CSI Device
*/ */
@@ -15,6 +15,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/nospec.h> #include <linux/nospec.h>
#include <linux/string.h>
#include <media/media-entity.h> #include <media/media-entity.h>
#include <media/v4l2-async.h> #include <media/v4l2-async.h>
@@ -276,10 +277,17 @@ static int update_video_source(struct tegra_csi_device *csi, int on, int is_tpg)
{ {
mutex_lock(&csi->source_update); mutex_lock(&csi->source_update);
if (!on) { if (!on) {
if (is_tpg) if (is_tpg) {
csi->tpg_active--; if (csi->tpg_active > INT_MIN)
else csi->tpg_active--;
csi->sensor_active--; else
goto stream_fail;
} else {
if (csi->sensor_active > INT_MIN)
csi->sensor_active--;
else
goto stream_fail;
}
WARN_ON(csi->tpg_active < 0 || csi->sensor_active < 0); WARN_ON(csi->tpg_active < 0 || csi->sensor_active < 0);
goto stream_okay; goto stream_okay;
} }
@@ -291,6 +299,7 @@ static int update_video_source(struct tegra_csi_device *csi, int on, int is_tpg)
csi->sensor_active++; csi->sensor_active++;
goto stream_okay; goto stream_okay;
} }
stream_fail:
mutex_unlock(&csi->source_update); mutex_unlock(&csi->source_update);
dev_err(csi->dev, "Request rejected for new %s stream\n", dev_err(csi->dev, "Request rejected for new %s stream\n",
is_tpg ? "tpg" : "sensor"); is_tpg ? "tpg" : "sensor");
@@ -420,10 +429,45 @@ unsigned int tegra_csi_ths_settling_time(
const unsigned int csicil_clk_mhz, const unsigned int csicil_clk_mhz,
const unsigned int mipi_clk_mhz) const unsigned int mipi_clk_mhz)
{ {
unsigned int cil_settletime; unsigned int cil_settletime = 0;
/* The calculation formula is as follows:
* (115 * csicil_clk_mhz + 8000 * csicil_clk_mhz / (2 * mipi_clk_mhz) - 5500) / 1000
*/
unsigned int result_mul1 = 0;
unsigned int result_mul2 = 0;
unsigned int result_mul3 = 0;
unsigned int result_add1 = 0;
unsigned int result_sub1 = 0;
if (__builtin_umul_overflow(115, csicil_clk_mhz, &result_mul1)) {
dev_err(csi->dev, "Number of calculated tegra csi ths settling time exceeds the limit\n");
return cil_settletime;
}
if (__builtin_umul_overflow(8000, csicil_clk_mhz, &result_mul2)) {
dev_err(csi->dev, "Number of calculated tegra csi ths settling time exceeds the limit\n");
return cil_settletime;
}
if (__builtin_umul_overflow(2, mipi_clk_mhz, &result_mul3) || (result_mul3 == 0)) {
dev_err(csi->dev, "Number of calculated tegra csi ths settling time exceeds the limit " \
"or bad param of mipi clk mhz value is 0\n");
return cil_settletime;
}
if (__builtin_uadd_overflow(result_mul1, (result_mul2 / result_mul3), &result_add1)) {
dev_err(csi->dev, "Number of calculated tegra csi ths settling time exceeds the limit\n");
return cil_settletime;
}
if (__builtin_usub_overflow(result_add1, 5500, &result_sub1)) {
dev_err(csi->dev, "Number of calculated tegra csi ths settling time exceeds the limit\n");
return cil_settletime;
}
cil_settletime = result_sub1 / 1000;
cil_settletime = (115 * csicil_clk_mhz + 8000 * csicil_clk_mhz
/ (2 * mipi_clk_mhz) - 5500) / 1000;
return cil_settletime; return cil_settletime;
} }
EXPORT_SYMBOL(tegra_csi_ths_settling_time); EXPORT_SYMBOL(tegra_csi_ths_settling_time);
@@ -432,9 +476,24 @@ unsigned int tegra_csi_clk_settling_time(
struct tegra_csi_device *csi, struct tegra_csi_device *csi,
const unsigned int csicil_clk_mhz) const unsigned int csicil_clk_mhz)
{ {
unsigned int clk_settletime; unsigned int clk_settletime = 0;
clk_settletime = ((95 + 300) * csicil_clk_mhz - 13000) / 2000; /* The calculation formula is as follows:
* ((95 + 300) * csicil_clk_mhz - 13000) / 2000;
*/
unsigned int result_mul1 = 0;
unsigned int result_sub1 = 0;
if (__builtin_umul_overflow((95 + 300), csicil_clk_mhz, &result_mul1)) {
dev_err(csi->dev, "Number of calculated tegra csi clk settling time exceeds the limit\n");
return clk_settletime;
}
if (__builtin_usub_overflow(result_mul1, 13000, &result_sub1)) {
dev_err(csi->dev, "Number of calculated tegra csi clk settling time exceeds the limit\n");
return clk_settletime;
}
clk_settletime = result_sub1 / 2000;
return clk_settletime; return clk_settletime;
} }
EXPORT_SYMBOL(tegra_csi_clk_settling_time); EXPORT_SYMBOL(tegra_csi_clk_settling_time);
@@ -903,8 +962,16 @@ static int tegra_csi_channel_init_one(struct tegra_csi_channel *chan)
* pp means pixel parser, correspond to port[0] below. * pp means pixel parser, correspond to port[0] below.
* tpg id correspond to chan->id * tpg id correspond to chan->id
*/ */
chan->port[0] = (chan->id - csi->num_channels)
% NUM_TPG_INSTANCE; int result_sub1 = 0;
if (__builtin_sub_overflow(chan->id, csi->num_channels, &result_sub1)) {
dev_err(chan->csi->dev, "Number of calculated channel port exceeds the limit“\
\n");
return -ENOMEM;
}
chan->port[0] = result_sub1 % NUM_TPG_INSTANCE;
WARN_ON(chan->port[0] > csi->num_tpg_channels); WARN_ON(chan->port[0] > csi->num_tpg_channels);
chan->ports[0].stream_id = chan->port[0]; chan->ports[0].stream_id = chan->port[0];
chan->ports[0].virtual_channel_id chan->ports[0].virtual_channel_id
@@ -987,7 +1054,9 @@ static int csi_parse_dt(struct tegra_csi_device *csi,
if (strncmp(node->name, "nvcsi", 5)) { if (strncmp(node->name, "nvcsi", 5)) {
node = of_find_node_by_name(node, "nvcsi"); node = of_find_node_by_name(node, "nvcsi");
strncpy(csi->devname, "nvcsi", 6); if (sizeof(csi->devname) >= sizeof("nvcsi")) {
strncpy(csi->devname, "nvcsi", 6);
}
} }
if (node) { if (node) {

View File

@@ -1,8 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2015-2023, NVIDIA Corporation. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
* *
* camera_common.h - utilities for tegra camera driver * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __camera_common__ #ifndef __camera_common__
@@ -271,7 +282,16 @@ struct camera_common_focuser_data {
static inline void msleep_range(unsigned int delay_base) static inline void msleep_range(unsigned int delay_base)
{ {
usleep_range(delay_base * 1000, delay_base * 1000 + 500); unsigned int time_start = 0;
unsigned int time_end = 0;
if (__builtin_umul_overflow(delay_base, 1000, &time_start))
return;
if (__builtin_uadd_overflow(time_start, 500, &time_end))
return;
usleep_range(time_start, time_end);
} }
static inline struct camera_common_data *to_camera_common_data( static inline struct camera_common_data *to_camera_common_data(