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]