summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18/cx18-driver.c
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2009-11-20 01:15:54 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 15:10:43 -0300
commitd68b687b1e322e7325b1458d799e8234997e4ccd (patch)
tree57b63b7f8ec2505582a944df31e6139f60c9265a /drivers/media/video/cx18/cx18-driver.c
parent4a8cfe6a5c158133f57c2e8476f259366d4bdc4d (diff)
V4L/DVB: cx18: rework cx18-alsa module loading to support automatic loading
Restructure the way the module gets loaded so that it gets loaded automatically when cx18 is loaded, and make it work properly if there are multiple cards present (since the old code would only take one opportunity to connect to cx18 instances when the module first loaded). This work was sponsored by ONELAN Limited. Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.c')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 458f5f072374..870c43e6e2f9 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -47,6 +47,10 @@
setting this to 1 you ensure that radio0 is now also radio1. */
int cx18_first_minor;
+/* Callback for registering extensions */
+int (*cx18_ext_init)(struct cx18 *);
+EXPORT_SYMBOL(cx18_ext_init);
+
/* add your revision and whatnot here */
static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -243,6 +247,9 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(CX18_VERSION);
+/* Forward Declaration */
+static void request_modules(struct cx18 *dev);
+
/* Generic utility functions */
int cx18_msleep_timeout(unsigned int msecs, int intr)
{
@@ -1049,6 +1056,10 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
}
CX18_INFO("Initialized card: %s\n", cx->card_name);
+
+ /* Load cx18 submodules (cx18-alsa) */
+ request_modules(cx);
+
return 0;
free_streams:
@@ -1237,6 +1248,29 @@ static void cx18_remove(struct pci_dev *pci_dev)
kfree(cx);
}
+
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+ struct cx18 *dev=container_of(work, struct cx18, request_module_wk);
+
+ /* Make sure cx18-alsa module is loaded */
+ request_module("cx18-alsa");
+
+ /* Initialize cx18-alsa for this instance of the cx18 device */
+ if (cx18_ext_init != NULL)
+ cx18_ext_init(dev);
+}
+
+static void request_modules(struct cx18 *dev)
+{
+ INIT_WORK(&dev->request_module_wk, request_module_async);
+ schedule_work(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
/* define a pci_driver for card detection */
static struct pci_driver cx18_pci_driver = {
.name = "cx18",