On Thu Dec 4 17:41:53 2025 +0800, Xulin Sun wrote:
> Move video device unregistration to the beginning of the remove function
> to ensure all video operations are stopped before cleaning up the worker
> thread and disabling PM runtime. This prevents hardware register access
> after the device has been powered down.
> 
> In polling mode, the hrtimer periodically triggers
> wave5_vpu_timer_callback() which queues work to the kthread worker.
> The worker executes wave5_vpu_irq_work_fn() which reads hardware
> registers via wave5_vdi_read_register().
> 
> The original cleanup order disabled PM runtime and powered down hardware
> before unregistering video devices. When autosuspend triggers and powers
> off the hardware, the video devices are still registered and the worker
> thread can still be triggered by the hrtimer, causing it to attempt
> reading registers from powered-off hardware. This results in a bus error
> (synchronous external abort) and kernel panic.
> 
> This causes random kernel panics during encoding operations:
> 
>   Internal error: synchronous external abort: 0000000096000010
>     [#1] PREEMPT SMP
>   Modules linked in: wave5 rpmsg_ctrl rpmsg_char ...
>   CPU: 0 UID: 0 PID: 1520 Comm: vpu_irq_thread
>     Tainted: G   M    W
>   pc : wave5_vdi_read_register+0x10/0x38 [wave5]
>   lr : wave5_vpu_irq_work_fn+0x28/0x60 [wave5]
>   Call trace:
>    wave5_vdi_read_register+0x10/0x38 [wave5]
>    kthread_worker_fn+0xd8/0x238
>    kthread+0x104/0x120
>    ret_from_fork+0x10/0x20
>   Code: aa1e03e9 d503201f f9416800 8b214000 (b9400000)
>   ---[ end trace 0000000000000000 ]---
>   Kernel panic - not syncing: synchronous external abort:
>     Fatal exception
> 
> Fixes: 9707a6254a8a ("media: chips-media: wave5: Add the v4l2 layer")
> Cc: [email protected]
> Signed-off-by: Xulin Sun <[email protected]>
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/chips-media/wave5/wave5-vpu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

---

diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c 
b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
index 0bcd48df49d0..77d6c934d0b9 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
@@ -351,6 +351,10 @@ static void wave5_vpu_remove(struct platform_device *pdev)
 {
        struct vpu_device *dev = dev_get_drvdata(&pdev->dev);
 
+       wave5_vpu_enc_unregister_device(dev);
+       wave5_vpu_dec_unregister_device(dev);
+       v4l2_device_unregister(&dev->v4l2_dev);
+
        if (dev->irq < 0) {
                hrtimer_cancel(&dev->hrtimer);
                kthread_cancel_work_sync(&dev->work);
@@ -364,9 +368,6 @@ static void wave5_vpu_remove(struct platform_device *pdev)
        mutex_destroy(&dev->hw_lock);
        reset_control_assert(dev->resets);
        clk_bulk_disable_unprepare(dev->num_clks, dev->clks);
-       wave5_vpu_enc_unregister_device(dev);
-       wave5_vpu_dec_unregister_device(dev);
-       v4l2_device_unregister(&dev->v4l2_dev);
        wave5_vdi_release(&pdev->dev);
        ida_destroy(&dev->inst_ida);
 }
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to