diff options
-rw-r--r-- | drivers/media/video/cx18/cx18-alsa-main.c | 38 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 34 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 6 |
3 files changed, 46 insertions, 32 deletions
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c index 3c339774522a..6433ff0ad859 100644 --- a/drivers/media/video/cx18/cx18-alsa-main.c +++ b/drivers/media/video/cx18/cx18-alsa-main.c @@ -190,11 +190,9 @@ err_exit: return ret; } -static int __init cx18_alsa_init_callback(struct device *dev, void *data) +int cx18_alsa_load(struct cx18 *cx) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); - int *count = data; - struct cx18 *cx; + struct v4l2_device *v4l2_dev = &cx->v4l2_dev; struct cx18_stream *s; if (v4l2_dev == NULL) { @@ -227,41 +225,16 @@ static int __init cx18_alsa_init_callback(struct device *dev, void *data) __func__); } else { CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance " - "%d\n", __func__, *count); - (*count)++; + "\n", __func__); } return 0; } static int __init cx18_alsa_init(void) { - struct device_driver *drv; - int count = 0; - int ret; - printk(KERN_INFO "cx18-alsa: module loading...\n"); - - drv = driver_find("cx18", &pci_bus_type); - if (drv == NULL) { - printk("cx18-alsa: drv was null\n"); - return -ENODEV; - } - ret = driver_for_each_device(drv, NULL, &count, - cx18_alsa_init_callback); - put_driver(drv); - - if (count == 0) { - printk(KERN_ERR "cx18-alsa: no cx18 cards found with a PCM " - "capture stream allocated\n"); - ret = -ENODEV; - } else { - printk(KERN_INFO "cx18-alsa: ALSA interface(s) created for %d " - "cx18 card(s)\n", count); - ret = 0; - } - - printk(KERN_INFO "cx18-alsa: module load complete\n"); - return ret; + cx18_ext_init = &cx18_alsa_load; + return 0; } static void snd_cx18_exit(struct snd_cx18_card *cxsc) @@ -308,6 +281,7 @@ static void cx18_alsa_exit(void) ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); put_driver(drv); + cx18_ext_init = NULL; printk(KERN_INFO "cx18-alsa: module unload complete\n"); } 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", diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 22634cf6a96a..23ad6d548dc5 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -637,6 +637,9 @@ struct cx18 { u32 active_input; v4l2_std_id std; v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ + + /* Used for cx18-alsa module loading */ + struct work_struct request_module_wk; }; static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) @@ -644,6 +647,9 @@ static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) return container_of(v4l2_dev, struct cx18, v4l2_dev); } +/* cx18 extensions to be loaded */ +extern int (*cx18_ext_init)(struct cx18 *); + /* Globals */ extern int cx18_first_minor; |