mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
kernel: nvidia-oot: Fix Static issues S12/11
Jira CAMERASW-30258 Change-Id: I5fd26611f6bac71ec186458a583622b55ba8735e Signed-off-by: Yuyuan Chen <yuyuanc@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3262275 Reviewed-by: Ankur Pawar <ankurp@nvidia.com> Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com> Reviewed-by: Frank Chen <frankc@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: Ryan Li <ryanli@nvidia.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/overflow.h>
|
||||||
#include <linux/nvhost.h>
|
#include <linux/nvhost.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
@@ -519,6 +520,11 @@ int isp_channel_drv_register(
|
|||||||
chdrv_ = chan_drv;
|
chdrv_ = chan_drv;
|
||||||
mutex_unlock(&chdrv_lock);
|
mutex_unlock(&chdrv_lock);
|
||||||
|
|
||||||
|
if (isp_channel_major < 0) {
|
||||||
|
pr_err("%s: Invalid major number for ISP channel\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < chan_drv->num_channels; i++) {
|
for (i = 0; i < chan_drv->num_channels; i++) {
|
||||||
dev_t devt = MKDEV(isp_channel_major, i);
|
dev_t devt = MKDEV(isp_channel_major, i);
|
||||||
|
|
||||||
@@ -568,6 +574,11 @@ void isp_channel_drv_unregister(
|
|||||||
WARN_ON(chan_drv->dev != dev);
|
WARN_ON(chan_drv->dev != dev);
|
||||||
mutex_unlock(&chdrv_lock);
|
mutex_unlock(&chdrv_lock);
|
||||||
|
|
||||||
|
if (isp_channel_major < 0) {
|
||||||
|
pr_err("%s: Invalid major number for ISP channel\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < chan_drv->num_channels; i++) {
|
for (i = 0; i < chan_drv->num_channels; i++) {
|
||||||
dev_t devt = MKDEV(isp_channel_major, i);
|
dev_t devt = MKDEV(isp_channel_major, i);
|
||||||
|
|
||||||
|
|||||||
@@ -1156,11 +1156,17 @@ void isp_get_nvhost_device(
|
|||||||
struct tegra_isp_channel *chan,
|
struct tegra_isp_channel *chan,
|
||||||
struct isp_capture_setup *setup)
|
struct isp_capture_setup *setup)
|
||||||
{
|
{
|
||||||
uint32_t isp_inst = setup->isp_unit;
|
uint32_t isp_inst = 0U;
|
||||||
|
|
||||||
struct tegra_capture_isp_data *info =
|
struct tegra_capture_isp_data *info =
|
||||||
platform_get_drvdata(chan->isp_capture_pdev);
|
platform_get_drvdata(chan->isp_capture_pdev);
|
||||||
|
|
||||||
|
if (setup == NULL) {
|
||||||
|
dev_err(chan->isp_dev, "%s: Invalid ISP capture request\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isp_inst = setup->isp_unit;
|
||||||
|
|
||||||
if (isp_inst >= MAX_ISP_UNITS) {
|
if (isp_inst >= MAX_ISP_UNITS) {
|
||||||
dev_err(chan->isp_dev,
|
dev_err(chan->isp_dev,
|
||||||
"%s: ISP unit index is out of bound\n", __func__);
|
"%s: ISP unit index is out of bound\n", __func__);
|
||||||
|
|||||||
@@ -322,14 +322,20 @@ static int pin_vi_capture_request_buffers_locked(struct tegra_vi_channel *chan,
|
|||||||
struct capture_common_unpins *request_unpins)
|
struct capture_common_unpins *request_unpins)
|
||||||
{
|
{
|
||||||
struct vi_capture *capture = chan->capture_data;
|
struct vi_capture *capture = chan->capture_data;
|
||||||
struct capture_descriptor* desc = (struct capture_descriptor*)
|
struct capture_descriptor *desc = NULL;
|
||||||
(capture->requests.va +
|
|
||||||
req->buffer_index * capture->request_size);
|
|
||||||
|
|
||||||
struct capture_descriptor_memoryinfo* desc_mem =
|
struct capture_descriptor_memoryinfo* desc_mem =
|
||||||
&capture->requests_memoryinfo[req->buffer_index];
|
&capture->requests_memoryinfo[req->buffer_index];
|
||||||
int i;
|
int i;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
uint32_t buffer_amount = 0;
|
||||||
|
|
||||||
|
if (check_mul_overflow(req->buffer_index, capture->request_size, &buffer_amount)) {
|
||||||
|
dev_err(chan->dev, "%s: Requests memoryinfo overflow\n", __func__);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc = (struct capture_descriptor *)
|
||||||
|
(capture->requests.va + buffer_amount);
|
||||||
|
|
||||||
/* Buffer count: ATOMP surfaces + engine_surface */
|
/* Buffer count: ATOMP surfaces + engine_surface */
|
||||||
BUG_ON(VI_NUM_ATOMP_SURFACES + 1U >= MAX_PIN_BUFFER_PER_REQUEST);
|
BUG_ON(VI_NUM_ATOMP_SURFACES + 1U >= MAX_PIN_BUFFER_PER_REQUEST);
|
||||||
@@ -738,6 +744,11 @@ void vi_channel_drv_unregister(
|
|||||||
WARN_ON(&chan_drv->vi_capture_pdev->dev != dev);
|
WARN_ON(&chan_drv->vi_capture_pdev->dev != dev);
|
||||||
mutex_unlock(&chdrv_lock);
|
mutex_unlock(&chdrv_lock);
|
||||||
|
|
||||||
|
if (vi_channel_major < 0) {
|
||||||
|
pr_err("%s: Invalid major number for VI channel\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < chan_drv->num_channels; i++) {
|
for (i = 0; i < chan_drv->num_channels; i++) {
|
||||||
dev_t devt = MKDEV(vi_channel_major, i);
|
dev_t devt = MKDEV(vi_channel_major, i);
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/* SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES.
|
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES.
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
|
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
|
||||||
@@ -586,8 +574,7 @@ void vi_get_nvhost_device(
|
|||||||
platform_get_drvdata(chan->vi_capture_pdev);
|
platform_get_drvdata(chan->vi_capture_pdev);
|
||||||
|
|
||||||
if (setup->csi_stream_id >= MAX_NVCSI_STREAM_IDS) {
|
if (setup->csi_stream_id >= MAX_NVCSI_STREAM_IDS) {
|
||||||
dev_err(chan->dev,
|
dev_err(&chan->vi_capture_pdev->dev, "CSI stream ID over the limit\n");
|
||||||
"%s: csi stream id is out of bound\n", __func__);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
// SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
* regmap_util.c - utilities for writing regmap tables
|
// regmap_util.c - utilities for writing regmap tables
|
||||||
*
|
|
||||||
* Copyright (c) 2013-2022, NVIDIA Corporation. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/overflow.h>
|
||||||
#include <media/camera_common.h>
|
#include <media/camera_common.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -22,6 +20,7 @@ regmap_util_write_table_8(struct regmap *regmap,
|
|||||||
|
|
||||||
int range_start = -1;
|
int range_start = -1;
|
||||||
unsigned int range_count = 0;
|
unsigned int range_count = 0;
|
||||||
|
int range_end = 0;
|
||||||
/* bug 200048392 -
|
/* bug 200048392 -
|
||||||
* the vi i2c cannot take a FIFO buffer bigger than 16 bytes
|
* the vi i2c cannot take a FIFO buffer bigger than 16 bytes
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +31,12 @@ regmap_util_write_table_8(struct regmap *regmap,
|
|||||||
/* If we have a range open and */
|
/* If we have a range open and */
|
||||||
/* either the address doesn't match */
|
/* either the address doesn't match */
|
||||||
/* or the temporary storage is full, flush */
|
/* or the temporary storage is full, flush */
|
||||||
if ((next->addr != range_start + range_count) ||
|
if (check_add_overflow(range_start, (int)range_count, &range_end)) {
|
||||||
|
pr_err("%s:regmap_util_write_table overflow", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((next->addr != range_end) ||
|
||||||
(next->addr == end_addr) ||
|
(next->addr == end_addr) ||
|
||||||
(next->addr == wait_ms_addr) ||
|
(next->addr == wait_ms_addr) ||
|
||||||
(range_count == max_range_vals)) {
|
(range_count == max_range_vals)) {
|
||||||
@@ -104,6 +108,7 @@ regmap_util_write_table_16_as_8(struct regmap *regmap,
|
|||||||
|
|
||||||
int range_start = -1;
|
int range_start = -1;
|
||||||
unsigned int range_count = 0;
|
unsigned int range_count = 0;
|
||||||
|
int range_end = 0;
|
||||||
u8 range_vals[256];
|
u8 range_vals[256];
|
||||||
int max_range_vals = ARRAY_SIZE(range_vals) - 1;
|
int max_range_vals = ARRAY_SIZE(range_vals) - 1;
|
||||||
|
|
||||||
@@ -111,7 +116,12 @@ regmap_util_write_table_16_as_8(struct regmap *regmap,
|
|||||||
/* If we have a range open and */
|
/* If we have a range open and */
|
||||||
/* either the address doesn't match */
|
/* either the address doesn't match */
|
||||||
/* or the temporary storage is full, flush*/
|
/* or the temporary storage is full, flush*/
|
||||||
if ((next->addr != range_start + range_count) ||
|
if (check_add_overflow(range_start, (int)range_count, &range_end)) {
|
||||||
|
pr_err("%s:regmap_util_write_table overflow", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((next->addr != range_end) ||
|
||||||
(next->addr == end_addr) ||
|
(next->addr == end_addr) ||
|
||||||
(next->addr == wait_ms_addr) ||
|
(next->addr == wait_ms_addr) ||
|
||||||
(range_count == max_range_vals)) {
|
(range_count == max_range_vals)) {
|
||||||
@@ -166,4 +176,3 @@ regmap_util_write_table_16_as_8(struct regmap *regmap,
|
|||||||
|
|
||||||
EXPORT_SYMBOL_GPL(regmap_util_write_table_16_as_8);
|
EXPORT_SYMBOL_GPL(regmap_util_write_table_16_as_8);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES.
|
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
* All rights reserved.
|
// Tegra Video Input 5 device common APIs.
|
||||||
*
|
|
||||||
* Tegra Video Input 5 device common APIs
|
|
||||||
*
|
|
||||||
* Author: Frank Chen <frank@nvidia.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/freezer.h>
|
#include <linux/freezer.h>
|
||||||
@@ -264,8 +255,12 @@ static int vi5_channel_open(struct tegra_channel *chan, u32 vi_port)
|
|||||||
* by the platform will trigger a ENODEV from the
|
* by the platform will trigger a ENODEV from the
|
||||||
* VI capture channel driver
|
* VI capture channel driver
|
||||||
*/
|
*/
|
||||||
if (err == -EBUSY)
|
if (err == -EBUSY) {
|
||||||
channel++;
|
if (check_add_overflow(channel, 1, &channel)) {
|
||||||
|
dev_err(chan->vi->dev, "%s:channel overflow\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
dev_err(&chan->video->dev,
|
dev_err(&chan->video->dev,
|
||||||
"Error opening VI capture channel node %s with err: %ld\n",
|
"Error opening VI capture channel node %s with err: %ld\n",
|
||||||
@@ -390,22 +385,38 @@ static int tegra_channel_capture_setup(struct tegra_channel *chan, unsigned int
|
|||||||
static void vi5_setup_surface(struct tegra_channel *chan,
|
static void vi5_setup_surface(struct tegra_channel *chan,
|
||||||
struct tegra_channel_buffer *buf, unsigned int descr_index, unsigned int vi_port)
|
struct tegra_channel_buffer *buf, unsigned int descr_index, unsigned int vi_port)
|
||||||
{
|
{
|
||||||
dma_addr_t offset = buf->addr + chan->buffer_offset[vi_port];
|
dma_addr_t offset = 0;
|
||||||
u32 height = chan->format.height;
|
u32 height = chan->format.height;
|
||||||
u32 width = chan->format.width;
|
u32 width = chan->format.width;
|
||||||
u32 format = chan->fmtinfo->img_fmt;
|
u32 format = chan->fmtinfo->img_fmt;
|
||||||
u32 bpl = chan->format.bytesperline;
|
u32 bpl = chan->format.bytesperline;
|
||||||
u32 data_type = chan->fmtinfo->img_dt;
|
u32 data_type = chan->fmtinfo->img_dt;
|
||||||
u32 nvcsi_stream = chan->port[vi_port];
|
u32 nvcsi_stream = chan->port[vi_port];
|
||||||
|
unsigned int range = 0;
|
||||||
struct capture_descriptor_memoryinfo *desc_memoryinfo =
|
struct capture_descriptor_memoryinfo *desc_memoryinfo =
|
||||||
&chan->tegra_vi_channel[vi_port]->
|
&chan->tegra_vi_channel[vi_port]->
|
||||||
capture_data->requests_memoryinfo[descr_index];
|
capture_data->requests_memoryinfo[descr_index];
|
||||||
struct capture_descriptor *desc = &chan->request[vi_port][descr_index];
|
struct capture_descriptor *desc = &chan->request[vi_port][descr_index];
|
||||||
|
|
||||||
|
if (check_add_overflow(buf->addr, (dma_addr_t)chan->buffer_offset[vi_port], &offset)) {
|
||||||
|
dev_err(chan->vi->dev, "%s:Buf addr overflow\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (chan->valid_ports > NVCSI_STREAM_1) {
|
if (chan->valid_ports > NVCSI_STREAM_1) {
|
||||||
height = chan->gang_height;
|
height = chan->gang_height;
|
||||||
width = chan->gang_width;
|
width = chan->gang_width;
|
||||||
offset = buf->addr + chan->buffer_offset[1 - vi_port];
|
|
||||||
|
if (vi_port > 1) {
|
||||||
|
dev_err(chan->vi->dev, "%s: Invalid VI port number\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_add_overflow(buf->addr, (dma_addr_t)chan->buffer_offset[1 - vi_port],
|
||||||
|
&offset)) {
|
||||||
|
dev_err(chan->vi->dev, "%s: Buf addr overflow\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(desc, &capture_template, sizeof(capture_template));
|
memcpy(desc, &capture_template, sizeof(capture_template));
|
||||||
@@ -444,7 +455,11 @@ static void vi5_setup_surface(struct tegra_channel *chan,
|
|||||||
= chan->embedded_data_width * BPP_MEM;
|
= chan->embedded_data_width * BPP_MEM;
|
||||||
}
|
}
|
||||||
//capture sequence should increment for each vi channel
|
//capture sequence should increment for each vi channel
|
||||||
if ((chan->valid_ports - vi_port) == 1)
|
if (check_sub_overflow(chan->valid_ports, vi_port, &range)) {
|
||||||
|
dev_err(chan->vi->dev, "%s:Chan valid ports overflow\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (range == 1)
|
||||||
chan->capture_descr_sequence += 1;
|
chan->capture_descr_sequence += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +468,12 @@ static void vi5_release_buffer(struct tegra_channel *chan,
|
|||||||
{
|
{
|
||||||
struct vb2_v4l2_buffer *vbuf = &buf->buf;
|
struct vb2_v4l2_buffer *vbuf = &buf->buf;
|
||||||
|
|
||||||
vbuf->sequence = chan->sequence++;
|
if (check_add_overflow(chan->sequence, 1U, &chan->sequence)) {
|
||||||
|
dev_err(chan->vi->dev, "%s:chan sequence overflow\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vbuf->sequence = chan->sequence;
|
||||||
vbuf->field = V4L2_FIELD_NONE;
|
vbuf->field = V4L2_FIELD_NONE;
|
||||||
vb2_set_plane_payload(&vbuf->vb2_buf, 0, chan->format.sizeimage);
|
vb2_set_plane_payload(&vbuf->vb2_buf, 0, chan->format.sizeimage);
|
||||||
|
|
||||||
@@ -611,6 +631,7 @@ static int vi5_channel_error_recover(struct tegra_channel *chan,
|
|||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned int vi_port = 0;
|
unsigned int vi_port = 0;
|
||||||
|
unsigned long flags = 0;
|
||||||
struct tegra_channel_buffer *buf;
|
struct tegra_channel_buffer *buf;
|
||||||
struct tegra_mc_vi *vi = chan->vi;
|
struct tegra_mc_vi *vi = chan->vi;
|
||||||
struct v4l2_subdev *csi_subdev;
|
struct v4l2_subdev *csi_subdev;
|
||||||
@@ -679,7 +700,9 @@ static int vi5_channel_error_recover(struct tegra_channel *chan,
|
|||||||
chan->capture_reqs_enqueued = 0;
|
chan->capture_reqs_enqueued = 0;
|
||||||
|
|
||||||
/* clear capture channel error state */
|
/* clear capture channel error state */
|
||||||
|
spin_lock_irqsave(&chan->capture_state_lock, flags);
|
||||||
chan->capture_state = CAPTURE_IDLE;
|
chan->capture_state = CAPTURE_IDLE;
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return err;
|
return err;
|
||||||
@@ -739,10 +762,12 @@ static int tegra_channel_kthread_capture_dequeue(void *data)
|
|||||||
while (1) {
|
while (1) {
|
||||||
try_to_freeze();
|
try_to_freeze();
|
||||||
|
|
||||||
|
spin_lock_irqsave(&chan->capture_state_lock, flags);
|
||||||
wait_event_interruptible(chan->dequeue_wait,
|
wait_event_interruptible(chan->dequeue_wait,
|
||||||
(kthread_should_stop()
|
(kthread_should_stop()
|
||||||
|| !list_empty(&chan->dequeue)
|
|| !list_empty(&chan->dequeue)
|
||||||
|| (chan->capture_state == CAPTURE_ERROR)));
|
|| (chan->capture_state == CAPTURE_ERROR)));
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
|
|
||||||
while (!(kthread_should_stop() || list_empty(&chan->dequeue)
|
while (!(kthread_should_stop() || list_empty(&chan->dequeue)
|
||||||
|| (chan->capture_state == CAPTURE_ERROR))) {
|
|| (chan->capture_state == CAPTURE_ERROR))) {
|
||||||
|
|||||||
Reference in New Issue
Block a user