Re: [PATCH] media: intel/ipu6: do not handle interrupts when device is disabled

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

 



Hi,

On 31-Oct-24 11:23 AM, Stanislaw Gruszka wrote:
> Some IPU6 devices have shared interrupts. We need to handle properly
> case when interrupt is triggered from other device on shared irq line
> and IPU6 itself disabled. In such case we get 0xffffffff from
> ISR_STATUS register and handle all irq's cases, for what we are not
> not prepared and usually hang the whole system.
> 
> To avoid the issue use pm_runtime_get_if_active() to check if
> the device is enabled and prevent suspending it when we handle irq
> until the end of irq. Additionally use synchronize_irq() in suspend
> 
> Fixes: ab29a2478e70 ("media: intel/ipu6: add IPU6 buttress interface driver")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@xxxxxxxxxxxxxxx>

Thanks, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@xxxxxxxxxx>

I have also given this a test run on a "ThinkPad X1 Yoga Gen 8" and
everything there works at least as well as before:

Tested-by: Hans de Goede <hdegoede@xxxxxxxxxx> # ThinkPad X1 Yoga Gen 8, ov2740

Regards,

Hans


> ---
>  drivers/media/pci/intel/ipu6/ipu6-buttress.c | 13 +++++++++----
>  drivers/media/pci/intel/ipu6/ipu6.c          |  3 +++
>  2 files changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
> index e47f84c30e10..edaa285283a1 100644
> --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c
> +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
> @@ -345,12 +345,16 @@ irqreturn_t ipu6_buttress_isr(int irq, void *isp_ptr)
>  	u32 disable_irqs = 0;
>  	u32 irq_status;
>  	u32 i, count = 0;
> +	int active;
>  
> -	pm_runtime_get_noresume(&isp->pdev->dev);
> +	active = pm_runtime_get_if_active(&isp->pdev->dev);
> +	if (!active)
> +		return IRQ_NONE;
>  
>  	irq_status = readl(isp->base + reg_irq_sts);
> -	if (!irq_status) {
> -		pm_runtime_put_noidle(&isp->pdev->dev);
> +	if (irq_status == 0 || WARN_ON_ONCE(irq_status == 0xffffffffu)) {
> +		if (active > 0)
> +			pm_runtime_put_noidle(&isp->pdev->dev);
>  		return IRQ_NONE;
>  	}
>  
> @@ -426,7 +430,8 @@ irqreturn_t ipu6_buttress_isr(int irq, void *isp_ptr)
>  		writel(BUTTRESS_IRQS & ~disable_irqs,
>  		       isp->base + BUTTRESS_REG_ISR_ENABLE);
>  
> -	pm_runtime_put(&isp->pdev->dev);
> +	if (active > 0)
> +		pm_runtime_put(&isp->pdev->dev);
>  
>  	return ret;
>  }
> diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c
> index 7fb707d35309..91718eabd74e 100644
> --- a/drivers/media/pci/intel/ipu6/ipu6.c
> +++ b/drivers/media/pci/intel/ipu6/ipu6.c
> @@ -752,6 +752,9 @@ static void ipu6_pci_reset_done(struct pci_dev *pdev)
>   */
>  static int ipu6_suspend(struct device *dev)
>  {
> +	struct pci_dev *pdev = to_pci_dev(dev);
> +
> +	synchronize_irq(pdev->irq);
>  	return 0;
>  }
>  





[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