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.
*
* 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 ==
camera_common_color_fmts[i].pix_fmt &&
!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_index = i;
// 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;
/* mode_type can be filled in sensor driver */
if (!(v4l2_g_ctrl(s_data->ctrl_handler, &hdr_control)))
mode_type |=
switch_ctrl_qmenu[hdr_control.value] ? HDR_ENABLE : 0;
if (!(v4l2_g_ctrl(s_data->ctrl_handler, &hdr_control))) {
if ((hdr_control.value < 0) || (hdr_control.value >= ARRAY_SIZE(switch_ctrl_qmenu))) {
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_prop_idx = 0;
@@ -898,7 +907,15 @@ void camera_common_dpd_disable(struct camera_common_data *s_data)
int i;
int io_idx;
/* 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 */
for (i = 0; i < numports; i++) {
@@ -934,7 +951,15 @@ void camera_common_dpd_enable(struct camera_common_data *s_data)
int i;
int io_idx;
/* 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 */
for (i = 0; i < numports; i++) {

View File

@@ -1,5 +1,5 @@
// 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
*/
@@ -15,6 +15,7 @@
#include <linux/of_platform.h>
#include <linux/property.h>
#include <linux/nospec.h>
#include <linux/string.h>
#include <media/media-entity.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);
if (!on) {
if (is_tpg)
if (is_tpg) {
if (csi->tpg_active > INT_MIN)
csi->tpg_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);
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++;
goto stream_okay;
}
stream_fail:
mutex_unlock(&csi->source_update);
dev_err(csi->dev, "Request rejected for new %s stream\n",
is_tpg ? "tpg" : "sensor");
@@ -420,10 +429,45 @@ unsigned int tegra_csi_ths_settling_time(
const unsigned int csicil_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;
}
EXPORT_SYMBOL(tegra_csi_ths_settling_time);
@@ -432,9 +476,24 @@ unsigned int tegra_csi_clk_settling_time(
struct tegra_csi_device *csi,
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;
}
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.
* 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);
chan->ports[0].stream_id = chan->port[0];
chan->ports[0].virtual_channel_id
@@ -987,8 +1054,10 @@ static int csi_parse_dt(struct tegra_csi_device *csi,
if (strncmp(node->name, "nvcsi", 5)) {
node = of_find_node_by_name(node, "nvcsi");
if (sizeof(csi->devname) >= sizeof("nvcsi")) {
strncpy(csi->devname, "nvcsi", 6);
}
}
if (node) {
err = of_property_read_u32(node, "num-channels", &num_channels);

View File

@@ -1,8 +1,19 @@
/* 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__
@@ -271,7 +282,16 @@ struct camera_common_focuser_data {
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(