Commit cfb320d9 authored by Stefan Wahren's avatar Stefan Wahren Committed by Greg Kroah-Hartman
Browse files

staging: vchiq_arm: Stop kthreads if vchiq cdev register fails



In case the vchiq character device cannot be registered during probe,
all kthreads needs to be stopped to avoid resource leaks.

Fixes: 863a756a ("staging: vc04_services: vchiq_core: Stop kthreads on vchiq module unload")
Signed-off-by: default avatarStefan Wahren <wahrenst@gmx.net>
Link: https://lore.kernel.org/r/20250309125014.37166-4-wahrenst@gmx.net


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3db89bc6
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -308,6 +308,20 @@ static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *
	return (struct vchiq_arm_state *)state->platform_state;
}

static void
vchiq_platform_uninit(struct vchiq_drv_mgmt *mgmt)
{
	struct vchiq_arm_state *arm_state;

	kthread_stop(mgmt->state.sync_thread);
	kthread_stop(mgmt->state.recycle_thread);
	kthread_stop(mgmt->state.slot_handler_thread);

	arm_state = vchiq_platform_get_arm_state(&mgmt->state);
	if (!IS_ERR_OR_NULL(arm_state->ka_thread))
		kthread_stop(arm_state->ka_thread);
}

void vchiq_dump_platform_state(struct seq_file *f)
{
	seq_puts(f, "  Platform: 2835 (VC master)\n");
@@ -1396,6 +1410,7 @@ static int vchiq_probe(struct platform_device *pdev)
	ret = vchiq_register_chrdev(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
		vchiq_platform_uninit(mgmt);
		return ret;
	}

@@ -1410,20 +1425,12 @@ static int vchiq_probe(struct platform_device *pdev)
static void vchiq_remove(struct platform_device *pdev)
{
	struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(&pdev->dev);
	struct vchiq_arm_state *arm_state;

	vchiq_device_unregister(bcm2835_audio);
	vchiq_device_unregister(bcm2835_camera);
	vchiq_debugfs_deinit();
	vchiq_deregister_chrdev();

	kthread_stop(mgmt->state.sync_thread);
	kthread_stop(mgmt->state.recycle_thread);
	kthread_stop(mgmt->state.slot_handler_thread);

	arm_state = vchiq_platform_get_arm_state(&mgmt->state);
	if (!IS_ERR_OR_NULL(arm_state->ka_thread))
		kthread_stop(arm_state->ka_thread);
	vchiq_platform_uninit(mgmt);
}

static struct platform_driver vchiq_driver = {