Skip to content

Commit

Permalink
media: ti: cal: combine wdma irq handling
Browse files Browse the repository at this point in the history
Instead of handling the WDMA START and END interrupts separately, we
need to handle both at the same time to better manage the inherent race
conditions related to CAL interrupts.

Change the code so that we have a single function,
cal_irq_handle_wdma(), which gets two booleans, start and end, as
parameters, which allows us to manage the race conditions in the
following patch.

Signed-off-by: Tomi Valkeinen <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
tomba authored and mchehab committed Aug 30, 2022
1 parent ebdb28a commit 0872dc0
Showing 1 changed file with 25 additions and 34 deletions.
59 changes: 25 additions & 34 deletions drivers/media/platform/ti/cal/cal.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,22 +715,33 @@ static inline void cal_irq_wdma_end(struct cal_ctx *ctx)
}
}

static void cal_irq_handle_wdma(struct cal_ctx *ctx, bool start, bool end)
{
if (end)
cal_irq_wdma_end(ctx);

if (start)
cal_irq_wdma_start(ctx);
}

static irqreturn_t cal_irq(int irq_cal, void *data)
{
struct cal_dev *cal = data;
u32 status;

status = cal_read(cal, CAL_HL_IRQSTATUS(0));
if (status) {
unsigned int i;
u32 status[3];
unsigned int i;

cal_write(cal, CAL_HL_IRQSTATUS(0), status);
for (i = 0; i < 3; ++i) {
status[i] = cal_read(cal, CAL_HL_IRQSTATUS(i));
if (status[i])
cal_write(cal, CAL_HL_IRQSTATUS(i), status[i]);
}

if (status & CAL_HL_IRQ_OCPO_ERR_MASK)
if (status[0]) {
if (status[0] & CAL_HL_IRQ_OCPO_ERR_MASK)
dev_err_ratelimited(cal->dev, "OCPO ERROR\n");

for (i = 0; i < cal->data->num_csi2_phy; ++i) {
if (status & CAL_HL_IRQ_CIO_MASK(i)) {
if (status[0] & CAL_HL_IRQ_CIO_MASK(i)) {
u32 cio_stat = cal_read(cal,
CAL_CSI2_COMPLEXIO_IRQSTATUS(i));

Expand All @@ -741,7 +752,7 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
cio_stat);
}

if (status & CAL_HL_IRQ_VC_MASK(i)) {
if (status[0] & CAL_HL_IRQ_VC_MASK(i)) {
u32 vc_stat = cal_read(cal, CAL_CSI2_VC_IRQSTATUS(i));

dev_err_ratelimited(cal->dev,
Expand All @@ -753,32 +764,12 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
}
}

/* Check which DMA just finished */
status = cal_read(cal, CAL_HL_IRQSTATUS(1));
if (status) {
unsigned int i;

/* Clear Interrupt status */
cal_write(cal, CAL_HL_IRQSTATUS(1), status);

for (i = 0; i < cal->num_contexts; ++i) {
if (status & CAL_HL_IRQ_WDMA_END_MASK(i))
cal_irq_wdma_end(cal->ctx[i]);
}
}

/* Check which DMA just started */
status = cal_read(cal, CAL_HL_IRQSTATUS(2));
if (status) {
unsigned int i;

/* Clear Interrupt status */
cal_write(cal, CAL_HL_IRQSTATUS(2), status);
for (i = 0; i < cal->num_contexts; ++i) {
bool end = !!(status[1] & CAL_HL_IRQ_WDMA_END_MASK(i));
bool start = !!(status[2] & CAL_HL_IRQ_WDMA_START_MASK(i));

for (i = 0; i < cal->num_contexts; ++i) {
if (status & CAL_HL_IRQ_WDMA_START_MASK(i))
cal_irq_wdma_start(cal->ctx[i]);
}
if (start || end)
cal_irq_handle_wdma(cal->ctx[i], start, end);
}

return IRQ_HANDLED;
Expand Down

0 comments on commit 0872dc0

Please sign in to comment.