diff --git a/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c b/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c index bfc50eb9..e1e86c0d 100644 --- a/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c +++ b/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c @@ -1,5 +1,17 @@ // SPDX-License-Identifier: GPL-2.0-only -// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +/* SPDX-FileCopyrightText: Copyright (c) 2017-2024 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 @@ -1457,7 +1469,12 @@ int vi_capture_status( /* negative timeout means wait forever */ if (timeout_ms < 0) { - wait_for_completion(&capture->capture_resp); + ret = wait_for_completion_interruptible(&capture->capture_resp); + if (ret == -ERESTARTSYS) { + dev_dbg(chan->dev, + "capture status interrupted\n"); + return -ETIMEDOUT; + } } else { ret = wait_for_completion_timeout( &capture->capture_resp, diff --git a/drivers/media/platform/tegra/camera/vi/vi5_fops.c b/drivers/media/platform/tegra/camera/vi/vi5_fops.c index 7b16dcaf..c6093a75 100644 --- a/drivers/media/platform/tegra/camera/vi/vi5_fops.c +++ b/drivers/media/platform/tegra/camera/vi/vi5_fops.c @@ -1,8 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 -/* +/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. + * All rights reserved. + * * Tegra Video Input 5 device common APIs * - * Copyright (c) 2016-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Author: Frank Chen + * + * 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 @@ -134,6 +140,9 @@ static int tegra_vi5_s_ctrl(struct v4l2_ctrl *ctrl) case TEGRA_CAMERA_CID_WRITE_ISPFORMAT: chan->write_ispformat = ctrl->val; break; + case TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT: + chan->capture_timeout_ms = ctrl->val; + break; default: dev_err(&chan->video->dev, "%s:Not valid ctrl\n", __func__); return -EINVAL; @@ -200,6 +209,16 @@ static const struct v4l2_ctrl_config vi5_custom_ctrls[] = { .step = 1, .dims = { SENSOR_CTRL_BLOB_SIZE }, }, + { + .ops = &vi5_ctrl_ops, + .id = TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT, + .name = "Override capture timeout ms", + .type = V4L2_CTRL_TYPE_INTEGER, + .def = CAPTURE_TIMEOUT_MS, + .min = -1, + .max = 0x7FFFFFFF, + .step = 1, + }, }; static int vi5_add_ctrls(struct tegra_channel *chan) @@ -497,6 +516,7 @@ static void vi5_capture_dequeue(struct tegra_channel *chan, unsigned long flags; struct tegra_mc_vi *vi = chan->vi; struct vb2_v4l2_buffer *vb = &buf->buf; + int timeout_ms = CAPTURE_TIMEOUT_MS; struct timespec64 ts; struct capture_descriptor *descr = NULL; @@ -507,12 +527,21 @@ static void vi5_capture_dequeue(struct tegra_channel *chan, goto rel_buf; /* Dequeue a frame and check its capture status */ - err = vi_capture_status(chan->tegra_vi_channel[vi_port], CAPTURE_TIMEOUT_MS); + timeout_ms = chan->capture_timeout_ms; + err = vi_capture_status(chan->tegra_vi_channel[vi_port], timeout_ms); if (err) { if (err == -ETIMEDOUT) { - dev_err(vi->dev, - "uncorr_err: request timed out after %d ms\n", - CAPTURE_TIMEOUT_MS); + if (timeout_ms < 0) { + spin_lock_irqsave(&chan->capture_state_lock, flags); + chan->capture_state = CAPTURE_ERROR_TIMEOUT; + spin_unlock_irqrestore(&chan->capture_state_lock, flags); + buf->vb2_state = VB2_BUF_STATE_ERROR; + goto rel_buf; + } else { + dev_err(vi->dev, + "uncorr_err: request timed out after %d ms\n", + timeout_ms); + } } else { dev_err(vi->dev, "uncorr_err: request err %d\n", err); } @@ -702,6 +731,7 @@ static int tegra_channel_kthread_capture_dequeue(void *data) struct tegra_channel_buffer *buf; set_freezable(); + allow_signal(SIGINT); while (1) { try_to_freeze(); @@ -722,6 +752,12 @@ static int tegra_channel_kthread_capture_dequeue(void *data) } spin_lock_irqsave(&chan->capture_state_lock, flags); + if (chan->capture_state == CAPTURE_ERROR_TIMEOUT) { + spin_unlock_irqrestore(&chan->capture_state_lock, + flags); + break; + } + if (chan->capture_state == CAPTURE_ERROR) { spin_unlock_irqrestore(&chan->capture_state_lock, flags); @@ -791,6 +827,7 @@ static void vi5_channel_stop_kthreads(struct tegra_channel *chan) /* Stop the kthread for capture dequeue */ if (chan->kthread_capture_dequeue) { + send_sig(SIGINT, chan->kthread_capture_dequeue, 1); kthread_stop(chan->kthread_capture_dequeue); chan->kthread_capture_dequeue = NULL; } diff --git a/include/media/mc_common.h b/include/media/mc_common.h index 0408ba67..607f1f5f 100644 --- a/include/media/mc_common.h +++ b/include/media/mc_common.h @@ -1,8 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* +/* SPDX-FileCopyrightText: Copyright (c) 2012-2024 NVIDIA CORPORATION & AFFILIATES. + * All rights reserved. + * + * drivers/media/platform/tegra/camera/mc_common.h + * * Tegra Media controller common APIs * - * Copyright (c) 2012-2024 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #ifndef __CAMERA_MC_COMMON_H__ @@ -229,6 +243,7 @@ struct tegra_channel { struct v4l2_fh *fh; bool bypass; bool write_ispformat; + int capture_timeout_ms; bool low_latency; enum tegra_vi_pg_mode pg_mode; bool bfirst_fstart; diff --git a/include/media/tegra-v4l2-camera.h b/include/media/tegra-v4l2-camera.h index 3521ed37..f39f8639 100644 --- a/include/media/tegra-v4l2-camera.h +++ b/include/media/tegra-v4l2-camera.h @@ -1,8 +1,20 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tegra-v4l2-camera.h - utilities for tegra camera driver +/* SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. + * All rights reserved. * - * Copyright (c) 2017-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * TEGRA_V4L2_CAMERA.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 . */ #ifndef __TEGRA_V4L2_CAMERA__ @@ -48,6 +60,7 @@ #define TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS (TEGRA_CAMERA_CID_BASE+108) #define TEGRA_CAMERA_CID_LOW_LATENCY (TEGRA_CAMERA_CID_BASE+109) #define TEGRA_CAMERA_CID_VI_PREFERRED_STRIDE (TEGRA_CAMERA_CID_BASE+110) +#define TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT (TEGRA_CAMERA_CID_BASE+111) /** * This is temporary with the current v4l2 infrastructure