Video drivers request submodules using a work during probe and calls
flush_scheduled_work() on exit to make sure the work is complete
before being unloaded. This patch makes these drivers flush the work
directly instead of using flush_scheduled_work().
While at it, relocate request_submodules() call in saa7134_initdev()
right right before successful return as in other drivers to avoid
failing after the work is scheduled and returning failure without the
work still active.
This is in preparation for the deprecation of flush_scheduled_work().
Signed-off-by: Tejun Heo <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
INIT_WORK(&dev->request_module_wk, request_module_async);
schedule_work(&dev->request_module_wk);
}
+
+static void flush_request_modules(struct bttv *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
#else
#define request_modules(dev)
+#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */
if (bttv_verbose)
printk("bttv%d: unloading\n",btv->c.nr);
+ if (bttv_tvcards[btv->c.type].has_dvb)
+ flush_request_modules(btv);
+
/* shutdown everything (DMA+IRQs) */
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(0, BT848_INT_MASK);
INIT_WORK(&dev->request_module_wk, request_module_async);
schedule_work(&dev->request_module_wk);
}
+
+static void flush_request_modules(struct cx18 *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
#else
#define request_modules(dev)
+#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */
/* Generic utility functions */
CX18_DEBUG_INFO("Removing Card\n");
+ flush_request_modules(cx);
+
/* Stop all captures */
CX18_DEBUG_INFO("Stopping all streams\n");
if (atomic_read(&cx->tot_capturing) > 0)
INIT_WORK(&dev->request_module_wk, request_module_async);
schedule_work(&dev->request_module_wk);
}
+
+static void flush_request_modules(struct cx231xx *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
#else
#define request_modules(dev)
+#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */
/*
if (!dev->udev)
return;
+ flush_request_modules(dev);
+
/* delete v4l2 device */
v4l2_device_unregister(&dev->v4l2_dev);
INIT_WORK(&dev->request_module_wk, request_module_async);
schedule_work(&dev->request_module_wk);
}
+
+static void flush_request_modules(struct cx8802_dev *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
#else
#define request_modules(dev)
+#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */
dprintk( 1, "%s\n", __func__);
+ flush_request_modules(dev);
+
if (!list_empty(&dev->drvlist)) {
struct cx8802_driver *drv, *tmp;
int err;
INIT_WORK(&dev->request_module_wk, request_module_async);
schedule_work(&dev->request_module_wk);
}
+
+static void flush_request_modules(struct em28xx *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
#else
#define request_modules(dev)
+#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */
/*
em28xx_info("disconnecting %s\n", dev->vdev->name);
+ flush_request_modules(dev);
+
/* wait until all current v4l2 io is finished then deallocate
resources */
mutex_lock(&dev->lock);
schedule_work(&dev->request_module_wk);
}
+static void flush_request_submodules(struct saa7134_dev *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
+
#else
#define request_submodules(dev)
+#define flush_request_submodules(dev)
#endif /* CONFIG_MODULES */
/* ------------------------------------------------------------------ */
}
}
- request_submodules(dev);
-
v4l2_prio_init(&dev->prio);
mutex_lock(&saa7134_devlist_lock);
if (saa7134_dmasound_init && !dev->dmasound.priv_data)
saa7134_dmasound_init(dev);
+ request_submodules(dev);
return 0;
fail4:
struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
struct saa7134_mpeg_ops *mops;
+ flush_request_submodules(dev);
+
/* Release DMA sound modules if present */
if (saa7134_dmasound_exit && dev->dmasound.priv_data) {
saa7134_dmasound_exit(dev);