From 273b21ef0826f2f7739266f0f0e65ae3739bf69a Mon Sep 17 00:00:00 2001 From: Hu Kejun Date: Fri, 28 Jun 2019 08:47:34 +0800 Subject: [PATCH] media: rockchip: isp1: fix receive mipi isr before isp clock resume The mipi interrupt is auto on in resume operation, so we may receive interrupt before isp clock resume, and the kernel will be dead when access isp register in mipi isr function. Change-Id: I73779111cb103457b0a4f125d8e4c9420a2d8553 Signed-off-by: Hu Kejun --- drivers/media/platform/rockchip/isp1/dev.c | 19 +++++++++++++++++++ drivers/media/platform/rockchip/isp1/dev.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c index 2bbf85ea6ed9..9da0efe176c8 100644 --- a/drivers/media/platform/rockchip/isp1/dev.c +++ b/drivers/media/platform/rockchip/isp1/dev.c @@ -998,6 +998,7 @@ static int rkisp1_plat_probe(struct platform_device *pdev) return PTR_ERR(isp_dev->base_addr); match_data = match->data; + isp_dev->mipi_irq = -1; res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, match_data->irqs[0].name); if (res) { @@ -1011,6 +1012,9 @@ static int rkisp1_plat_probe(struct platform_device *pdev) return irq; } + if (!strcmp(match_data->irqs[i].name, "mipi_irq")) + isp_dev->mipi_irq = irq; + ret = devm_request_irq(dev, irq, match_data->irqs[i].irq_hdl, IRQF_SHARED, @@ -1022,6 +1026,9 @@ static int rkisp1_plat_probe(struct platform_device *pdev) ret); return ret; } + + if (isp_dev->mipi_irq == irq) + disable_irq(isp_dev->mipi_irq); } } else { /* no irq names in dts */ @@ -1138,6 +1145,10 @@ static int __maybe_unused rkisp1_runtime_suspend(struct device *dev) { struct rkisp1_device *isp_dev = dev_get_drvdata(dev); + if (isp_dev->isp_ver == ISP_V12 || isp_dev->isp_ver == ISP_V13) { + if (isp_dev->mipi_irq >= 0) + disable_irq(isp_dev->mipi_irq); + } rkisp1_disable_sys_clk(isp_dev); return pinctrl_pm_select_sleep_state(dev); } @@ -1152,6 +1163,14 @@ static int __maybe_unused rkisp1_runtime_resume(struct device *dev) return ret; rkisp1_enable_sys_clk(isp_dev); + if (isp_dev->isp_ver == ISP_V12 || isp_dev->isp_ver == ISP_V13) { + writel(0, isp_dev->base_addr + CIF_ISP_CSI0_MASK1); + writel(0, isp_dev->base_addr + CIF_ISP_CSI0_MASK2); + writel(0, isp_dev->base_addr + CIF_ISP_CSI0_MASK3); + if (isp_dev->mipi_irq >= 0) + enable_irq(isp_dev->mipi_irq); + } + return 0; } diff --git a/drivers/media/platform/rockchip/isp1/dev.h b/drivers/media/platform/rockchip/isp1/dev.h index 66e585f1d7af..e83e5803e225 100644 --- a/drivers/media/platform/rockchip/isp1/dev.h +++ b/drivers/media/platform/rockchip/isp1/dev.h @@ -159,6 +159,7 @@ struct rkisp1_device { unsigned int emd_vc; unsigned int emd_dt; int vs_irq; + int mipi_irq; struct gpio_desc *vs_irq_gpio; struct v4l2_subdev *hdr_sensor; enum rkisp1_isp_state isp_state;