media: cx23885: Handle additional bufs on interrupt
On Ryzen systems interrupts are occasionally missed: cx23885: cx23885_wakeup: [ffff99b384b83c00/28] wakeup reg=5406 buf=5405 cx23885: cx23885_wakeup: [ffff99b40bf79400/31] wakeup reg=9537 buf=9536 This patch loops up to five times on wakeup, marking any buffers found done. Since the count register is u16, but the vb2 counter is u32, some modulo arithmetic is used to accommodate wraparound and ensure current active buffer is the buffer expected. Signed-off-by: Brad Love <brad@nextdimension.cc> Signed-off-by: Hans Verkuil <hansverk@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
acd14c181f
commit
9a7dc2b064
|
@ -422,19 +422,30 @@ static void cx23885_wakeup(struct cx23885_tsport *port,
|
|||
struct cx23885_dmaqueue *q, u32 count)
|
||||
{
|
||||
struct cx23885_buffer *buf;
|
||||
int count_delta;
|
||||
int max_buf_done = 5; /* service maximum five buffers */
|
||||
|
||||
if (list_empty(&q->active))
|
||||
return;
|
||||
buf = list_entry(q->active.next,
|
||||
struct cx23885_buffer, queue);
|
||||
do {
|
||||
if (list_empty(&q->active))
|
||||
return;
|
||||
buf = list_entry(q->active.next,
|
||||
struct cx23885_buffer, queue);
|
||||
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
buf->vb.sequence = q->count++;
|
||||
dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
|
||||
buf->vb.vb2_buf.index,
|
||||
count, q->count);
|
||||
list_del(&buf->queue);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
buf->vb.sequence = q->count++;
|
||||
if (count != (q->count % 65536)) {
|
||||
dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
|
||||
buf->vb.vb2_buf.index, count, q->count);
|
||||
} else {
|
||||
dprintk(7, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
|
||||
buf->vb.vb2_buf.index, count, q->count);
|
||||
}
|
||||
list_del(&buf->queue);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
max_buf_done--;
|
||||
/* count register is 16 bits so apply modulo appropriately */
|
||||
count_delta = ((int)count - (int)(q->count % 65536));
|
||||
} while ((count_delta > 0) && (max_buf_done > 0));
|
||||
}
|
||||
|
||||
int cx23885_sram_channel_setup(struct cx23885_dev *dev,
|
||||
|
|
Loading…
Reference in a new issue