Re: [PATCH] media: vsp1: mask interrupts before enabling

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

 



Hi Nikita,

Quoting Nikita Yushchenko (2021-09-26 16:53:56)
> Setting up VSP interrupt handler without masking interrupt before causes
> interrupt handler to be immediately called (and crash due to null pointer
> dereference) on r8a77951-ulcb-kf board.
> 
> Fix that by explicitly masking all interrupts before setting the interrupt
> handler. To do so, have to set the interrupt handler later, after hw
> revision is already detected and number of interrupts to mask gets
> known.
> 
> Based on patch by Koji Matsuoka <koji.matsuoka.xm@xxxxxxxxxxx> included
> in the Renesas BSP kernel. Updated that to use wfp_count as the number of

s/wfp_count/wpf_count/

> WPF interrupts to mask.
> 
> Signed-off-by: Nikita Yushchenko <nikita.yoush@xxxxxxxxxxxxxxxxxx>
> ---
>  drivers/media/platform/vsp1/vsp1_drv.c | 23 +++++++++++++++--------
>  1 file changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index de442d6c9926..0e9a6fad54f8 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -811,13 +811,6 @@ static int vsp1_probe(struct platform_device *pdev)
>                 return -EINVAL;
>         }
>  
> -       ret = devm_request_irq(&pdev->dev, irq->start, vsp1_irq_handler,
> -                             IRQF_SHARED, dev_name(&pdev->dev), vsp1);
> -       if (ret < 0) {
> -               dev_err(&pdev->dev, "failed to request IRQ\n");
> -               return ret;
> -       }
> -
>         /* FCP (optional). */
>         fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
>         if (fcp_node) {
> @@ -847,7 +840,6 @@ static int vsp1_probe(struct platform_device *pdev)
>                 goto done;
>  
>         vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION);
> -       vsp1_device_put(vsp1);
>  
>         for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) {
>                 if ((vsp1->version & VI6_IP_VERSION_MODEL_MASK) ==
> @@ -861,11 +853,26 @@ static int vsp1_probe(struct platform_device *pdev)
>                 dev_err(&pdev->dev, "unsupported IP version 0x%08x\n",
>                         vsp1->version);
>                 ret = -ENXIO;
> +               vsp1_device_put(vsp1);
>                 goto done;
>         }
>  
>         dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version);
>  
> +       for (i = 0; i < vsp1->info->lif_count; ++i)
> +               vsp1_write(vsp1, VI6_DISP_IRQ_ENB(i), 0);
> +       for (i = 0; i < vsp1->info->wpf_count; ++i)
> +               vsp1_write(vsp1, VI6_WPF_IRQ_ENB(i), 0);

Should any other state or context on the hardware be manually reset?

The initial value of VI6_WPFn_IRQ_ENB and VI6_DISPn_IRQ_ENB is
explicitly stated as H'00000000 in the datasheet. So perhaps that
implies that something else is going on here.

Perhaps the display is already used before the kernel boots to handle a
bootsplash screen or such ?

Will the 'pending' interrupts have otherwise been cleared by the time we
get to come to enable them? or will we still have a race...

Otherwise we should be clearing the status bits too. And if we need to
do a whole software reset, we should use the software reset controls
instead.

Looking at vsp1_device_init(), which does a vsp1_reset_wpf for any WPF
running, and is called at vsp1_pm_runtime_resume() means that everything
should already be getting reset by software at the first call to
pm_runtime_enable I think...

That said, I can see how there could still be a race so requesting the
IRQ below /after/ the device is initialised is a good thing. I just
don't think we need the manual resets that you've added above.

Could you test to see if those lines to explicitly set VI6_DISP_IRQ_ENB
and VI6_WPF_IRQ_ENB are really needed in your use case please?

--
Kieran


> +
> +       vsp1_device_put(vsp1);
> +
> +       ret = devm_request_irq(&pdev->dev, irq->start, vsp1_irq_handler,
> +                              IRQF_SHARED, dev_name(&pdev->dev), vsp1);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "failed to request IRQ\n");
> +               goto done;
> +       }
> +
>         /* Instantiate entities. */
>         ret = vsp1_create_entities(vsp1);
>         if (ret < 0) {
> -- 
> 2.30.2
>




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux