Commit c7cfc7b9 authored by Nikita Yushchenko's avatar Nikita Yushchenko Committed by Mauro Carvalho Chehab

media: vsp1: mask interrupts before enabling

VSP hardware could be used (e.g. by the bootloader) before driver load,
and some interrupts could be left in enabled and pending state. In this
case, setting up VSP interrupt handler without masking interrupts before
causes interrupt handler to be immediately called (and crash due to null
vsp->info dereference).

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@renesas.com> included
in the Renesas BSP kernel.
Signed-off-by: default avatarNikita Yushchenko <nikita.yoush@cogentembedded.com>
Reviewed-by: default avatarKieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 53c26454
......@@ -550,6 +550,16 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
return 0;
}
static void vsp1_mask_all_interrupts(struct vsp1_device *vsp1)
{
unsigned int i;
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);
}
/*
* vsp1_device_get - Acquire the VSP1 device
*
......@@ -817,13 +827,6 @@ static int vsp1_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
ret = devm_request_irq(&pdev->dev, irq, 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) {
......@@ -853,7 +856,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) ==
......@@ -866,12 +868,31 @@ static int vsp1_probe(struct platform_device *pdev)
if (!vsp1->info) {
dev_err(&pdev->dev, "unsupported IP version 0x%08x\n",
vsp1->version);
vsp1_device_put(vsp1);
ret = -ENXIO;
goto done;
}
dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version);
/*
* Previous use of the hardware (e.g. by the bootloader) could leave
* some interrupts enabled and pending.
*
* TODO: Investigate if this shouldn't be better handled by using the
* device reset provided by the CPG.
*/
vsp1_mask_all_interrupts(vsp1);
vsp1_device_put(vsp1);
ret = devm_request_irq(&pdev->dev, irq, 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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment