0
0
mirror of https://git.openwrt.org/openwrt/openwrt.git synced 2024-11-22 04:56:15 +00:00
openwrt/target/linux/bcm27xx/patches-6.6/950-0349-media-bcm2835-unicam-Handle-a-repeated-frame-start-w.patch
Álvaro Fernández Rojas 8c405cdccc bcm27xx: add 6.6 kernel patches
The patches were generated from the RPi repo with the following command:
git format-patch v6.6.34..rpi-6.1.y

Some patches needed rebasing and, as usual, the applied and reverted, wireless
drivers, Github workflows, READMEs and defconfigs patches were removed.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-06-18 18:52:49 +02:00

64 lines
2.3 KiB
Diff

From 81838b0c1e957ad68aa2c32825647f1012ae7f74 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Fri, 4 Feb 2022 16:12:35 +0000
Subject: [PATCH 0349/1085] media: bcm2835-unicam: Handle a repeated frame
start with no end
In the case of 2 frame starts being received with no frame end
between, the queued buffer held in next_frm was lost as the
pointer was overwritten with the dummy buffer.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
.../media/platform/bcm2835/bcm2835-unicam.c | 29 +++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
@@ -930,10 +930,14 @@ static irqreturn_t unicam_isr(int irq, v
* as complete, as the HW will reuse that buffer.
*/
if (unicam->node[i].cur_frm &&
- unicam->node[i].cur_frm != unicam->node[i].next_frm)
+ unicam->node[i].cur_frm != unicam->node[i].next_frm) {
unicam_process_buffer_complete(&unicam->node[i],
sequence);
- unicam->node[i].cur_frm = unicam->node[i].next_frm;
+ unicam->node[i].cur_frm = unicam->node[i].next_frm;
+ unicam->node[i].next_frm = NULL;
+ } else {
+ unicam->node[i].cur_frm = unicam->node[i].next_frm;
+ }
}
unicam->sequence++;
}
@@ -956,10 +960,25 @@ static irqreturn_t unicam_isr(int irq, v
i);
/*
* Set the next frame output to go to a dummy frame
- * if we have not managed to obtain another frame
- * from the queue.
+ * if no buffer currently queued.
*/
- unicam_schedule_dummy_buffer(&unicam->node[i]);
+ if (!unicam->node[i].next_frm ||
+ unicam->node[i].next_frm == unicam->node[i].cur_frm) {
+ unicam_schedule_dummy_buffer(&unicam->node[i]);
+ } else if (unicam->node[i].cur_frm) {
+ /*
+ * Repeated FS without FE. Hardware will have
+ * swapped buffers, but the cur_frm doesn't
+ * contain valid data. Return cur_frm to the
+ * queue.
+ */
+ spin_lock(&unicam->node[i].dma_queue_lock);
+ list_add_tail(&unicam->node[i].cur_frm->list,
+ &unicam->node[i].dma_queue);
+ spin_unlock(&unicam->node[i].dma_queue_lock);
+ unicam->node[i].cur_frm = unicam->node[i].next_frm;
+ unicam->node[i].next_frm = NULL;
+ }
}
unicam_queue_event_sof(unicam);