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: | |||
190 | return ret; | 190 | return ret; |
191 | } | 191 | } |
192 | 192 | ||
193 | static int __init cx18_alsa_init_callback(struct device *dev, void *data) | 193 | int 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 | ||
236 | static int __init cx18_alsa_init(void) | 233 | static 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 | ||
267 | static void snd_cx18_exit(struct snd_cx18_card *cxsc) | 240 | static 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. */ |
48 | int cx18_first_minor; | 48 | int cx18_first_minor; |
49 | 49 | ||
50 | /* Callback for registering extensions */ | ||
51 | int (*cx18_ext_init)(struct cx18 *); | ||
52 | EXPORT_SYMBOL(cx18_ext_init); | ||
53 | |||
50 | /* add your revision and whatnot here */ | 54 | /* add your revision and whatnot here */ |
51 | static struct pci_device_id cx18_pci_tbl[] __devinitdata = { | 55 | static 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 | ||
244 | MODULE_VERSION(CX18_VERSION); | 248 | MODULE_VERSION(CX18_VERSION); |
245 | 249 | ||
250 | /* Forward Declaration */ | ||
251 | static void request_modules(struct cx18 *dev); | ||
252 | |||
246 | /* Generic utility functions */ | 253 | /* Generic utility functions */ |
247 | int cx18_msleep_timeout(unsigned int msecs, int intr) | 254 | int 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 | ||
1054 | free_streams: | 1065 | free_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) | ||
1253 | static 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 | |||
1265 | static 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 */ |
1241 | static struct pci_driver cx18_pci_driver = { | 1275 | static 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 | ||
642 | static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) | 645 | 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) | |||
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 */ | ||
651 | extern int (*cx18_ext_init)(struct cx18 *); | ||
652 | |||
647 | /* Globals */ | 653 | /* Globals */ |
648 | extern int cx18_first_minor; | 654 | extern int cx18_first_minor; |
649 | 655 | ||