aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c38
-rw-r--r--drivers/media/video/cx18/cx18-driver.c34
-rw-r--r--drivers/media/video/cx18/cx18-driver.h6
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:
190 return ret; 190 return ret;
191} 191}
192 192
193static int __init cx18_alsa_init_callback(struct device *dev, void *data) 193int cx18_alsa_load(struct cx18 *cx)
194{ 194{
195 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); 195 struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
196 int *count = data;
197 struct cx18 *cx;
198 struct cx18_stream *s; 196 struct cx18_stream *s;
199 197
200 if (v4l2_dev == NULL) { 198 if (v4l2_dev == NULL) {
@@ -227,41 +225,16 @@ static int __init cx18_alsa_init_callback(struct device *dev, void *data)
227 __func__); 225 __func__);
228 } else { 226 } else {
229 CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance " 227 CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
230 "%d\n", __func__, *count); 228 "\n", __func__);
231 (*count)++;
232 } 229 }
233 return 0; 230 return 0;
234} 231}
235 232
236static int __init cx18_alsa_init(void) 233static int __init cx18_alsa_init(void)
237{ 234{
238 struct device_driver *drv;
239 int count = 0;
240 int ret;
241
242 printk(KERN_INFO "cx18-alsa: module loading...\n"); 235 printk(KERN_INFO "cx18-alsa: module loading...\n");
243 236 cx18_ext_init = &cx18_alsa_load;
244 drv = driver_find("cx18", &pci_bus_type); 237 return 0;
245 if (drv == NULL) {
246 printk("cx18-alsa: drv was null\n");
247 return -ENODEV;
248 }
249 ret = driver_for_each_device(drv, NULL, &count,
250 cx18_alsa_init_callback);
251 put_driver(drv);
252
253 if (count == 0) {
254 printk(KERN_ERR "cx18-alsa: no cx18 cards found with a PCM "
255 "capture stream allocated\n");
256 ret = -ENODEV;
257 } else {
258 printk(KERN_INFO "cx18-alsa: ALSA interface(s) created for %d "
259 "cx18 card(s)\n", count);
260 ret = 0;
261 }
262
263 printk(KERN_INFO "cx18-alsa: module load complete\n");
264 return ret;
265} 238}
266 239
267static void snd_cx18_exit(struct snd_cx18_card *cxsc) 240static void snd_cx18_exit(struct snd_cx18_card *cxsc)
@@ -308,6 +281,7 @@ static void cx18_alsa_exit(void)
308 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); 281 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
309 put_driver(drv); 282 put_driver(drv);
310 283
284 cx18_ext_init = NULL;
311 printk(KERN_INFO "cx18-alsa: module unload complete\n"); 285 printk(KERN_INFO "cx18-alsa: module unload complete\n");
312} 286}
313 287
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 @@
47 setting this to 1 you ensure that radio0 is now also radio1. */ 47 setting this to 1 you ensure that radio0 is now also radio1. */
48int cx18_first_minor; 48int cx18_first_minor;
49 49
50/* Callback for registering extensions */
51int (*cx18_ext_init)(struct cx18 *);
52EXPORT_SYMBOL(cx18_ext_init);
53
50/* add your revision and whatnot here */ 54/* add your revision and whatnot here */
51static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 55static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
52 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 56 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -243,6 +247,9 @@ MODULE_LICENSE("GPL");
243 247
244MODULE_VERSION(CX18_VERSION); 248MODULE_VERSION(CX18_VERSION);
245 249
250/* Forward Declaration */
251static void request_modules(struct cx18 *dev);
252
246/* Generic utility functions */ 253/* Generic utility functions */
247int cx18_msleep_timeout(unsigned int msecs, int intr) 254int cx18_msleep_timeout(unsigned int msecs, int intr)
248{ 255{
@@ -1049,6 +1056,10 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1049 } 1056 }
1050 1057
1051 CX18_INFO("Initialized card: %s\n", cx->card_name); 1058 CX18_INFO("Initialized card: %s\n", cx->card_name);
1059
1060 /* Load cx18 submodules (cx18-alsa) */
1061 request_modules(cx);
1062
1052 return 0; 1063 return 0;
1053 1064
1054free_streams: 1065free_streams:
@@ -1237,6 +1248,29 @@ static void cx18_remove(struct pci_dev *pci_dev)
1237 kfree(cx); 1248 kfree(cx);
1238} 1249}
1239 1250
1251
1252#if defined(CONFIG_MODULES) && defined(MODULE)
1253static void request_module_async(struct work_struct *work)
1254{
1255 struct cx18 *dev=container_of(work, struct cx18, request_module_wk);
1256
1257 /* Make sure cx18-alsa module is loaded */
1258 request_module("cx18-alsa");
1259
1260 /* Initialize cx18-alsa for this instance of the cx18 device */
1261 if (cx18_ext_init != NULL)
1262 cx18_ext_init(dev);
1263}
1264
1265static void request_modules(struct cx18 *dev)
1266{
1267 INIT_WORK(&dev->request_module_wk, request_module_async);
1268 schedule_work(&dev->request_module_wk);
1269}
1270#else
1271#define request_modules(dev)
1272#endif /* CONFIG_MODULES */
1273
1240/* define a pci_driver for card detection */ 1274/* define a pci_driver for card detection */
1241static struct pci_driver cx18_pci_driver = { 1275static struct pci_driver cx18_pci_driver = {
1242 .name = "cx18", 1276 .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 {
637 u32 active_input; 637 u32 active_input;
638 v4l2_std_id std; 638 v4l2_std_id std;
639 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ 639 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
640
641 /* Used for cx18-alsa module loading */
642 struct work_struct request_module_wk;
640}; 643};
641 644
642static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) 645static 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)
644 return container_of(v4l2_dev, struct cx18, v4l2_dev); 647 return container_of(v4l2_dev, struct cx18, v4l2_dev);
645} 648}
646 649
650/* cx18 extensions to be loaded */
651extern int (*cx18_ext_init)(struct cx18 *);
652
647/* Globals */ 653/* Globals */
648extern int cx18_first_minor; 654extern int cx18_first_minor;
649 655