[PATCH] media: vivid: initialize control update work items early

From: Hyeonjun Hong

Date: Wed Sep 16 2026 - 11:20:59 EST


vivid_create_instance() installs the v4l2_device release callback long
before it initializes the update_hdmi_ctrl_work and update_svid_ctrl_work
items. If any of the error paths in between is taken, dropping the last
v4l2_device reference calls vivid_dev_release(), which cancels both work
items while their work->func is still NULL. __flush_work() then trips
WARN_ON(!work->func) and taints the kernel.

Reproduced by asking for an HDMI input while disabling both the video
and the metadata capture nodes, which vivid_detect_feature_set() rejects
with -EINVAL:

$ modprobe vivid node_types=0xc1d3c

WARNING: kernel/workqueue.c:4400 at __flush_work+0x9a7/0xc20
cancel_work_sync+0x90/0xc0
vivid_dev_release+0x1e/0x170 [vivid]
v4l2_device_put+0x80/0xb0
vivid_probe+0x257c/0xa3e0 [vivid]

Two such warnings are printed, one per work item.

Initialize both work items right after the vivid_dev structure is
allocated, so that vivid_dev_release() can cancel them from any error
path.

Fixes: d7c969f37515 ("media: vivid: Add 'Is Connected To' menu controls")
Assisted-by: LLM
Signed-off-by: Hyeonjun Hong <hyeonjunhong330@xxxxxxxxx>
---
drivers/media/test-drivers/vivid/vivid-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
index c042d92db175..ea0b5ae6f437 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.c
+++ b/drivers/media/test-drivers/vivid/vivid-core.c
@@ -1820,6 +1820,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
return -ENOMEM;

dev->inst = inst;
+ INIT_WORK(&dev->update_hdmi_ctrl_work, update_hdmi_ctrls_work_handler);
+ INIT_WORK(&dev->update_svid_ctrl_work, update_svid_ctrls_work_handler);

#ifdef CONFIG_MEDIA_CONTROLLER
dev->v4l2_dev.mdev = &dev->mdev;
@@ -1913,8 +1915,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
dev->edid_max_blocks = dev->edid_blocks = 2;
memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
dev->radio_rds_init_time = ktime_get();
- INIT_WORK(&dev->update_hdmi_ctrl_work, update_hdmi_ctrls_work_handler);
- INIT_WORK(&dev->update_svid_ctrl_work, update_svid_ctrls_work_handler);
for (int j = 0, k = 0; j < dev->num_inputs; ++j)
if (dev->input_type[j] == HDMI)
dev->hdmi_index_to_input_index[k++] = j;
--
2.34.1