Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media/video: explicitly flush request_module work

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 <tj@kernel.org>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>

Tejun Heo 707bcf32 883624a0

+50 -2
+9
drivers/media/video/bt8xx/bttv-driver.c
··· 189 189 INIT_WORK(&dev->request_module_wk, request_module_async); 190 190 schedule_work(&dev->request_module_wk); 191 191 } 192 + 193 + static void flush_request_modules(struct bttv *dev) 194 + { 195 + flush_work_sync(&dev->request_module_wk); 196 + } 192 197 #else 193 198 #define request_modules(dev) 199 + #define flush_request_modules(dev) 194 200 #endif /* CONFIG_MODULES */ 195 201 196 202 ··· 4578 4572 4579 4573 if (bttv_verbose) 4580 4574 printk("bttv%d: unloading\n",btv->c.nr); 4575 + 4576 + if (bttv_tvcards[btv->c.type].has_dvb) 4577 + flush_request_modules(btv); 4581 4578 4582 4579 /* shutdown everything (DMA+IRQs) */ 4583 4580 btand(~15, BT848_GPIO_DMA_CTL);
+8
drivers/media/video/cx18/cx18-driver.c
··· 266 266 INIT_WORK(&dev->request_module_wk, request_module_async); 267 267 schedule_work(&dev->request_module_wk); 268 268 } 269 + 270 + static void flush_request_modules(struct cx18 *dev) 271 + { 272 + flush_work_sync(&dev->request_module_wk); 273 + } 269 274 #else 270 275 #define request_modules(dev) 276 + #define flush_request_modules(dev) 271 277 #endif /* CONFIG_MODULES */ 272 278 273 279 /* Generic utility functions */ ··· 1231 1225 int i; 1232 1226 1233 1227 CX18_DEBUG_INFO("Removing Card\n"); 1228 + 1229 + flush_request_modules(cx); 1234 1230 1235 1231 /* Stop all captures */ 1236 1232 CX18_DEBUG_INFO("Stopping all streams\n");
+8
drivers/media/video/cx231xx/cx231xx-cards.c
··· 762 762 INIT_WORK(&dev->request_module_wk, request_module_async); 763 763 schedule_work(&dev->request_module_wk); 764 764 } 765 + 766 + static void flush_request_modules(struct cx231xx *dev) 767 + { 768 + flush_work_sync(&dev->request_module_wk); 769 + } 765 770 #else 766 771 #define request_modules(dev) 772 + #define flush_request_modules(dev) 767 773 #endif /* CONFIG_MODULES */ 768 774 769 775 /* ··· 1101 1095 1102 1096 if (!dev->udev) 1103 1097 return; 1098 + 1099 + flush_request_modules(dev); 1104 1100 1105 1101 /* delete v4l2 device */ 1106 1102 v4l2_device_unregister(&dev->v4l2_dev);
+8
drivers/media/video/cx88/cx88-mpeg.c
··· 66 66 INIT_WORK(&dev->request_module_wk, request_module_async); 67 67 schedule_work(&dev->request_module_wk); 68 68 } 69 + 70 + static void flush_request_modules(struct cx8802_dev *dev) 71 + { 72 + flush_work_sync(&dev->request_module_wk); 73 + } 69 74 #else 70 75 #define request_modules(dev) 76 + #define flush_request_modules(dev) 71 77 #endif /* CONFIG_MODULES */ 72 78 73 79 ··· 824 818 dev = pci_get_drvdata(pci_dev); 825 819 826 820 dprintk( 1, "%s\n", __func__); 821 + 822 + flush_request_modules(dev); 827 823 828 824 if (!list_empty(&dev->drvlist)) { 829 825 struct cx8802_driver *drv, *tmp;
+8
drivers/media/video/em28xx/em28xx-cards.c
··· 2632 2632 INIT_WORK(&dev->request_module_wk, request_module_async); 2633 2633 schedule_work(&dev->request_module_wk); 2634 2634 } 2635 + 2636 + static void flush_request_modules(struct em28xx *dev) 2637 + { 2638 + flush_work_sync(&dev->request_module_wk); 2639 + } 2635 2640 #else 2636 2641 #define request_modules(dev) 2642 + #define flush_request_modules(dev) 2637 2643 #endif /* CONFIG_MODULES */ 2638 2644 2639 2645 /* ··· 3065 3059 return; 3066 3060 3067 3061 em28xx_info("disconnecting %s\n", dev->vdev->name); 3062 + 3063 + flush_request_modules(dev); 3068 3064 3069 3065 /* wait until all current v4l2 io is finished then deallocate 3070 3066 resources */
+9 -2
drivers/media/video/saa7134/saa7134-core.c
··· 166 166 schedule_work(&dev->request_module_wk); 167 167 } 168 168 169 + static void flush_request_submodules(struct saa7134_dev *dev) 170 + { 171 + flush_work_sync(&dev->request_module_wk); 172 + } 173 + 169 174 #else 170 175 #define request_submodules(dev) 176 + #define flush_request_submodules(dev) 171 177 #endif /* CONFIG_MODULES */ 172 178 173 179 /* ------------------------------------------------------------------ */ ··· 1016 1010 } 1017 1011 } 1018 1012 1019 - request_submodules(dev); 1020 - 1021 1013 v4l2_prio_init(&dev->prio); 1022 1014 1023 1015 mutex_lock(&saa7134_devlist_lock); ··· 1070 1066 if (saa7134_dmasound_init && !dev->dmasound.priv_data) 1071 1067 saa7134_dmasound_init(dev); 1072 1068 1069 + request_submodules(dev); 1073 1070 return 0; 1074 1071 1075 1072 fail4: ··· 1095 1090 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); 1096 1091 struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); 1097 1092 struct saa7134_mpeg_ops *mops; 1093 + 1094 + flush_request_submodules(dev); 1098 1095 1099 1096 /* Release DMA sound modules if present */ 1100 1097 if (saa7134_dmasound_exit && dev->dmasound.priv_data) {