From patchwork Tue Dec 5 08:09:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 750593 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EbFcLUbf" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D58ED124; Tue, 5 Dec 2023 00:10:06 -0800 (PST) Received: from [127.0.1.1] (91-158-149-209.elisa-laajakaista.fi [91.158.149.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 320D4A06; Tue, 5 Dec 2023 09:09:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1701763764; bh=1DkaPRB62rbwVz1efQTvY0qAzOElI3EW4hHk1yOlrto=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EbFcLUbfyoORI145e9Ncnuhw2Rx35qlgXqbipmVdpnWEWL5UY2xsnrPhx4eao2C4K AV08AuQXuTi5yXrpsli5u9X8rDkM3yYGjoiTvTT6XUTfctOGz2FfN9p2MOPmbCq/gi AhC2gyw1Er9I8Z/9T0xv5apIQmC2sopo9sY7w3zw= From: Tomi Valkeinen Date: Tue, 05 Dec 2023 10:09:32 +0200 Subject: [PATCH 1/4] media: rkisp1: Store IRQ lines Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231205-rkisp-irq-fix-v1-1-f4045c74ba45@ideasonboard.com> References: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> In-Reply-To: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> To: Dafna Hirschfeld , Laurent Pinchart , Mauro Carvalho Chehab , Heiko Stuebner , Paul Elder Cc: Alexander Stein , kieran.bingham@ideasonboard.com, umang.jain@ideasonboard.com, aford173@gmail.com, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Tomi Valkeinen X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=4221; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=1DkaPRB62rbwVz1efQTvY0qAzOElI3EW4hHk1yOlrto=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBlbtrY21tIgI6aHdBw7pS6gbN26PjpLU5dAJSUy WZaxcFQhEuJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZW7a2AAKCRD6PaqMvJYe 9ctUD/0U3inIQmzSNkB1t1NWxNhxajVV0i+6StgEoo97hCnE0xX6DJLLv+7sllwOh3EANrpte6E X/qvXh5jeAK/Sa//aNRy9hIeB9VL1N7lMCmcAhmYxFxpxXEx7D4FkAX1QMZSxsDkbdZylZHLlsJ twIsPho5MU/anu/nbLnuNJMZNrEyJaV/nhK4fepQB6L8z7RLI5vg/AIx1bqqSf3zw6Dry2juz0x bSMfD6e3/EuMMq5UCmaB25WWMCjZm7mPBV3KBPwP/so9cU7p8nrCkndGyXiZuK/NFSU+4jQjB9s PGGFyHg4No071VuHDBULCe/V5Euqkz86iD+wCsu7G6xUyLEE28eGNvtN4iGUbDjSIQnRy8WbR13 qa/0pTl30Scl+ByQHxVI6DacAJ6xrX4XVF1D0ym2ux16ftRquQu4bHxFQqLaKVILBYsZItvIrlP ZyFEMcJEpOBOxKgTJJoqMbJnWaYXwnR6C8gRcNGqvHmBTf+jdgqZnuOsuLW03w2MUqnr63oK5cX 0KAtbdqi1uj8Vj2ereqFt6/eEgfqKug4hrxPiLHPtWpksk31hyTGh3B9oPFSI0eM5xCArNxEXjL HSuf+aZixgMu7lX+H21mo3p5ijKKZTAFRh/BRrCsQ3IyraGIGvUqFHa+GhoruHYELX9nz3fbqzH ueVSB2qflbNIy3g== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 Store the IRQ lines used by the driver for easy access. These are needed in future patches which fix IRQ race issues. Signed-off-by: Tomi Valkeinen --- .../media/platform/rockchip/rkisp1/rkisp1-common.h | 11 ++++++++++- drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 19 ++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index 960ab89c659b..ec28907d978e 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -62,6 +62,14 @@ struct regmap; RKISP1_CIF_ISP_EXP_END | \ RKISP1_CIF_ISP_HIST_MEASURE_RDY) +/* IRQ lines */ +enum rkisp1_irq_line { + RKISP1_IRQ_ISP = 0, + RKISP1_IRQ_MI, + RKISP1_IRQ_MIPI, + RKISP1_NUM_IRQS, +}; + /* enum for the resizer pads */ enum rkisp1_rsz_pad { RKISP1_RSZ_PAD_SINK, @@ -437,7 +445,6 @@ struct rkisp1_debug { * struct rkisp1_device - ISP platform device * * @base_addr: base register address - * @irq: the irq number * @dev: a pointer to the struct device * @clk_size: number of clocks * @clks: array of clocks @@ -457,6 +464,7 @@ struct rkisp1_debug { * @stream_lock: serializes {start/stop}_streaming callbacks between the capture devices. * @debug: debug params to be exposed on debugfs * @info: version-specific ISP information + * @irqs: IRQ line numbers */ struct rkisp1_device { void __iomem *base_addr; @@ -479,6 +487,7 @@ struct rkisp1_device { struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */ struct rkisp1_debug debug; const struct rkisp1_info *info; + int irqs[RKISP1_NUM_IRQS]; }; /* diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 2b9886fd0800..76f93614b4cf 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -115,6 +115,7 @@ struct rkisp1_isr_data { const char *name; irqreturn_t (*isr)(int irq, void *ctx); + u32 line_mask; }; /* ---------------------------------------------------------------------------- @@ -465,9 +466,9 @@ static const char * const px30_isp_clks[] = { }; static const struct rkisp1_isr_data px30_isp_isrs[] = { - { "isp", rkisp1_isp_isr }, - { "mi", rkisp1_capture_isr }, - { "mipi", rkisp1_csi_isr }, + { "isp", rkisp1_isp_isr, BIT(RKISP1_IRQ_ISP) }, + { "mi", rkisp1_capture_isr, BIT(RKISP1_IRQ_MI) }, + { "mipi", rkisp1_csi_isr, BIT(RKISP1_IRQ_MIPI) }, }; static const struct rkisp1_info px30_isp_info = { @@ -488,7 +489,7 @@ static const char * const rk3399_isp_clks[] = { }; static const struct rkisp1_isr_data rk3399_isp_isrs[] = { - { NULL, rkisp1_isr }, + { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) }, }; static const struct rkisp1_info rk3399_isp_info = { @@ -509,7 +510,7 @@ static const char * const imx8mp_isp_clks[] = { }; static const struct rkisp1_isr_data imx8mp_isp_isrs[] = { - { NULL, rkisp1_isr }, + { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) }, }; static const struct rkisp1_info imx8mp_isp_info = { @@ -566,6 +567,9 @@ static int rkisp1_probe(struct platform_device *pdev) if (IS_ERR(rkisp1->base_addr)) return PTR_ERR(rkisp1->base_addr); + for (unsigned int il = 0; il < RKISP1_NUM_IRQS; ++il) + rkisp1->irqs[il] = -1; + for (i = 0; i < info->isr_size; i++) { irq = info->isrs[i].name ? platform_get_irq_byname(pdev, info->isrs[i].name) @@ -573,6 +577,11 @@ static int rkisp1_probe(struct platform_device *pdev) if (irq < 0) return irq; + for (unsigned int il = 0; il < RKISP1_NUM_IRQS; ++il) { + if (info->isrs[i].line_mask & BIT(il)) + rkisp1->irqs[il] = irq; + } + ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED, dev_driver_string(dev), dev); if (ret) { From patchwork Tue Dec 5 08:09:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 751974 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="PnaOPacs" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C15AA127; Tue, 5 Dec 2023 00:10:07 -0800 (PST) Received: from [127.0.1.1] (91-158-149-209.elisa-laajakaista.fi [91.158.149.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2FF0CEEE; Tue, 5 Dec 2023 09:09:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1701763764; bh=WNFwBf6lfujD0ZQ+VOP/UJchIYnz0NMJp9HloMbZytA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PnaOPacsNt55CsSxBteS0KdXjZuHHlLbjuZw2U3XpRZbabFJD3MEq1VFag4cIAX0a G+DyM175on5WDyMg4NpXol3r2XHfXQO7jcaH2w8f/wEZhrPo/utPUtbZ7HbU6EUCsm YRpjZvs+dlf4TcgalR58edCgbVZG5D86YwSQPKRI= From: Tomi Valkeinen Date: Tue, 05 Dec 2023 10:09:33 +0200 Subject: [PATCH 2/4] media: rkisp1: Fix IRQ handler return values Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231205-rkisp-irq-fix-v1-2-f4045c74ba45@ideasonboard.com> References: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> In-Reply-To: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> To: Dafna Hirschfeld , Laurent Pinchart , Mauro Carvalho Chehab , Heiko Stuebner , Paul Elder Cc: Alexander Stein , kieran.bingham@ideasonboard.com, umang.jain@ideasonboard.com, aford173@gmail.com, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Tomi Valkeinen X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=1603; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=WNFwBf6lfujD0ZQ+VOP/UJchIYnz0NMJp9HloMbZytA=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBlbtrYHUyIcw9QFvbFkSIrfTb+8f/fz4Git+i/W 6Gu5IM4MJqJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZW7a2AAKCRD6PaqMvJYe 9dKSEACJtMy5hagG9Dgbka6/kKGcekwuWk4WVA+I0YyWHK3zz6ryIxYta3z/0swDdSIz7cAg58m af6c5kr2Mi5CgLYgh4sokjBBQOaX3AFIz0rGSxz2J/KFdQZOz4Yq9BBciF8qQBpetAIzDgcxgkq nEGmykPUCKesFrjk1gQOFIlq4EMbg0yfIuCs6E0Bc52Mu0yEy+91sgiCqwX76AOS62xaPUMVndJ vQB/A//jHQxdn5zeNtoUYlXcnpl7BT5CBQcIaEUTiMSCS29PZvBZ/kqmyFXQ4MasjBkBDGrHB6D GFc7xbsYYzqTn+tzg8Jcw7fZEPKoDV6Dg3eTo0biDVSCyu4l8CRFODZU+LcvXj+I7RmAJNOVgw+ qGbCKH1iE/IbygRVFS3nWQuKIp4rO0JjTBH8fbspQifIsjuk0DYeJj4DzqlpmnWbvNbobfc/kzq lxrCrLrEm7EJgaOx3Ww4iaE0XoFKzkkGx7TnBoX79ywepqARu6EWgb6ejdkd5rhhGn5aAPdVAH0 j7J6QM0mH41FwAky6Gzu5AjCwhUndC3p6zZy2wUQB4VW4zG9acoueE3xuXB3IUABBVELQeBs37v ZNaCMzxlAg4v/GpDtZTDoREqphZKSmtjvxSOQwNgdNH44JI2UPvm7xvK6THnIAQ49HuRYw6XYTS SfnS5jlZ1/b/xAQ== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 The IRQ handler rkisp1_isr() calls sub-handlers, all of which returns an irqreturn_t value, but rkisp1_isr() ignores those values and always returns IRQ_HANDLED. Fix this by collecting the return values, and returning IRQ_HANDLED or IRQ_NONE as appropriate. Signed-off-by: Tomi Valkeinen --- drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 76f93614b4cf..1d60f4b8bd09 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -445,17 +445,27 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1) static irqreturn_t rkisp1_isr(int irq, void *ctx) { + irqreturn_t ret; + /* * Call rkisp1_capture_isr() first to handle the frame that * potentially completed using the current frame_sequence number before * it is potentially incremented by rkisp1_isp_isr() in the vertical * sync. */ - rkisp1_capture_isr(irq, ctx); - rkisp1_isp_isr(irq, ctx); - rkisp1_csi_isr(irq, ctx); - return IRQ_HANDLED; + ret = IRQ_NONE; + + if (rkisp1_capture_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + if (rkisp1_isp_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + if (rkisp1_csi_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + return ret; } static const char * const px30_isp_clks[] = { From patchwork Tue Dec 5 08:09:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 750592 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="T2B8z+EF" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 199FFD3; Tue, 5 Dec 2023 00:10:09 -0800 (PST) Received: from [127.0.1.1] (91-158-149-209.elisa-laajakaista.fi [91.158.149.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 243E31010; Tue, 5 Dec 2023 09:09:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1701763765; bh=mZtjLUcwPurRjWrqxlSCj4xDyOLWjQrMwEJHqEedGrc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=T2B8z+EFK7yLMReLZkqX9uLlblAixwWFtW4w9OrUtqDvnIfnZV28/DB3CAz3fRJPM sDpUXFmHqK4sK6+zKXch5KJE1mZSLXmMaEI1NcnsP9PePDIOqzP2ZpkaRIa6XILfGv 5QqCugz8PlXWX2F8ueVztEMk5bYQKK38SVtYbquQ= From: Tomi Valkeinen Date: Tue, 05 Dec 2023 10:09:34 +0200 Subject: [PATCH 3/4] media: rkisp1: Fix IRQ handling due to shared interrupts Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231205-rkisp-irq-fix-v1-3-f4045c74ba45@ideasonboard.com> References: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> In-Reply-To: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> To: Dafna Hirschfeld , Laurent Pinchart , Mauro Carvalho Chehab , Heiko Stuebner , Paul Elder Cc: Alexander Stein , kieran.bingham@ideasonboard.com, umang.jain@ideasonboard.com, aford173@gmail.com, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Tomi Valkeinen X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=4620; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=mZtjLUcwPurRjWrqxlSCj4xDyOLWjQrMwEJHqEedGrc=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBlbtrY0ag5xyx3Lvv6lltmY2X9cTNDItBEJueE1 /dtr4OCXaCJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZW7a2AAKCRD6PaqMvJYe 9QsvD/wKjXWKvhIraBeIDihoS0XIIVMphsqF9AQl4NGzoX0MehHO9SgTNjNmA95+ILO2R6MMuHx vXG7j3tLwF1O0WOjQzRXl2p9DHvtsySnQFHlSp8SEx0DXoVWwRbRGQ92tF6kYnQOUXeznJQOnG4 idNHblxE3f7pfvwLmkpWTDfHVfKRJN76QNAt+pVEFCSTB+DtB2TBWXGrBazlPRBW0hbx414AmYA wI41GEvlDfpoACZxYjaKpb+/4UruMRASpZOd3Ksg4E92AFDNB+4RcecVwb4DTeFHX1m4JinRnlG t9S3D+AJS0qZg9ECDt3S3Fv4DAL4vuHModMlHZ/hPp4GGC9kVtqTMZUY4NMslb4uTpt/q0Tif1y Bth3uhcsXEb6XQ+P+mqBI8l88Z/RZffcH1i7DhH81oEtU0qORJpnEj8To8x4Va44Uj4Ai0vC3Z2 OpMebdT+709zFSwVkUokuQUkSZ1I0ZRZ6NaycdrjCpR6/cuXE2bjcHdXq5UuuyOnUJpiDnAG3R2 +AXqoxw0Zv9+rbSUEPOPtvJIbteqela88/Dao13K6GeJMLJTO5J6yNZC4+UrqN6zB1/w49H3dTB IUdwVTItp2jXk9prOm5FI7nFB/ujHNuruPx8svnd/huQPuuJAM6AnxSYSah7DaZsTdn/+UuXWnV 558PKJn7Z9WAgVg== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 The driver requests the interrupts as IRQF_SHARED, so the interrupt handlers can be called at any time. If such a call happens while the ISP is powered down, the SoC will hang as the driver tries to access the ISP registers. Fix this by adding a new field, 'irqs_enabled', which is used to bail out from the interrupt handler when the ISP is not operational. Signed-off-by: Tomi Valkeinen --- .../media/platform/rockchip/rkisp1/rkisp1-capture.c | 3 +++ .../media/platform/rockchip/rkisp1/rkisp1-common.h | 2 ++ drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c | 3 +++ drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 21 +++++++++++++++++++++ drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c | 3 +++ 5 files changed, 32 insertions(+) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index b50b044d22af..e92067897f28 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c @@ -779,6 +779,9 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx) unsigned int i; u32 status; + if (!rkisp1->irqs_enabled) + return IRQ_NONE; + status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS); if (!status) return IRQ_NONE; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index ec28907d978e..7f97fdf6e24c 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -465,6 +465,7 @@ struct rkisp1_debug { * @debug: debug params to be exposed on debugfs * @info: version-specific ISP information * @irqs: IRQ line numbers + * @irqs_enabled: the hardware is enabled and can cause interrupts */ struct rkisp1_device { void __iomem *base_addr; @@ -488,6 +489,7 @@ struct rkisp1_device { struct rkisp1_debug debug; const struct rkisp1_info *info; int irqs[RKISP1_NUM_IRQS]; + bool irqs_enabled; }; /* diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c index 47f4353a1784..f6b54654b435 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c @@ -184,6 +184,9 @@ irqreturn_t rkisp1_csi_isr(int irq, void *ctx) struct rkisp1_device *rkisp1 = dev_get_drvdata(dev); u32 val, status; + if (!rkisp1->irqs_enabled) + return IRQ_NONE; + status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS); if (!status) return IRQ_NONE; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 1d60f4b8bd09..fbe03f7864e3 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -306,6 +306,23 @@ static int __maybe_unused rkisp1_runtime_suspend(struct device *dev) { struct rkisp1_device *rkisp1 = dev_get_drvdata(dev); + rkisp1->irqs_enabled = false; + /* Make sure the IRQ handler will see the above */ + mb(); + + /* + * Wait until any running IRQ handler has returned. The IRQ handler + * may get called even after this (as it's a shared interrupt line) + * but the 'irqs_enabled' flag will make the handler return immediately. + */ + for (unsigned int i = 0; i < RKISP1_NUM_IRQS; ++i) { + if (rkisp1->irqs[i] == -1) + continue; + + if (i == 0 || rkisp1->irqs[i - 1] != rkisp1->irqs[i]) + synchronize_irq(rkisp1->irqs[i]); + } + clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks); return pinctrl_pm_select_sleep_state(dev); } @@ -322,6 +339,10 @@ static int __maybe_unused rkisp1_runtime_resume(struct device *dev) if (ret) return ret; + rkisp1->irqs_enabled = true; + /* Make sure the IRQ handler will see the above */ + mb(); + return 0; } diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c index dafbfd230542..d6b8786661ad 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -1082,6 +1082,9 @@ irqreturn_t rkisp1_isp_isr(int irq, void *ctx) struct rkisp1_device *rkisp1 = dev_get_drvdata(dev); u32 status, isp_err; + if (!rkisp1->irqs_enabled) + return IRQ_NONE; + status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS); if (!status) return IRQ_NONE; From patchwork Tue Dec 5 08:09:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 751973 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="MuUU0XQX" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E26CC11F; Tue, 5 Dec 2023 00:10:09 -0800 (PST) Received: from [127.0.1.1] (91-158-149-209.elisa-laajakaista.fi [91.158.149.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 21D0B158D; Tue, 5 Dec 2023 09:09:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1701763766; bh=rVmPtwm1uGmDrIWKXT2svm/MUUgksqxTNOdoxtoMjGU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MuUU0XQXq6ZXG66dOeIgSjJveT/+bR/YLt/ymW2upTL3owTAskGnfjTO/vYsO7QPL 16zakRN2AQ+QS8PFU6CSOLnFEmmY/pfkHl9LXGZICRZ4V37I0T/3WAsE3RTucbTC3t 9487GO8l/Jh18OrjAFpZx08TGj6KD5NSBdOvJvk8= From: Tomi Valkeinen Date: Tue, 05 Dec 2023 10:09:35 +0200 Subject: [PATCH 4/4] media: rkisp1: Fix IRQ disable race issue Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231205-rkisp-irq-fix-v1-4-f4045c74ba45@ideasonboard.com> References: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> In-Reply-To: <20231205-rkisp-irq-fix-v1-0-f4045c74ba45@ideasonboard.com> To: Dafna Hirschfeld , Laurent Pinchart , Mauro Carvalho Chehab , Heiko Stuebner , Paul Elder Cc: Alexander Stein , kieran.bingham@ideasonboard.com, umang.jain@ideasonboard.com, aford173@gmail.com, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Tomi Valkeinen X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=3150; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=rVmPtwm1uGmDrIWKXT2svm/MUUgksqxTNOdoxtoMjGU=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBlbtrZU6iFL2/Y58GR7rOJhBlQDCvuGEErOgG0X XlZATZxLJKJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZW7a2QAKCRD6PaqMvJYe 9Tm4D/9Sq2B3VjwaBr6L8KhLLf2C7zg40sLxpalB/S4jSwZguMCWNTiEuqknm/LXBBOh5HG8GEp VLyFyIn0NvXtVvxyOLYf3hlux+YjGoZABwQps827/TlJs9Egyf1D+X7EYwfdgguuePOeDp3H2z2 YhBzLAdIaJ2le4cmk89cow16VtWuoKgjo8fcM5edz72sV/8/NM7pqQJ+5PZMZD1wWs0fsH0+GHE wROiwZB8Kj9QLf9P6GLlOymwP1rqmVhTf8BOIHeYaxxlbQrS8AdHNw7pZ0aDkx+7kVS4BnOxemi BdJekPp9Xj+k8AEHQmouZ77wMZxBUuYg1vKSoKJwMFC4TR+TM97Q5gPcb6gCE3BkqRUBlZ/3Mv8 kGEZhc2cQRU3BXeoUsnPbI/Qlu31jlz9LGE9Ws15h/mTdP+uNiPDgHwYCNPQpL+zshEbeIqOTTR FZ9P572LCytqw/V2qlI2r5EnDyJ37Hi1X5nzzL88/Js1tCL/OIQf9/XMpjtKsCYxFZqu97PmIRE TTYyugTXYCWiFCrYC380+wIgU37svswllDUwCv6y2bLxisA7BXPSWLP3d2RUd7vlisv5jlGQ+l/ XnRzAgi2gBVOk2u5qvZ8LXR+t6sqGzO6p6EuZjheclWTre0ek9cM/Irob4PCWpbaxIi8opGjYfu usRe3ZoUttSytSQ== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 In rkisp1_isp_stop() and rkisp1_csi_disable() the driver masks the interrupts and then apparently assumes that the interrupt handler won't be running, and proceeds in the stop procedure. This is not the case, as the interrupt handler can already be running, which would lead to the ISP being disabled while the interrupt handler handling a captured frame. It is not clear to me if this problem causes a real issue, but shutting down the ISP while an interrupt handler is running sounds rather bad. Signed-off-by: Tomi Valkeinen --- drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c | 14 +++++++++++++- drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c | 20 +++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c index f6b54654b435..f0cef766fc0c 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c @@ -125,8 +125,20 @@ static void rkisp1_csi_disable(struct rkisp1_csi *csi) struct rkisp1_device *rkisp1 = csi->rkisp1; u32 val; - /* Mask and clear interrupts. */ + /* Mask MIPI interrupts. */ rkisp1_write(rkisp1, RKISP1_CIF_MIPI_IMSC, 0); + + /* Flush posted writes */ + rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC); + + /* + * Wait until the IRQ handler has ended. The IRQ handler may get called + * even after this, but it will return immediately as the MIPI + * interrupts have been masked. + */ + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MIPI]); + + /* Clear MIPI interrupt status */ rkisp1_write(rkisp1, RKISP1_CIF_MIPI_ICR, ~0); val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL); diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c index d6b8786661ad..a6dd497c884c 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -364,11 +364,25 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp) * ISP(mi) stop in mi frame end -> Stop ISP(mipi) -> * Stop ISP(isp) ->wait for ISP isp off */ - /* stop and clear MI and ISP interrupts */ - rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); - rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); + /* Mask MI and ISP interrupts */ + rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); rkisp1_write(rkisp1, RKISP1_CIF_MI_IMSC, 0); + + /* Flush posted writes */ + rkisp1_read(rkisp1, RKISP1_CIF_MI_IMSC); + + /* + * Wait until the IRQ handler has ended. The IRQ handler may get called + * even after this, but it will return immediately as the MI and ISP + * interrupts have been masked. + */ + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_ISP]); + if (rkisp1->irqs[RKISP1_IRQ_ISP] != rkisp1->irqs[RKISP1_IRQ_MI]) + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MI]); + + /* Clear MI and ISP interrupt status */ + rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, ~0); /* stop ISP */