Re: [PATCH 5/6] media: ti: cal: combine wdma irq handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Tomi,

Thank you for the patch.

On Thu, Apr 21, 2022 at 05:34:48PM +0300, Tomi Valkeinen wrote:
> 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 <tomi.valkeinen@xxxxxxxxxxxxxxxx>

Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>

> ---
>  drivers/media/platform/ti/cal/cal.c | 59 ++++++++++++-----------------
>  1 file changed, 25 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c
> index 783ce5a8cd79..e4355f266c58 100644
> --- a/drivers/media/platform/ti/cal/cal.c
> +++ b/drivers/media/platform/ti/cal/cal.c
> @@ -668,22 +668,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));
>  
> @@ -694,7 +705,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,
> @@ -706,32 +717,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;

-- 
Regards,

Laurent Pinchart



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux