From aaaa072ed1df70209b4691c22c71c0ee3897c181 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 | 16 ++++++++++++++++ drivers/media/platform/rockchip/isp1/dev.h | 1 + 2 files changed, 17 insertions(+) diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c index 8bfd9c37cace..a9c99d230844 100644 --- a/drivers/media/platform/rockchip/isp1/dev.c +++ b/drivers/media/platform/rockchip/isp1/dev.c @@ -1127,6 +1127,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) { @@ -1140,6 +1141,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, @@ -1296,6 +1300,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); } @@ -1310,6 +1318,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 632821e4e569..fc82fb6de18c 100644 --- a/drivers/media/platform/rockchip/isp1/dev.h +++ b/drivers/media/platform/rockchip/isp1/dev.h @@ -161,6 +161,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;