[PATCH] media: aspeed: acquire IRQ after reset and clock resources
Myeonghun Pak
mhun512 at gmail.com
Thu Oct 15 18:20:08 PDT 2026
The threaded IRQ uses the reset and clock resources, but it is
registered before those managed handles are acquired. Reverse devres
cleanup can release the handles before the IRQ action has been removed
and joined.
On a resolution-change interrupt, aspeed_video_irq() calls
aspeed_video_irq_res_change(), which invokes aspeed_video_reset() and
accesses video->reset through reset_control_assert() and
reset_control_deassert().
Request the IRQ after reset, clock and JPEG-table initialization so
managed IRQ release precedes release of those handles. Add rollback for
the JPEG allocation, reserved-memory association and prepared clocks if
the later IRQ request fails.
This issue was identified as part of our ongoing research while
reviewing kernel code.
Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver")
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000 at gmail.com>
Signed-off-by: Ijae Kim <ae878000 at gmail.com>
Signed-off-by: Myeonghun Pak <mhun512 at gmail.com>
---
This fixes managed handle lifetime only.
Compile-tested with Clang 22.1.2, W=1. No runtime or hardware testing.
Base: 0fcb05b72344f40806cbe810de8872f1698bf053
drivers/media/platform/aspeed/aspeed-video.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/aspeed/aspeed-video.c b/drivers/media/platform/aspeed/aspeed-video.c
index a292275f6b7b..234001a93ad4 100644
--- a/drivers/media/platform/aspeed/aspeed-video.c
+++ b/drivers/media/platform/aspeed/aspeed-video.c
@@ -2232,14 +2232,6 @@ static int aspeed_video_init(struct aspeed_video *video)
return -ENODEV;
}
- rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
- IRQF_ONESHOT, DEVICE_NAME, video);
- if (rc < 0) {
- dev_err(dev, "Unable to request IRQ %d\n", irq);
- return rc;
- }
- dev_info(video->dev, "irq %d\n", irq);
-
video->reset = devm_reset_control_get(dev, NULL);
if (IS_ERR(video->reset)) {
dev_err(dev, "Unable to get reset\n");
@@ -2286,8 +2278,19 @@ static int aspeed_video_init(struct aspeed_video *video)
aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
+ /* Release the IRQ before the reset and clock handles on devres unwind. */
+ rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
+ IRQF_ONESHOT, DEVICE_NAME, video);
+ if (rc < 0) {
+ dev_err(dev, "Unable to request IRQ %d\n", irq);
+ goto err_free_jpeg;
+ }
+ dev_info(video->dev, "irq %d\n", irq);
+
return 0;
+err_free_jpeg:
+ aspeed_video_free_buf(video, &video->jpeg);
err_release_reserved_mem:
of_reserved_mem_device_release(dev);
clk_unprepare(video->vclk);
More information about the linux-arm-kernel
mailing list