[PATCH RESEND 43/45] media: qcom: camss: ife: queue params buffers in FIFO order
From: Gjorgji . Rosikopulos . gjorgji . rosikopulos
Date: Wed Oct 07 2026 - 05:18:08 EST
From: Gjorgji Rosikopulos <gjorgji.rosikopulos@xxxxxxxxxxxxxxxx>
ife->pending_params was a single-slot pointer: queuing a second PARAMS
buffer before the next PP epoch0 IRQ consumed it would silently
displace the first one, completing it with VB2_BUF_STATE_ERROR. This
means a userspace client that queues several params buffers ahead of
time (mirroring how image buffers are queued) loses all but the most
recently queued one instead of having them applied one per frame in
order.
Turn pending_params into a struct list_head FIFO, following the same
pending_bufs/bufs_lock pattern already used for image buffers. Buffers
are now enqueued at the tail in camss_ife_queue_buffer() and dequeued
from the head once per PP epoch0 IRQ, applying at most one params
buffer per frame without dropping queued-ahead buffers. Flushing on
stream-off now completes every buffer left in the list rather than
just one.
Signed-off-by: Gjorgji Rosikopulos <gjorgji.rosikopulos@xxxxxxxxxxxxxxxx>
---
drivers/media/platform/qcom/camss/camss-ife.c | 25 +++++++++----------
drivers/media/platform/qcom/camss/camss-ife.h | 2 +-
2 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-ife.c b/drivers/media/platform/qcom/camss/camss-ife.c
index ab6102fd1126..57fab10a87f5 100644
--- a/drivers/media/platform/qcom/camss/camss-ife.c
+++ b/drivers/media/platform/qcom/camss/camss-ife.c
@@ -293,8 +293,10 @@ static void ife_hw_isr_pp_epoch0(struct ife_device *ife)
spin_lock_irqsave(&ife->bufs_lock, flags);
- params_buf = ife->pending_params;
- ife->pending_params = NULL;
+ params_buf = list_first_entry_or_null(&ife->pending_params,
+ struct camss_buffer, queue);
+ if (params_buf)
+ list_del(¶ms_buf->queue);
for (i = 0; i < ife->npads; i++) {
struct ife_video_pad *vid_pad = ife->pads[i].vid_pad;
@@ -1360,17 +1362,13 @@ static int ife_queue_buffer(struct camss_video *vid, struct camss_buffer *buf)
struct ife_device *ife = vid_pad->ife;
if (is_ife_video_params(vid)) {
- struct camss_buffer *old_buf;
unsigned long flags;
spin_lock_irqsave(&ife->bufs_lock, flags);
- old_buf = ife->pending_params;
- ife->pending_params = buf;
+ INIT_LIST_HEAD(&buf->queue);
+ list_add_tail(&buf->queue, &ife->pending_params);
spin_unlock_irqrestore(&ife->bufs_lock, flags);
- if (old_buf)
- vb2_buffer_done(&old_buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-
return 0;
}
@@ -1387,15 +1385,15 @@ static int ife_flush_buffers(struct camss_video *vid, enum vb2_buffer_state stat
if (is_ife_video_params(vid)) {
struct ife_device *ife = vid_pad->ife;
struct camss_buffer *buf;
+ struct camss_buffer *tmp;
unsigned long flags;
spin_lock_irqsave(&ife->bufs_lock, flags);
- buf = ife->pending_params;
- ife->pending_params = NULL;
- spin_unlock_irqrestore(&ife->bufs_lock, flags);
-
- if (buf)
+ list_for_each_entry_safe(buf, tmp, &ife->pending_params, queue) {
+ list_del(&buf->queue);
vb2_buffer_done(&buf->vb.vb2_buf, state);
+ }
+ spin_unlock_irqrestore(&ife->bufs_lock, flags);
return 0;
}
@@ -1499,6 +1497,7 @@ int camss_ife_subdev_init(struct camss *camss, struct ife_device *ife,
init_completion(&ife->reset_complete);
mutex_init(&ife->state_mutex);
spin_lock_init(&ife->bufs_lock);
+ INIT_LIST_HEAD(&ife->pending_params);
/* Memory */
base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
diff --git a/drivers/media/platform/qcom/camss/camss-ife.h b/drivers/media/platform/qcom/camss/camss-ife.h
index c38b96076a1f..9656d29717d1 100644
--- a/drivers/media/platform/qcom/camss/camss-ife.h
+++ b/drivers/media/platform/qcom/camss/camss-ife.h
@@ -367,7 +367,7 @@ struct ife_device {
struct camss_ife_pipeline_cfg pipeline_cfg[IFE_CAMIF_HW_PIPES_MAX];
- struct camss_buffer *pending_params;
+ struct list_head pending_params;
struct v4l2_subdev sd;
struct device *genpd;
--
2.34.1