Kernel panic when mipi input is disconnected and reconnected

Linux R35.5.0 (Jetpack 5.1.3) with custom carrier board
I have modified the device tree and ov5693 driver to support camera capture from an FPGA. The Xilinx FPGA is sending yuv8 1920x1080 frames at 60fps, MIPI data rate 1400 Mbps, continous clock and 2 lanes .
I run the following v4l2-ctl command and then disconnect and then reconnect the 1080p60 source resulting in a kernel panic as per attached log,

v4l2-ctl --device /dev/video1 --set-fmt-video=width=1920,height=1080,pixelformat=YUYV --set-ctrl bypass_mode=0 --stream-mmap

Is there a patch to fix this?

dmesg.txt (93.2 KB)

hello alanser,

may I know what’s the real use-case?
had you try terminate v4l pipeline after you disconnect the stream?

Use-case is avionics DVR. DVR has to be tolerant of input disconnect/reconnect and video input format changes. If disconnect does not result in kernel panic I can terminate v4l and this happens:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 60.00 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 60.00 fps

root@xavier:~# v4l2-ctl --device /dev/video1 --set-fmt-video=width=1920,height=1080,pixelformat=YUYV --set-ctrl bypass_mode=0 --stream-mmap
VIDIOC_STREAMON returned -1 (Connection timed out)

And this prints in the kernel log:
root@xavier:~# [ 475.839695] tegra194-vi5 capture control message timed out
[ 475.841500] tegra-camrtc-capture-vi tegra-capture-vi: vi capture setup failed
[ 476.863688] tegra194-vi5 capture control message timed out
[ 476.865352] tegra194-vi5 csi_stream_release: failed to disable nvcsi tpg on stream 0 virtual channel 0

hello alanser,

let’s try apply below kernel patch, which add semaphore to avoid race condition.

diff --git a/drivers/platform/tegra/rtcpu/capture-ivc.c b/drivers/platform/tegra/rtcpu/capture-ivc.c

@@ -28,11 +30,15 @@
 #include <linux/tegra-ivc.h>
 #include <linux/tegra-ivc-bus.h>
 #include <linux/nospec.h>
+#include <linux/semaphore.h>
 #include <asm/barrier.h>
 #include "capture-ivc-priv.h"
+/* Timeout for acquiring channel-id */
 static int tegra_capture_ivc_tx(struct tegra_capture_ivc *civc,
                                const void *req, size_t len)
@@ -165,6 +171,11 @@ int tegra_capture_ivc_notify_chan_id(uint32_t chan_id, uint32_t trans_id)
        civc = __scivc_control;
+       if (down_timeout(&civc->cb_ctx[chan_id].sem_ch,
+                               TIMEOUT_ACQUIRE_CHANNEL_ID)) {
+               return -EBUSY;
+       }
        if (WARN(civc->cb_ctx[trans_id].cb_func == NULL,
@@ -269,6 +280,7 @@ int tegra_capture_ivc_unregister_control_cb(uint32_t id)
        civc->cb_ctx[id].priv_context = NULL;
+       up(&civc->cb_ctx[id].sem_ch);
         * If it's trans_id, client encountered an error before or during
@@ -415,6 +427,9 @@ static int tegra_capture_ivc_probe(struct tegra_ivc_channel *chan)
+       for (i = 0; i < TOTAL_CHANNELS; i++)
+               sema_init(&civc->cb_ctx[i].sem_ch, 1);
        /* Initialize ivc_work */
        INIT_WORK(&civc->work, tegra_capture_ivc_worker);

Semaphore patch seems to have improved matters. I still have no recovery on a disconnect/reconnect but on v4l terminate and restart it recovers. However after doing that a few times I still got a kernel oops. See attached log. Any ideas on how to fix crash?
minicom351.txt (15.9 KB)

you may checking Topic 280731 for patches of error handling use-case via v4l2.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.