diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 19:58:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 19:58:04 -0500 |
commit | 23d69b09b78c4876e134f104a3814c30747c53f1 (patch) | |
tree | 40744de4f4126c21027ce537264524095e0e7979 | |
parent | e744070fd4ff9d3114277e52d77afa21579adce2 (diff) | |
parent | 569ff2de2e1c8ac67c8df3a7367d46d0d9460a35 (diff) |
Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
* 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: (33 commits)
usb: don't use flush_scheduled_work()
speedtch: don't abuse struct delayed_work
media/video: don't use flush_scheduled_work()
media/video: explicitly flush request_module work
ioc4: use static work_struct for ioc4_load_modules()
init: don't call flush_scheduled_work() from do_initcalls()
s390: don't use flush_scheduled_work()
rtc: don't use flush_scheduled_work()
mmc: update workqueue usages
mfd: update workqueue usages
dvb: don't use flush_scheduled_work()
leds-wm8350: don't use flush_scheduled_work()
mISDN: don't use flush_scheduled_work()
macintosh/ams: don't use flush_scheduled_work()
vmwgfx: don't use flush_scheduled_work()
tpm: don't use flush_scheduled_work()
sonypi: don't use flush_scheduled_work()
hvsi: don't use flush_scheduled_work()
xen: don't use flush_scheduled_work()
gdrom: don't use flush_scheduled_work()
...
Fixed up trivial conflict in drivers/media/video/bt8xx/bttv-input.c
as per Tejun.
80 files changed, 289 insertions, 156 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index f2742e115b09..22f10818c2b3 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -566,3 +566,13 @@ Why: This field is deprecated. I2C device drivers shouldn't change their | |||
566 | Who: Jean Delvare <khali@linux-fr.org> | 566 | Who: Jean Delvare <khali@linux-fr.org> |
567 | 567 | ||
568 | ---------------------------- | 568 | ---------------------------- |
569 | |||
570 | What: cancel_rearming_delayed_work[queue]() | ||
571 | When: 2.6.39 | ||
572 | |||
573 | Why: The functions have been superceded by cancel_delayed_work_sync() | ||
574 | quite some time ago. The conversion is trivial and there is no | ||
575 | in-kernel user left. | ||
576 | Who: Tejun Heo <tj@kernel.org> | ||
577 | |||
578 | ---------------------------- | ||
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 8fed027b12dc..e68d46d415f3 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c | |||
@@ -579,7 +579,8 @@ static int sharpsl_ac_check(void) | |||
579 | static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state) | 579 | static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state) |
580 | { | 580 | { |
581 | sharpsl_pm.flags |= SHARPSL_SUSPENDED; | 581 | sharpsl_pm.flags |= SHARPSL_SUSPENDED; |
582 | flush_scheduled_work(); | 582 | flush_delayed_work_sync(&toggle_charger); |
583 | flush_delayed_work_sync(&sharpsl_bat); | ||
583 | 584 | ||
584 | if (sharpsl_pm.charge_mode == CHRG_ON) | 585 | if (sharpsl_pm.charge_mode == CHRG_ON) |
585 | sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; | 586 | sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; |
diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index 7b42c247316c..afc24556572b 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c | |||
@@ -107,7 +107,7 @@ static int switch_drv_remove(struct platform_device *pdev) | |||
107 | device_remove_file(&pdev->dev, &dev_attr_switch); | 107 | device_remove_file(&pdev->dev, &dev_attr_switch); |
108 | 108 | ||
109 | platform_set_drvdata(pdev, NULL); | 109 | platform_set_drvdata(pdev, NULL); |
110 | flush_scheduled_work(); | 110 | flush_work_sync(&psw->work); |
111 | del_timer_sync(&psw->debounce); | 111 | del_timer_sync(&psw->debounce); |
112 | free_irq(irq, pdev); | 112 | free_irq(irq, pdev); |
113 | 113 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f23d6d46b95b..0a6a943b3779 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -6128,7 +6128,7 @@ static void ata_port_detach(struct ata_port *ap) | |||
6128 | /* it better be dead now */ | 6128 | /* it better be dead now */ |
6129 | WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); | 6129 | WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); |
6130 | 6130 | ||
6131 | cancel_rearming_delayed_work(&ap->hotplug_task); | 6131 | cancel_delayed_work_sync(&ap->hotplug_task); |
6132 | 6132 | ||
6133 | skip_eh: | 6133 | skip_eh: |
6134 | if (ap->pmp_link) { | 6134 | if (ap->pmp_link) { |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 484697fef386..af6141bb1ba3 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1320,7 +1320,7 @@ void ata_sff_flush_pio_task(struct ata_port *ap) | |||
1320 | { | 1320 | { |
1321 | DPRINTK("ENTER\n"); | 1321 | DPRINTK("ENTER\n"); |
1322 | 1322 | ||
1323 | cancel_rearming_delayed_work(&ap->sff_pio_task); | 1323 | cancel_delayed_work_sync(&ap->sff_pio_task); |
1324 | ap->hsm_task_state = HSM_ST_IDLE; | 1324 | ap->hsm_task_state = HSM_ST_IDLE; |
1325 | 1325 | ||
1326 | if (ata_msg_ctl(ap)) | 1326 | if (ata_msg_ctl(ap)) |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 3951020e494a..25e4dffa0aad 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -4352,7 +4352,7 @@ static int __init floppy_init(void) | |||
4352 | out_unreg_platform_dev: | 4352 | out_unreg_platform_dev: |
4353 | platform_device_unregister(&floppy_device[drive]); | 4353 | platform_device_unregister(&floppy_device[drive]); |
4354 | out_flush_work: | 4354 | out_flush_work: |
4355 | flush_scheduled_work(); | 4355 | flush_work_sync(&floppy_work); |
4356 | if (atomic_read(&usage_count)) | 4356 | if (atomic_read(&usage_count)) |
4357 | floppy_release_irq_and_dma(); | 4357 | floppy_release_irq_and_dma(); |
4358 | out_unreg_region: | 4358 | out_unreg_region: |
@@ -4422,7 +4422,7 @@ static int floppy_grab_irq_and_dma(void) | |||
4422 | * We might have scheduled a free_irq(), wait it to | 4422 | * We might have scheduled a free_irq(), wait it to |
4423 | * drain first: | 4423 | * drain first: |
4424 | */ | 4424 | */ |
4425 | flush_scheduled_work(); | 4425 | flush_work_sync(&floppy_work); |
4426 | 4426 | ||
4427 | if (fd_request_irq()) { | 4427 | if (fd_request_irq()) { |
4428 | DPRINT("Unable to grab IRQ%d for the floppy driver\n", | 4428 | DPRINT("Unable to grab IRQ%d for the floppy driver\n", |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 657873e4328d..d7aa39e349a6 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -547,7 +547,7 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) | |||
547 | spin_unlock_irqrestore(&blkif_io_lock, flags); | 547 | spin_unlock_irqrestore(&blkif_io_lock, flags); |
548 | 548 | ||
549 | /* Flush gnttab callback work. Must be done with no locks held. */ | 549 | /* Flush gnttab callback work. Must be done with no locks held. */ |
550 | flush_scheduled_work(); | 550 | flush_work_sync(&info->work); |
551 | 551 | ||
552 | del_gendisk(info->gd); | 552 | del_gendisk(info->gd); |
553 | 553 | ||
@@ -596,7 +596,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) | |||
596 | spin_unlock_irq(&blkif_io_lock); | 596 | spin_unlock_irq(&blkif_io_lock); |
597 | 597 | ||
598 | /* Flush gnttab callback work. Must be done with no locks held. */ | 598 | /* Flush gnttab callback work. Must be done with no locks held. */ |
599 | flush_scheduled_work(); | 599 | flush_work_sync(&info->work); |
600 | 600 | ||
601 | /* Free resources associated with old device channel. */ | 601 | /* Free resources associated with old device channel. */ |
602 | if (info->ring_ref != GRANT_INVALID_REF) { | 602 | if (info->ring_ref != GRANT_INVALID_REF) { |
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index de65915308fb..64a21461c408 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c | |||
@@ -837,7 +837,7 @@ probe_fail_no_mem: | |||
837 | 837 | ||
838 | static int __devexit remove_gdrom(struct platform_device *devptr) | 838 | static int __devexit remove_gdrom(struct platform_device *devptr) |
839 | { | 839 | { |
840 | flush_scheduled_work(); | 840 | flush_work_sync(&work); |
841 | blk_cleanup_queue(gd.gdrom_rq); | 841 | blk_cleanup_queue(gd.gdrom_rq); |
842 | free_irq(HW_EVENT_GDROM_CMD, &gd); | 842 | free_irq(HW_EVENT_GDROM_CMD, &gd); |
843 | free_irq(HW_EVENT_GDROM_DMA, &gd); | 843 | free_irq(HW_EVENT_GDROM_DMA, &gd); |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index a2bc885ce60a..67a75a502c01 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -850,8 +850,8 @@ static void hvsi_flush_output(struct hvsi_struct *hp) | |||
850 | wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT); | 850 | wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT); |
851 | 851 | ||
852 | /* 'writer' could still be pending if it didn't see n_outbuf = 0 yet */ | 852 | /* 'writer' could still be pending if it didn't see n_outbuf = 0 yet */ |
853 | cancel_delayed_work(&hp->writer); | 853 | cancel_delayed_work_sync(&hp->writer); |
854 | flush_scheduled_work(); | 854 | flush_work_sync(&hp->handshaker); |
855 | 855 | ||
856 | /* | 856 | /* |
857 | * it's also possible that our timeout expired and hvsi_write_worker | 857 | * it's also possible that our timeout expired and hvsi_write_worker |
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index 99cffdab1056..0aeb5a38d296 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c | |||
@@ -1729,7 +1729,7 @@ void ipwireless_hardware_free(struct ipw_hardware *hw) | |||
1729 | 1729 | ||
1730 | ipwireless_stop_interrupts(hw); | 1730 | ipwireless_stop_interrupts(hw); |
1731 | 1731 | ||
1732 | flush_scheduled_work(); | 1732 | flush_work_sync(&hw->work_rx); |
1733 | 1733 | ||
1734 | for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) | 1734 | for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) |
1735 | if (hw->packet_assembler[i] != NULL) | 1735 | if (hw->packet_assembler[i] != NULL) |
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index 9fe538347932..f7daeea598e4 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c | |||
@@ -430,7 +430,8 @@ void ipwireless_network_free(struct ipw_network *network) | |||
430 | network->shutting_down = 1; | 430 | network->shutting_down = 1; |
431 | 431 | ||
432 | ipwireless_ppp_close(network); | 432 | ipwireless_ppp_close(network); |
433 | flush_scheduled_work(); | 433 | flush_work_sync(&network->work_go_online); |
434 | flush_work_sync(&network->work_go_offline); | ||
434 | 435 | ||
435 | ipwireless_stop_interrupts(network->hardware); | 436 | ipwireless_stop_interrupts(network->hardware); |
436 | ipwireless_associate_network(network->hardware, NULL); | 437 | ipwireless_associate_network(network->hardware, NULL); |
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 1a2c2c3b068f..f5eb28b6cb0f 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -577,7 +577,7 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
577 | mutex_unlock(&ttyj->ipw_tty_mutex); | 577 | mutex_unlock(&ttyj->ipw_tty_mutex); |
578 | tty_hangup(ttyj->linux_tty); | 578 | tty_hangup(ttyj->linux_tty); |
579 | /* Wait till the tty_hangup has completed */ | 579 | /* Wait till the tty_hangup has completed */ |
580 | flush_scheduled_work(); | 580 | flush_work_sync(&ttyj->linux_tty->hangup_work); |
581 | /* FIXME: Exactly how is the tty object locked here | 581 | /* FIXME: Exactly how is the tty object locked here |
582 | against a parallel ioctl etc */ | 582 | against a parallel ioctl etc */ |
583 | mutex_lock(&ttyj->ipw_tty_mutex); | 583 | mutex_lock(&ttyj->ipw_tty_mutex); |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 73f66d03624d..79e36c878a4c 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -1434,7 +1434,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
1434 | sonypi_disable(); | 1434 | sonypi_disable(); |
1435 | 1435 | ||
1436 | synchronize_irq(sonypi_device.irq); | 1436 | synchronize_irq(sonypi_device.irq); |
1437 | flush_scheduled_work(); | 1437 | flush_work_sync(&sonypi_device.input_work); |
1438 | 1438 | ||
1439 | if (useinput) { | 1439 | if (useinput) { |
1440 | input_unregister_device(sonypi_device.input_key_dev); | 1440 | input_unregister_device(sonypi_device.input_key_dev); |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 7c4133582dba..0b3af3fe6766 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -986,7 +986,7 @@ int tpm_release(struct inode *inode, struct file *file) | |||
986 | struct tpm_chip *chip = file->private_data; | 986 | struct tpm_chip *chip = file->private_data; |
987 | 987 | ||
988 | del_singleshot_timer_sync(&chip->user_read_timer); | 988 | del_singleshot_timer_sync(&chip->user_read_timer); |
989 | flush_scheduled_work(); | 989 | flush_work_sync(&chip->work); |
990 | file->private_data = NULL; | 990 | file->private_data = NULL; |
991 | atomic_set(&chip->data_pending, 0); | 991 | atomic_set(&chip->data_pending, 0); |
992 | kfree(chip->data_buffer); | 992 | kfree(chip->data_buffer); |
@@ -1038,7 +1038,7 @@ ssize_t tpm_read(struct file *file, char __user *buf, | |||
1038 | ssize_t ret_size; | 1038 | ssize_t ret_size; |
1039 | 1039 | ||
1040 | del_singleshot_timer_sync(&chip->user_read_timer); | 1040 | del_singleshot_timer_sync(&chip->user_read_timer); |
1041 | flush_scheduled_work(); | 1041 | flush_work_sync(&chip->work); |
1042 | ret_size = atomic_read(&chip->data_pending); | 1042 | ret_size = atomic_read(&chip->data_pending); |
1043 | atomic_set(&chip->data_pending, 0); | 1043 | atomic_set(&chip->data_pending, 0); |
1044 | if (ret_size > 0) { /* relay data */ | 1044 | if (ret_size > 0) { /* relay data */ |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 148a322d8f5d..934a96a78540 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -1472,8 +1472,7 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) | |||
1472 | list_del(&bdev->device_list); | 1472 | list_del(&bdev->device_list); |
1473 | mutex_unlock(&glob->device_list_mutex); | 1473 | mutex_unlock(&glob->device_list_mutex); |
1474 | 1474 | ||
1475 | if (!cancel_delayed_work(&bdev->wq)) | 1475 | cancel_delayed_work_sync(&bdev->wq); |
1476 | flush_scheduled_work(); | ||
1477 | 1476 | ||
1478 | while (ttm_bo_delayed_delete(bdev, true)) | 1477 | while (ttm_bo_delayed_delete(bdev, true)) |
1479 | ; | 1478 | ; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 41d9a5b73c03..fe096a7cc0d7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -659,7 +659,7 @@ int vmw_fb_off(struct vmw_private *vmw_priv) | |||
659 | par->dirty.active = false; | 659 | par->dirty.active = false; |
660 | spin_unlock_irqrestore(&par->dirty.lock, flags); | 660 | spin_unlock_irqrestore(&par->dirty.lock, flags); |
661 | 661 | ||
662 | flush_scheduled_work(); | 662 | flush_delayed_work_sync(&info->deferred_work); |
663 | 663 | ||
664 | par->bo_ptr = NULL; | 664 | par->bo_ptr = NULL; |
665 | ttm_bo_kunmap(&par->map); | 665 | ttm_bo_kunmap(&par->map); |
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index e54e79d4e2c1..92607ed25e2e 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c | |||
@@ -2297,6 +2297,7 @@ static int __init capidrv_init(void) | |||
2297 | 2297 | ||
2298 | errcode = capi20_get_profile(0, &profile); | 2298 | errcode = capi20_get_profile(0, &profile); |
2299 | if (errcode != CAPI_NOERROR) { | 2299 | if (errcode != CAPI_NOERROR) { |
2300 | unregister_capictr_notifier(&capictr_nb); | ||
2300 | capi20_release(&global.ap); | 2301 | capi20_release(&global.ap); |
2301 | return -EIO; | 2302 | return -EIO; |
2302 | } | 2303 | } |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 3acf94cc5acd..2b33b2627fce 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/rcupdate.h> | 38 | #include <linux/rcupdate.h> |
39 | 39 | ||
40 | static int showcapimsgs = 0; | 40 | static int showcapimsgs = 0; |
41 | static struct workqueue_struct *kcapi_wq; | ||
41 | 42 | ||
42 | MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); | 43 | MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); |
43 | MODULE_AUTHOR("Carsten Paeth"); | 44 | MODULE_AUTHOR("Carsten Paeth"); |
@@ -291,7 +292,7 @@ static int notify_push(unsigned int event_type, u32 controller) | |||
291 | event->type = event_type; | 292 | event->type = event_type; |
292 | event->controller = controller; | 293 | event->controller = controller; |
293 | 294 | ||
294 | schedule_work(&event->work); | 295 | queue_work(kcapi_wq, &event->work); |
295 | return 0; | 296 | return 0; |
296 | } | 297 | } |
297 | 298 | ||
@@ -408,7 +409,7 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl, | |||
408 | goto error; | 409 | goto error; |
409 | } | 410 | } |
410 | skb_queue_tail(&ap->recv_queue, skb); | 411 | skb_queue_tail(&ap->recv_queue, skb); |
411 | schedule_work(&ap->recv_work); | 412 | queue_work(kcapi_wq, &ap->recv_work); |
412 | rcu_read_unlock(); | 413 | rcu_read_unlock(); |
413 | 414 | ||
414 | return; | 415 | return; |
@@ -743,7 +744,7 @@ u16 capi20_release(struct capi20_appl *ap) | |||
743 | 744 | ||
744 | mutex_unlock(&capi_controller_lock); | 745 | mutex_unlock(&capi_controller_lock); |
745 | 746 | ||
746 | flush_scheduled_work(); | 747 | flush_workqueue(kcapi_wq); |
747 | skb_queue_purge(&ap->recv_queue); | 748 | skb_queue_purge(&ap->recv_queue); |
748 | 749 | ||
749 | if (showcapimsgs & 1) { | 750 | if (showcapimsgs & 1) { |
@@ -1285,21 +1286,30 @@ static int __init kcapi_init(void) | |||
1285 | { | 1286 | { |
1286 | int err; | 1287 | int err; |
1287 | 1288 | ||
1289 | kcapi_wq = alloc_workqueue("kcapi", 0, 0); | ||
1290 | if (!kcapi_wq) | ||
1291 | return -ENOMEM; | ||
1292 | |||
1288 | register_capictr_notifier(&capictr_nb); | 1293 | register_capictr_notifier(&capictr_nb); |
1289 | 1294 | ||
1290 | err = cdebug_init(); | 1295 | err = cdebug_init(); |
1291 | if (!err) | 1296 | if (err) { |
1292 | kcapi_proc_init(); | 1297 | unregister_capictr_notifier(&capictr_nb); |
1293 | return err; | 1298 | destroy_workqueue(kcapi_wq); |
1299 | return err; | ||
1300 | } | ||
1301 | |||
1302 | kcapi_proc_init(); | ||
1303 | return 0; | ||
1294 | } | 1304 | } |
1295 | 1305 | ||
1296 | static void __exit kcapi_exit(void) | 1306 | static void __exit kcapi_exit(void) |
1297 | { | 1307 | { |
1298 | kcapi_proc_exit(); | 1308 | kcapi_proc_exit(); |
1299 | 1309 | ||
1300 | /* make sure all notifiers are finished */ | 1310 | unregister_capictr_notifier(&capictr_nb); |
1301 | flush_scheduled_work(); | ||
1302 | cdebug_exit(); | 1311 | cdebug_exit(); |
1312 | destroy_workqueue(kcapi_wq); | ||
1303 | } | 1313 | } |
1304 | 1314 | ||
1305 | module_init(kcapi_init); | 1315 | module_init(kcapi_init); |
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index 307bd6e8988b..199f374cf9da 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c | |||
@@ -110,7 +110,7 @@ mISDN_freedchannel(struct dchannel *ch) | |||
110 | } | 110 | } |
111 | skb_queue_purge(&ch->squeue); | 111 | skb_queue_purge(&ch->squeue); |
112 | skb_queue_purge(&ch->rqueue); | 112 | skb_queue_purge(&ch->rqueue); |
113 | flush_scheduled_work(); | 113 | flush_work_sync(&ch->workq); |
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | EXPORT_SYMBOL(mISDN_freedchannel); | 116 | EXPORT_SYMBOL(mISDN_freedchannel); |
@@ -143,7 +143,7 @@ mISDN_freebchannel(struct bchannel *ch) | |||
143 | mISDN_clear_bchannel(ch); | 143 | mISDN_clear_bchannel(ch); |
144 | skb_queue_purge(&ch->rqueue); | 144 | skb_queue_purge(&ch->rqueue); |
145 | ch->rcount = 0; | 145 | ch->rcount = 0; |
146 | flush_scheduled_work(); | 146 | flush_work_sync(&ch->workq); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | EXPORT_SYMBOL(mISDN_freebchannel); | 149 | EXPORT_SYMBOL(mISDN_freebchannel); |
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 5b59796ed250..bd526f664a39 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -1269,6 +1269,8 @@ release_card(struct l1oip *hc) | |||
1269 | if (timer_pending(&hc->timeout_tl)) | 1269 | if (timer_pending(&hc->timeout_tl)) |
1270 | del_timer(&hc->timeout_tl); | 1270 | del_timer(&hc->timeout_tl); |
1271 | 1271 | ||
1272 | cancel_work_sync(&hc->workq); | ||
1273 | |||
1272 | if (hc->socket_thread) | 1274 | if (hc->socket_thread) |
1273 | l1oip_socket_close(hc); | 1275 | l1oip_socket_close(hc); |
1274 | 1276 | ||
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c index 5aab32ce4f4d..a04523273282 100644 --- a/drivers/leds/leds-wm8350.c +++ b/drivers/leds/leds-wm8350.c | |||
@@ -276,7 +276,7 @@ static int wm8350_led_remove(struct platform_device *pdev) | |||
276 | struct wm8350_led *led = platform_get_drvdata(pdev); | 276 | struct wm8350_led *led = platform_get_drvdata(pdev); |
277 | 277 | ||
278 | led_classdev_unregister(&led->cdev); | 278 | led_classdev_unregister(&led->cdev); |
279 | flush_scheduled_work(); | 279 | flush_work_sync(&led->work); |
280 | wm8350_led_disable(led); | 280 | wm8350_led_disable(led); |
281 | regulator_put(led->dcdc); | 281 | regulator_put(led->dcdc); |
282 | regulator_put(led->isink); | 282 | regulator_put(led->isink); |
diff --git a/drivers/macintosh/ams/ams-core.c b/drivers/macintosh/ams/ams-core.c index 2ad62c339cd2..399beb1638d1 100644 --- a/drivers/macintosh/ams/ams-core.c +++ b/drivers/macintosh/ams/ams-core.c | |||
@@ -226,7 +226,7 @@ void ams_sensor_detach(void) | |||
226 | * We do this after ams_info.exit(), because an interrupt might | 226 | * We do this after ams_info.exit(), because an interrupt might |
227 | * have arrived before disabling them. | 227 | * have arrived before disabling them. |
228 | */ | 228 | */ |
229 | flush_scheduled_work(); | 229 | flush_work_sync(&ams_info.worker); |
230 | 230 | ||
231 | /* Remove device */ | 231 | /* Remove device */ |
232 | of_device_unregister(ams_info.of_dev); | 232 | of_device_unregister(ams_info.of_dev); |
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 53cce3a5da23..39f660b2a60d 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c | |||
@@ -285,8 +285,8 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) | |||
285 | 285 | ||
286 | static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) | 286 | static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) |
287 | { | 287 | { |
288 | cancel_rearming_delayed_work(&rm->cpu[0].sniffer); | 288 | cancel_delayed_work_sync(&rm->cpu[0].sniffer); |
289 | cancel_rearming_delayed_work(&rm->cpu[1].sniffer); | 289 | cancel_delayed_work_sync(&rm->cpu[1].sniffer); |
290 | } | 290 | } |
291 | 291 | ||
292 | static int __devinit rackmeter_setup(struct rackmeter *rm) | 292 | static int __devinit rackmeter_setup(struct rackmeter *rm) |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 4df42aaae7f7..51752a9ef7a4 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -1329,7 +1329,8 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) | |||
1329 | return -EBUSY; | 1329 | return -EBUSY; |
1330 | 1330 | ||
1331 | dvb_net_stop(net); | 1331 | dvb_net_stop(net); |
1332 | flush_scheduled_work(); | 1332 | flush_work_sync(&priv->set_multicast_list_wq); |
1333 | flush_work_sync(&priv->restart_net_feed_wq); | ||
1333 | printk("dvb_net: removed network interface %s\n", net->name); | 1334 | printk("dvb_net: removed network interface %s\n", net->name); |
1334 | unregister_netdev(net); | 1335 | unregister_netdev(net); |
1335 | dvbnet->state[num]=0; | 1336 | dvbnet->state[num]=0; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index c6498f536dff..23005b3cf30b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | |||
@@ -313,8 +313,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) | |||
313 | int dvb_usb_remote_exit(struct dvb_usb_device *d) | 313 | int dvb_usb_remote_exit(struct dvb_usb_device *d) |
314 | { | 314 | { |
315 | if (d->state & DVB_USB_STATE_REMOTE) { | 315 | if (d->state & DVB_USB_STATE_REMOTE) { |
316 | cancel_rearming_delayed_work(&d->rc_query_work); | 316 | cancel_delayed_work_sync(&d->rc_query_work); |
317 | flush_scheduled_work(); | ||
318 | if (d->props.rc.mode == DVB_RC_LEGACY) | 317 | if (d->props.rc.mode == DVB_RC_LEGACY) |
319 | input_unregister_device(d->input_dev); | 318 | input_unregister_device(d->input_dev); |
320 | else | 319 | else |
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c index a7b369a439d6..9f73c2cfc9ea 100644 --- a/drivers/media/dvb/mantis/mantis_evm.c +++ b/drivers/media/dvb/mantis/mantis_evm.c | |||
@@ -111,7 +111,7 @@ void mantis_evmgr_exit(struct mantis_ca *ca) | |||
111 | struct mantis_pci *mantis = ca->ca_priv; | 111 | struct mantis_pci *mantis = ca->ca_priv; |
112 | 112 | ||
113 | dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); | 113 | dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); |
114 | flush_scheduled_work(); | 114 | flush_work_sync(&ca->hif_evm_work); |
115 | mantis_hif_exit(ca); | 115 | mantis_hif_exit(ca); |
116 | mantis_pcmcia_exit(ca); | 116 | mantis_pcmcia_exit(ca); |
117 | } | 117 | } |
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c index 7d2f2398fa8b..97b889e8a341 100644 --- a/drivers/media/dvb/mantis/mantis_uart.c +++ b/drivers/media/dvb/mantis/mantis_uart.c | |||
@@ -182,5 +182,6 @@ void mantis_uart_exit(struct mantis_pci *mantis) | |||
182 | { | 182 | { |
183 | /* disable interrupt */ | 183 | /* disable interrupt */ |
184 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | 184 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); |
185 | flush_work_sync(&mantis->uart_work); | ||
185 | } | 186 | } |
186 | EXPORT_SYMBOL_GPL(mantis_uart_exit); | 187 | EXPORT_SYMBOL_GPL(mantis_uart_exit); |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 849cd170b821..91399c94cd18 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -189,8 +189,14 @@ static void request_modules(struct bttv *dev) | |||
189 | INIT_WORK(&dev->request_module_wk, request_module_async); | 189 | INIT_WORK(&dev->request_module_wk, request_module_async); |
190 | schedule_work(&dev->request_module_wk); | 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 | #else | 197 | #else |
193 | #define request_modules(dev) | 198 | #define request_modules(dev) |
199 | #define flush_request_modules(dev) | ||
194 | #endif /* CONFIG_MODULES */ | 200 | #endif /* CONFIG_MODULES */ |
195 | 201 | ||
196 | 202 | ||
@@ -4429,6 +4435,9 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) | |||
4429 | if (bttv_verbose) | 4435 | if (bttv_verbose) |
4430 | printk("bttv%d: unloading\n",btv->c.nr); | 4436 | printk("bttv%d: unloading\n",btv->c.nr); |
4431 | 4437 | ||
4438 | if (bttv_tvcards[btv->c.type].has_dvb) | ||
4439 | flush_request_modules(btv); | ||
4440 | |||
4432 | /* shutdown everything (DMA+IRQs) */ | 4441 | /* shutdown everything (DMA+IRQs) */ |
4433 | btand(~15, BT848_GPIO_DMA_CTL); | 4442 | btand(~15, BT848_GPIO_DMA_CTL); |
4434 | btwrite(0, BT848_INT_MASK); | 4443 | btwrite(0, BT848_INT_MASK); |
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 97793b960600..e8b64bca9db2 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -319,16 +319,13 @@ static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) | |||
319 | 319 | ||
320 | static void bttv_ir_stop(struct bttv *btv) | 320 | static void bttv_ir_stop(struct bttv *btv) |
321 | { | 321 | { |
322 | if (btv->remote->polling) { | 322 | if (btv->remote->polling) |
323 | del_timer_sync(&btv->remote->timer); | 323 | del_timer_sync(&btv->remote->timer); |
324 | flush_scheduled_work(); | ||
325 | } | ||
326 | 324 | ||
327 | if (btv->remote->rc5_gpio) { | 325 | if (btv->remote->rc5_gpio) { |
328 | u32 gpio; | 326 | u32 gpio; |
329 | 327 | ||
330 | del_timer_sync(&btv->remote->timer); | 328 | del_timer_sync(&btv->remote->timer); |
331 | flush_scheduled_work(); | ||
332 | 329 | ||
333 | gpio = bttv_gpio_read(&btv->c); | 330 | gpio = bttv_gpio_read(&btv->c); |
334 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); | 331 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 676e5bef89eb..133ec2bac180 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -267,8 +267,14 @@ static void request_modules(struct cx18 *dev) | |||
267 | INIT_WORK(&dev->request_module_wk, request_module_async); | 267 | INIT_WORK(&dev->request_module_wk, request_module_async); |
268 | schedule_work(&dev->request_module_wk); | 268 | schedule_work(&dev->request_module_wk); |
269 | } | 269 | } |
270 | |||
271 | static void flush_request_modules(struct cx18 *dev) | ||
272 | { | ||
273 | flush_work_sync(&dev->request_module_wk); | ||
274 | } | ||
270 | #else | 275 | #else |
271 | #define request_modules(dev) | 276 | #define request_modules(dev) |
277 | #define flush_request_modules(dev) | ||
272 | #endif /* CONFIG_MODULES */ | 278 | #endif /* CONFIG_MODULES */ |
273 | 279 | ||
274 | /* Generic utility functions */ | 280 | /* Generic utility functions */ |
@@ -1233,6 +1239,8 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
1233 | 1239 | ||
1234 | CX18_DEBUG_INFO("Removing Card\n"); | 1240 | CX18_DEBUG_INFO("Removing Card\n"); |
1235 | 1241 | ||
1242 | flush_request_modules(cx); | ||
1243 | |||
1236 | /* Stop all captures */ | 1244 | /* Stop all captures */ |
1237 | CX18_DEBUG_INFO("Stopping all streams\n"); | 1245 | CX18_DEBUG_INFO("Stopping all streams\n"); |
1238 | if (atomic_read(&cx->tot_capturing) > 0) | 1246 | if (atomic_read(&cx->tot_capturing) > 0) |
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 6905607ffca3..588f3e8f028b 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -813,8 +813,14 @@ static void request_modules(struct cx231xx *dev) | |||
813 | INIT_WORK(&dev->request_module_wk, request_module_async); | 813 | INIT_WORK(&dev->request_module_wk, request_module_async); |
814 | schedule_work(&dev->request_module_wk); | 814 | schedule_work(&dev->request_module_wk); |
815 | } | 815 | } |
816 | |||
817 | static void flush_request_modules(struct cx231xx *dev) | ||
818 | { | ||
819 | flush_work_sync(&dev->request_module_wk); | ||
820 | } | ||
816 | #else | 821 | #else |
817 | #define request_modules(dev) | 822 | #define request_modules(dev) |
823 | #define flush_request_modules(dev) | ||
818 | #endif /* CONFIG_MODULES */ | 824 | #endif /* CONFIG_MODULES */ |
819 | 825 | ||
820 | /* | 826 | /* |
@@ -1147,6 +1153,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) | |||
1147 | if (!dev->udev) | 1153 | if (!dev->udev) |
1148 | return; | 1154 | return; |
1149 | 1155 | ||
1156 | flush_request_modules(dev); | ||
1157 | |||
1150 | /* delete v4l2 device */ | 1158 | /* delete v4l2 device */ |
1151 | v4l2_device_unregister(&dev->v4l2_dev); | 1159 | v4l2_device_unregister(&dev->v4l2_dev); |
1152 | 1160 | ||
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index 0b0d0664382a..199b9964bbe5 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c | |||
@@ -229,8 +229,6 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev) | |||
229 | v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); | 229 | v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); |
230 | v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); | 230 | v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); |
231 | } | 231 | } |
232 | |||
233 | flush_scheduled_work(); | ||
234 | } | 232 | } |
235 | 233 | ||
236 | static void cx23885_input_ir_close(struct rc_dev *rc) | 234 | static void cx23885_input_ir_close(struct rc_dev *rc) |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index f7d71acbb078..addf9545e9bf 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -66,8 +66,14 @@ static void request_modules(struct cx8802_dev *dev) | |||
66 | INIT_WORK(&dev->request_module_wk, request_module_async); | 66 | INIT_WORK(&dev->request_module_wk, request_module_async); |
67 | schedule_work(&dev->request_module_wk); | 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 | #else | 74 | #else |
70 | #define request_modules(dev) | 75 | #define request_modules(dev) |
76 | #define flush_request_modules(dev) | ||
71 | #endif /* CONFIG_MODULES */ | 77 | #endif /* CONFIG_MODULES */ |
72 | 78 | ||
73 | 79 | ||
@@ -819,6 +825,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) | |||
819 | 825 | ||
820 | dprintk( 1, "%s\n", __func__); | 826 | dprintk( 1, "%s\n", __func__); |
821 | 827 | ||
828 | flush_request_modules(dev); | ||
829 | |||
822 | if (!list_empty(&dev->drvlist)) { | 830 | if (!list_empty(&dev->drvlist)) { |
823 | struct cx8802_driver *drv, *tmp; | 831 | struct cx8802_driver *drv, *tmp; |
824 | int err; | 832 | int err; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 8af302b425b3..099d5df8c572 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -2690,8 +2690,14 @@ static void request_modules(struct em28xx *dev) | |||
2690 | INIT_WORK(&dev->request_module_wk, request_module_async); | 2690 | INIT_WORK(&dev->request_module_wk, request_module_async); |
2691 | schedule_work(&dev->request_module_wk); | 2691 | schedule_work(&dev->request_module_wk); |
2692 | } | 2692 | } |
2693 | |||
2694 | static void flush_request_modules(struct em28xx *dev) | ||
2695 | { | ||
2696 | flush_work_sync(&dev->request_module_wk); | ||
2697 | } | ||
2693 | #else | 2698 | #else |
2694 | #define request_modules(dev) | 2699 | #define request_modules(dev) |
2700 | #define flush_request_modules(dev) | ||
2695 | #endif /* CONFIG_MODULES */ | 2701 | #endif /* CONFIG_MODULES */ |
2696 | 2702 | ||
2697 | /* | 2703 | /* |
@@ -3118,6 +3124,8 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
3118 | 3124 | ||
3119 | em28xx_info("disconnecting %s\n", dev->vdev->name); | 3125 | em28xx_info("disconnecting %s\n", dev->vdev->name); |
3120 | 3126 | ||
3127 | flush_request_modules(dev); | ||
3128 | |||
3121 | /* wait until all current v4l2 io is finished then deallocate | 3129 | /* wait until all current v4l2 io is finished then deallocate |
3122 | resources */ | 3130 | resources */ |
3123 | mutex_lock(&dev->lock); | 3131 | mutex_lock(&dev->lock); |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 29cc74441a7d..ba1ba8648c81 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -551,7 +551,7 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev) | |||
551 | { | 551 | { |
552 | if (dev->sbutton_input_dev != NULL) { | 552 | if (dev->sbutton_input_dev != NULL) { |
553 | em28xx_info("Deregistering snapshot button\n"); | 553 | em28xx_info("Deregistering snapshot button\n"); |
554 | cancel_rearming_delayed_work(&dev->sbutton_query_work); | 554 | cancel_delayed_work_sync(&dev->sbutton_query_work); |
555 | input_unregister_device(dev->sbutton_input_dev); | 555 | input_unregister_device(dev->sbutton_input_dev); |
556 | dev->sbutton_input_dev = NULL; | 556 | dev->sbutton_input_dev = NULL; |
557 | } | 557 | } |
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 378b094aff16..017552762902 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c | |||
@@ -1198,7 +1198,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | |||
1198 | 1198 | ||
1199 | atomic_inc(&cam->reset_disable); | 1199 | atomic_inc(&cam->reset_disable); |
1200 | 1200 | ||
1201 | flush_scheduled_work(); | 1201 | flush_work_sync(&cam->sensor_reset_work); |
1202 | 1202 | ||
1203 | rval = videobuf_streamoff(q); | 1203 | rval = videobuf_streamoff(q); |
1204 | if (!rval) { | 1204 | if (!rval) { |
@@ -1512,7 +1512,7 @@ static int omap24xxcam_release(struct file *file) | |||
1512 | 1512 | ||
1513 | atomic_inc(&cam->reset_disable); | 1513 | atomic_inc(&cam->reset_disable); |
1514 | 1514 | ||
1515 | flush_scheduled_work(); | 1515 | flush_work_sync(&cam->sensor_reset_work); |
1516 | 1516 | ||
1517 | /* stop streaming capture */ | 1517 | /* stop streaming capture */ |
1518 | videobuf_streamoff(&fh->vbq); | 1518 | videobuf_streamoff(&fh->vbq); |
@@ -1536,7 +1536,7 @@ static int omap24xxcam_release(struct file *file) | |||
1536 | * not be scheduled anymore since streaming is already | 1536 | * not be scheduled anymore since streaming is already |
1537 | * disabled.) | 1537 | * disabled.) |
1538 | */ | 1538 | */ |
1539 | flush_scheduled_work(); | 1539 | flush_work_sync(&cam->sensor_reset_work); |
1540 | 1540 | ||
1541 | mutex_lock(&cam->mutex); | 1541 | mutex_lock(&cam->mutex); |
1542 | if (atomic_dec_return(&cam->users) == 0) { | 1542 | if (atomic_dec_return(&cam->users) == 0) { |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 756a27812260..6abeecff6da7 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -166,8 +166,14 @@ static void request_submodules(struct saa7134_dev *dev) | |||
166 | schedule_work(&dev->request_module_wk); | 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 | #else | 174 | #else |
170 | #define request_submodules(dev) | 175 | #define request_submodules(dev) |
176 | #define flush_request_submodules(dev) | ||
171 | #endif /* CONFIG_MODULES */ | 177 | #endif /* CONFIG_MODULES */ |
172 | 178 | ||
173 | /* ------------------------------------------------------------------ */ | 179 | /* ------------------------------------------------------------------ */ |
@@ -1010,8 +1016,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1010 | } | 1016 | } |
1011 | } | 1017 | } |
1012 | 1018 | ||
1013 | request_submodules(dev); | ||
1014 | |||
1015 | v4l2_prio_init(&dev->prio); | 1019 | v4l2_prio_init(&dev->prio); |
1016 | 1020 | ||
1017 | mutex_lock(&saa7134_devlist_lock); | 1021 | mutex_lock(&saa7134_devlist_lock); |
@@ -1066,6 +1070,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1066 | if (saa7134_dmasound_init && !dev->dmasound.priv_data) | 1070 | if (saa7134_dmasound_init && !dev->dmasound.priv_data) |
1067 | saa7134_dmasound_init(dev); | 1071 | saa7134_dmasound_init(dev); |
1068 | 1072 | ||
1073 | request_submodules(dev); | ||
1069 | return 0; | 1074 | return 0; |
1070 | 1075 | ||
1071 | fail4: | 1076 | fail4: |
@@ -1091,6 +1096,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1091 | struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); | 1096 | struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); |
1092 | struct saa7134_mpeg_ops *mops; | 1097 | struct saa7134_mpeg_ops *mops; |
1093 | 1098 | ||
1099 | flush_request_submodules(dev); | ||
1100 | |||
1094 | /* Release DMA sound modules if present */ | 1101 | /* Release DMA sound modules if present */ |
1095 | if (saa7134_dmasound_exit && dev->dmasound.priv_data) { | 1102 | if (saa7134_dmasound_exit && dev->dmasound.priv_data) { |
1096 | saa7134_dmasound_exit(dev); | 1103 | saa7134_dmasound_exit(dev); |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index b890aafe7d64..6b8459c7728e 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -553,7 +553,7 @@ static int empress_fini(struct saa7134_dev *dev) | |||
553 | 553 | ||
554 | if (NULL == dev->empress_dev) | 554 | if (NULL == dev->empress_dev) |
555 | return 0; | 555 | return 0; |
556 | flush_scheduled_work(); | 556 | flush_work_sync(&dev->empress_workqueue); |
557 | video_unregister_device(dev->empress_dev); | 557 | video_unregister_device(dev->empress_dev); |
558 | dev->empress_dev = NULL; | 558 | dev->empress_dev = NULL; |
559 | return 0; | 559 | return 0; |
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index 4ba85bbdb4c1..9cee8e7f0bcb 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c | |||
@@ -1259,7 +1259,7 @@ static int menelaus_probe(struct i2c_client *client, | |||
1259 | return 0; | 1259 | return 0; |
1260 | fail2: | 1260 | fail2: |
1261 | free_irq(client->irq, menelaus); | 1261 | free_irq(client->irq, menelaus); |
1262 | flush_scheduled_work(); | 1262 | flush_work_sync(&menelaus->work); |
1263 | fail1: | 1263 | fail1: |
1264 | kfree(menelaus); | 1264 | kfree(menelaus); |
1265 | return err; | 1265 | return err; |
@@ -1270,6 +1270,7 @@ static int __exit menelaus_remove(struct i2c_client *client) | |||
1270 | struct menelaus_chip *menelaus = i2c_get_clientdata(client); | 1270 | struct menelaus_chip *menelaus = i2c_get_clientdata(client); |
1271 | 1271 | ||
1272 | free_irq(client->irq, menelaus); | 1272 | free_irq(client->irq, menelaus); |
1273 | flush_work_sync(&menelaus->work); | ||
1273 | kfree(menelaus); | 1274 | kfree(menelaus); |
1274 | the_menelaus = NULL; | 1275 | the_menelaus = NULL; |
1275 | return 0; | 1276 | return 0; |
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index d0016b67d125..90187fe33e04 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c | |||
@@ -242,7 +242,7 @@ static int dbg_show(struct seq_file *s, void *_) | |||
242 | seq_printf(s, "mask2 %s\n", buf); | 242 | seq_printf(s, "mask2 %s\n", buf); |
243 | /* ignore ackint2 */ | 243 | /* ignore ackint2 */ |
244 | 244 | ||
245 | (void) schedule_delayed_work(&tps->work, POWER_POLL_DELAY); | 245 | schedule_delayed_work(&tps->work, POWER_POLL_DELAY); |
246 | 246 | ||
247 | 247 | ||
248 | /* VMAIN voltage, enable lowpower, etc */ | 248 | /* VMAIN voltage, enable lowpower, etc */ |
@@ -400,7 +400,7 @@ static void tps65010_interrupt(struct tps65010 *tps) | |||
400 | && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))) | 400 | && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))) |
401 | poll = 1; | 401 | poll = 1; |
402 | if (poll) | 402 | if (poll) |
403 | (void) schedule_delayed_work(&tps->work, POWER_POLL_DELAY); | 403 | schedule_delayed_work(&tps->work, POWER_POLL_DELAY); |
404 | 404 | ||
405 | /* also potentially gpio-in rise or fall */ | 405 | /* also potentially gpio-in rise or fall */ |
406 | } | 406 | } |
@@ -410,7 +410,7 @@ static void tps65010_work(struct work_struct *work) | |||
410 | { | 410 | { |
411 | struct tps65010 *tps; | 411 | struct tps65010 *tps; |
412 | 412 | ||
413 | tps = container_of(work, struct tps65010, work.work); | 413 | tps = container_of(to_delayed_work(work), struct tps65010, work); |
414 | mutex_lock(&tps->lock); | 414 | mutex_lock(&tps->lock); |
415 | 415 | ||
416 | tps65010_interrupt(tps); | 416 | tps65010_interrupt(tps); |
@@ -448,7 +448,7 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) | |||
448 | 448 | ||
449 | disable_irq_nosync(irq); | 449 | disable_irq_nosync(irq); |
450 | set_bit(FLAG_IRQ_ENABLE, &tps->flags); | 450 | set_bit(FLAG_IRQ_ENABLE, &tps->flags); |
451 | (void) schedule_work(&tps->work.work); | 451 | schedule_delayed_work(&tps->work, 0); |
452 | return IRQ_HANDLED; | 452 | return IRQ_HANDLED; |
453 | } | 453 | } |
454 | 454 | ||
@@ -527,8 +527,7 @@ static int __exit tps65010_remove(struct i2c_client *client) | |||
527 | } | 527 | } |
528 | if (client->irq > 0) | 528 | if (client->irq > 0) |
529 | free_irq(client->irq, tps); | 529 | free_irq(client->irq, tps); |
530 | cancel_delayed_work(&tps->work); | 530 | cancel_delayed_work_sync(&tps->work); |
531 | flush_scheduled_work(); | ||
532 | debugfs_remove(tps->file); | 531 | debugfs_remove(tps->file); |
533 | kfree(tps); | 532 | kfree(tps); |
534 | the_tps = NULL; | 533 | the_tps = NULL; |
@@ -720,7 +719,7 @@ int tps65010_set_vbus_draw(unsigned mA) | |||
720 | && test_and_set_bit( | 719 | && test_and_set_bit( |
721 | FLAG_VBUS_CHANGED, &the_tps->flags)) { | 720 | FLAG_VBUS_CHANGED, &the_tps->flags)) { |
722 | /* gadget drivers call this in_irq() */ | 721 | /* gadget drivers call this in_irq() */ |
723 | (void) schedule_work(&the_tps->work.work); | 722 | schedule_delayed_work(&the_tps->work, 0); |
724 | } | 723 | } |
725 | local_irq_restore(flags); | 724 | local_irq_restore(flags); |
726 | 725 | ||
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 193206602d88..668d41e594a9 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c | |||
@@ -273,13 +273,11 @@ ioc4_variant(struct ioc4_driver_data *idd) | |||
273 | static void __devinit | 273 | static void __devinit |
274 | ioc4_load_modules(struct work_struct *work) | 274 | ioc4_load_modules(struct work_struct *work) |
275 | { | 275 | { |
276 | /* arg just has to be freed */ | ||
277 | |||
278 | request_module("sgiioc4"); | 276 | request_module("sgiioc4"); |
279 | |||
280 | kfree(work); | ||
281 | } | 277 | } |
282 | 278 | ||
279 | static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules); | ||
280 | |||
283 | /* Adds a new instance of an IOC4 card */ | 281 | /* Adds a new instance of an IOC4 card */ |
284 | static int __devinit | 282 | static int __devinit |
285 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | 283 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) |
@@ -396,21 +394,12 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
396 | * PCI device. | 394 | * PCI device. |
397 | */ | 395 | */ |
398 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { | 396 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { |
399 | struct work_struct *work; | 397 | /* Request the module from a work procedure as the modprobe |
400 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | 398 | * goes out to a userland helper and that will hang if done |
401 | if (!work) { | 399 | * directly from ioc4_probe(). |
402 | printk(KERN_WARNING | 400 | */ |
403 | "%s: IOC4 unable to allocate memory for " | 401 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); |
404 | "load of sub-modules.\n", __func__); | 402 | schedule_work(&ioc4_load_modules_work); |
405 | } else { | ||
406 | /* Request the module from a work procedure as the | ||
407 | * modprobe goes out to a userland helper and that | ||
408 | * will hang if done directly from ioc4_probe(). | ||
409 | */ | ||
410 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); | ||
411 | INIT_WORK(work, ioc4_load_modules); | ||
412 | schedule_work(work); | ||
413 | } | ||
414 | } | 403 | } |
415 | 404 | ||
416 | return 0; | 405 | return 0; |
@@ -498,7 +487,7 @@ static void __exit | |||
498 | ioc4_exit(void) | 487 | ioc4_exit(void) |
499 | { | 488 | { |
500 | /* Ensure ioc4_load_modules() has completed before exiting */ | 489 | /* Ensure ioc4_load_modules() has completed before exiting */ |
501 | flush_scheduled_work(); | 490 | flush_work_sync(&ioc4_load_modules_work); |
502 | pci_unregister_driver(&ioc4_driver); | 491 | pci_unregister_driver(&ioc4_driver); |
503 | } | 492 | } |
504 | 493 | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 57dcf8fa774a..a3a780faf85a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1790,7 +1790,7 @@ static int __init mmc_init(void) | |||
1790 | { | 1790 | { |
1791 | int ret; | 1791 | int ret; |
1792 | 1792 | ||
1793 | workqueue = create_singlethread_workqueue("kmmcd"); | 1793 | workqueue = alloc_ordered_workqueue("kmmcd", 0); |
1794 | if (!workqueue) | 1794 | if (!workqueue) |
1795 | return -ENOMEM; | 1795 | return -ENOMEM; |
1796 | 1796 | ||
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 0c7e37f496ef..379d2ffe4c87 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -173,6 +173,8 @@ struct mmc_omap_host { | |||
173 | struct omap_mmc_platform_data *pdata; | 173 | struct omap_mmc_platform_data *pdata; |
174 | }; | 174 | }; |
175 | 175 | ||
176 | static struct workqueue_struct *mmc_omap_wq; | ||
177 | |||
176 | static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot) | 178 | static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot) |
177 | { | 179 | { |
178 | unsigned long tick_ns; | 180 | unsigned long tick_ns; |
@@ -289,7 +291,7 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled) | |||
289 | host->next_slot = new_slot; | 291 | host->next_slot = new_slot; |
290 | host->mmc = new_slot->mmc; | 292 | host->mmc = new_slot->mmc; |
291 | spin_unlock_irqrestore(&host->slot_lock, flags); | 293 | spin_unlock_irqrestore(&host->slot_lock, flags); |
292 | schedule_work(&host->slot_release_work); | 294 | queue_work(mmc_omap_wq, &host->slot_release_work); |
293 | return; | 295 | return; |
294 | } | 296 | } |
295 | 297 | ||
@@ -457,7 +459,7 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) | |||
457 | } | 459 | } |
458 | 460 | ||
459 | host->stop_data = data; | 461 | host->stop_data = data; |
460 | schedule_work(&host->send_stop_work); | 462 | queue_work(mmc_omap_wq, &host->send_stop_work); |
461 | } | 463 | } |
462 | 464 | ||
463 | static void | 465 | static void |
@@ -637,7 +639,7 @@ mmc_omap_cmd_timer(unsigned long data) | |||
637 | OMAP_MMC_WRITE(host, IE, 0); | 639 | OMAP_MMC_WRITE(host, IE, 0); |
638 | disable_irq(host->irq); | 640 | disable_irq(host->irq); |
639 | host->abort = 1; | 641 | host->abort = 1; |
640 | schedule_work(&host->cmd_abort_work); | 642 | queue_work(mmc_omap_wq, &host->cmd_abort_work); |
641 | } | 643 | } |
642 | spin_unlock_irqrestore(&host->slot_lock, flags); | 644 | spin_unlock_irqrestore(&host->slot_lock, flags); |
643 | } | 645 | } |
@@ -826,7 +828,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
826 | host->abort = 1; | 828 | host->abort = 1; |
827 | OMAP_MMC_WRITE(host, IE, 0); | 829 | OMAP_MMC_WRITE(host, IE, 0); |
828 | disable_irq_nosync(host->irq); | 830 | disable_irq_nosync(host->irq); |
829 | schedule_work(&host->cmd_abort_work); | 831 | queue_work(mmc_omap_wq, &host->cmd_abort_work); |
830 | return IRQ_HANDLED; | 832 | return IRQ_HANDLED; |
831 | } | 833 | } |
832 | 834 | ||
@@ -1387,7 +1389,7 @@ static void mmc_omap_remove_slot(struct mmc_omap_slot *slot) | |||
1387 | 1389 | ||
1388 | tasklet_kill(&slot->cover_tasklet); | 1390 | tasklet_kill(&slot->cover_tasklet); |
1389 | del_timer_sync(&slot->cover_timer); | 1391 | del_timer_sync(&slot->cover_timer); |
1390 | flush_scheduled_work(); | 1392 | flush_workqueue(mmc_omap_wq); |
1391 | 1393 | ||
1392 | mmc_remove_host(mmc); | 1394 | mmc_remove_host(mmc); |
1393 | mmc_free_host(mmc); | 1395 | mmc_free_host(mmc); |
@@ -1608,12 +1610,22 @@ static struct platform_driver mmc_omap_driver = { | |||
1608 | 1610 | ||
1609 | static int __init mmc_omap_init(void) | 1611 | static int __init mmc_omap_init(void) |
1610 | { | 1612 | { |
1611 | return platform_driver_probe(&mmc_omap_driver, mmc_omap_probe); | 1613 | int ret; |
1614 | |||
1615 | mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); | ||
1616 | if (!mmc_omap_wq) | ||
1617 | return -ENOMEM; | ||
1618 | |||
1619 | ret = platform_driver_probe(&mmc_omap_driver, mmc_omap_probe); | ||
1620 | if (ret) | ||
1621 | destroy_workqueue(mmc_omap_wq); | ||
1622 | return ret; | ||
1612 | } | 1623 | } |
1613 | 1624 | ||
1614 | static void __exit mmc_omap_exit(void) | 1625 | static void __exit mmc_omap_exit(void) |
1615 | { | 1626 | { |
1616 | platform_driver_unregister(&mmc_omap_driver); | 1627 | platform_driver_unregister(&mmc_omap_driver); |
1628 | destroy_workqueue(mmc_omap_wq); | ||
1617 | } | 1629 | } |
1618 | 1630 | ||
1619 | module_init(mmc_omap_init); | 1631 | module_init(mmc_omap_init); |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5d46021cbb57..078fdf11af03 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -2290,7 +2290,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
2290 | free_irq(host->irq, host); | 2290 | free_irq(host->irq, host); |
2291 | if (mmc_slot(host).card_detect_irq) | 2291 | if (mmc_slot(host).card_detect_irq) |
2292 | free_irq(mmc_slot(host).card_detect_irq, host); | 2292 | free_irq(mmc_slot(host).card_detect_irq, host); |
2293 | flush_scheduled_work(); | 2293 | flush_work_sync(&host->mmc_carddetect_work); |
2294 | 2294 | ||
2295 | mmc_host_disable(host->mmc); | 2295 | mmc_host_disable(host->mmc); |
2296 | clk_disable(host->iclk); | 2296 | clk_disable(host->iclk); |
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c index 4c6028512d10..a683fd3bb624 100644 --- a/drivers/net/chelsio/my3126.c +++ b/drivers/net/chelsio/my3126.c | |||
@@ -22,7 +22,7 @@ static int my3126_interrupt_enable(struct cphy *cphy) | |||
22 | 22 | ||
23 | static int my3126_interrupt_disable(struct cphy *cphy) | 23 | static int my3126_interrupt_disable(struct cphy *cphy) |
24 | { | 24 | { |
25 | cancel_rearming_delayed_work(&cphy->phy_update); | 25 | cancel_delayed_work_sync(&cphy->phy_update); |
26 | return 0; | 26 | return 0; |
27 | } | 27 | } |
28 | 28 | ||
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 8f11d29a5828..6d9275c52e05 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -1279,7 +1279,7 @@ static void emac_force_link_update(struct emac_instance *dev) | |||
1279 | netif_carrier_off(dev->ndev); | 1279 | netif_carrier_off(dev->ndev); |
1280 | smp_rmb(); | 1280 | smp_rmb(); |
1281 | if (dev->link_polling) { | 1281 | if (dev->link_polling) { |
1282 | cancel_rearming_delayed_work(&dev->link_work); | 1282 | cancel_delayed_work_sync(&dev->link_work); |
1283 | if (dev->link_polling) | 1283 | if (dev->link_polling) |
1284 | schedule_delayed_work(&dev->link_work, PHY_POLL_LINK_OFF); | 1284 | schedule_delayed_work(&dev->link_work, PHY_POLL_LINK_OFF); |
1285 | } | 1285 | } |
@@ -1294,7 +1294,7 @@ static int emac_close(struct net_device *ndev) | |||
1294 | 1294 | ||
1295 | if (dev->phy.address >= 0) { | 1295 | if (dev->phy.address >= 0) { |
1296 | dev->link_polling = 0; | 1296 | dev->link_polling = 0; |
1297 | cancel_rearming_delayed_work(&dev->link_work); | 1297 | cancel_delayed_work_sync(&dev->link_work); |
1298 | } | 1298 | } |
1299 | mutex_lock(&dev->link_lock); | 1299 | mutex_lock(&dev->link_lock); |
1300 | emac_netif_stop(dev); | 1300 | emac_netif_stop(dev); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 43307bd42a69..6107304cb94c 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -1207,7 +1207,6 @@ static void housekeeping_enable(struct zd_mac *mac) | |||
1207 | static void housekeeping_disable(struct zd_mac *mac) | 1207 | static void housekeeping_disable(struct zd_mac *mac) |
1208 | { | 1208 | { |
1209 | dev_dbg_f(zd_mac_dev(mac), "\n"); | 1209 | dev_dbg_f(zd_mac_dev(mac), "\n"); |
1210 | cancel_rearming_delayed_workqueue(zd_workqueue, | 1210 | cancel_delayed_work_sync(&mac->housekeeping.link_led_work); |
1211 | &mac->housekeeping.link_led_work); | ||
1212 | zd_chip_control_leds(&mac->chip, ZD_LED_OFF); | 1211 | zd_chip_control_leds(&mac->chip, ZD_LED_OFF); |
1213 | } | 1212 | } |
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index b3c01c16a164..e7f89785beef 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c | |||
@@ -580,10 +580,8 @@ static int ds2760_battery_remove(struct platform_device *pdev) | |||
580 | { | 580 | { |
581 | struct ds2760_device_info *di = platform_get_drvdata(pdev); | 581 | struct ds2760_device_info *di = platform_get_drvdata(pdev); |
582 | 582 | ||
583 | cancel_rearming_delayed_workqueue(di->monitor_wqueue, | 583 | cancel_delayed_work_sync(&di->monitor_work); |
584 | &di->monitor_work); | 584 | cancel_delayed_work_sync(&di->set_charged_work); |
585 | cancel_rearming_delayed_workqueue(di->monitor_wqueue, | ||
586 | &di->set_charged_work); | ||
587 | destroy_workqueue(di->monitor_wqueue); | 585 | destroy_workqueue(di->monitor_wqueue); |
588 | power_supply_unregister(&di->bat); | 586 | power_supply_unregister(&di->bat); |
589 | kfree(di); | 587 | kfree(di); |
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index 2a10cd361181..36cf402c0677 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c | |||
@@ -730,8 +730,7 @@ static __devinit int probe(int irq, struct device *dev) | |||
730 | power_reg_failed_1: | 730 | power_reg_failed_1: |
731 | power_supply_unregister(&pbi->batt); | 731 | power_supply_unregister(&pbi->batt); |
732 | power_reg_failed: | 732 | power_reg_failed: |
733 | cancel_rearming_delayed_workqueue(pbi->monitor_wqueue, | 733 | cancel_delayed_work_sync(&pbi->monitor_battery); |
734 | &pbi->monitor_battery); | ||
735 | requestirq_failed: | 734 | requestirq_failed: |
736 | destroy_workqueue(pbi->monitor_wqueue); | 735 | destroy_workqueue(pbi->monitor_wqueue); |
737 | wqueue_failed: | 736 | wqueue_failed: |
@@ -760,8 +759,7 @@ static int __devexit platform_pmic_battery_remove(struct platform_device *pdev) | |||
760 | struct pmic_power_module_info *pbi = dev_get_drvdata(&pdev->dev); | 759 | struct pmic_power_module_info *pbi = dev_get_drvdata(&pdev->dev); |
761 | 760 | ||
762 | free_irq(pbi->irq, pbi); | 761 | free_irq(pbi->irq, pbi); |
763 | cancel_rearming_delayed_workqueue(pbi->monitor_wqueue, | 762 | cancel_delayed_work_sync(&pbi->monitor_battery); |
764 | &pbi->monitor_battery); | ||
765 | destroy_workqueue(pbi->monitor_wqueue); | 763 | destroy_workqueue(pbi->monitor_wqueue); |
766 | 764 | ||
767 | power_supply_unregister(&pbi->usb); | 765 | power_supply_unregister(&pbi->usb); |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 62227cd52410..0cc0984d155b 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -104,7 +104,7 @@ static int clear_uie(struct rtc_device *rtc) | |||
104 | } | 104 | } |
105 | if (rtc->uie_task_active) { | 105 | if (rtc->uie_task_active) { |
106 | spin_unlock_irq(&rtc->irq_lock); | 106 | spin_unlock_irq(&rtc->irq_lock); |
107 | flush_scheduled_work(); | 107 | flush_work_sync(&rtc->uie_task); |
108 | spin_lock_irq(&rtc->irq_lock); | 108 | spin_lock_irq(&rtc->irq_lock); |
109 | } | 109 | } |
110 | rtc->uie_irq_active = 0; | 110 | rtc->uie_irq_active = 0; |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 48da85e97ca4..077af1d7b9e4 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -813,7 +813,7 @@ static int __devexit ds1305_remove(struct spi_device *spi) | |||
813 | if (spi->irq) { | 813 | if (spi->irq) { |
814 | set_bit(FLAG_EXITING, &ds1305->flags); | 814 | set_bit(FLAG_EXITING, &ds1305->flags); |
815 | free_irq(spi->irq, ds1305); | 815 | free_irq(spi->irq, ds1305); |
816 | flush_scheduled_work(); | 816 | cancel_work_sync(&ds1305->work); |
817 | } | 817 | } |
818 | 818 | ||
819 | rtc_device_unregister(ds1305->rtc); | 819 | rtc_device_unregister(ds1305->rtc); |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 1f0007fd4431..47fb6357c346 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -417,7 +417,7 @@ static int __devexit ds1374_remove(struct i2c_client *client) | |||
417 | mutex_unlock(&ds1374->mutex); | 417 | mutex_unlock(&ds1374->mutex); |
418 | 418 | ||
419 | free_irq(client->irq, client); | 419 | free_irq(client->irq, client); |
420 | flush_scheduled_work(); | 420 | cancel_work_sync(&ds1374->work); |
421 | } | 421 | } |
422 | 422 | ||
423 | rtc_device_unregister(ds1374->rtc); | 423 | rtc_device_unregister(ds1374->rtc); |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 57063552d3b7..23a9ee19764c 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -463,7 +463,7 @@ static int __devexit ds3232_remove(struct i2c_client *client) | |||
463 | mutex_unlock(&ds3232->mutex); | 463 | mutex_unlock(&ds3232->mutex); |
464 | 464 | ||
465 | free_irq(client->irq, client); | 465 | free_irq(client->irq, client); |
466 | flush_scheduled_work(); | 466 | cancel_work_sync(&ds3232->work); |
467 | } | 467 | } |
468 | 468 | ||
469 | rtc_device_unregister(ds3232->rtc); | 469 | rtc_device_unregister(ds3232->rtc); |
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 1146e3522d3c..af32a62e12a8 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
@@ -650,7 +650,7 @@ static int __devexit rx8025_remove(struct i2c_client *client) | |||
650 | mutex_unlock(lock); | 650 | mutex_unlock(lock); |
651 | 651 | ||
652 | free_irq(client->irq, client); | 652 | free_irq(client->irq, client); |
653 | flush_scheduled_work(); | 653 | cancel_work_sync(&rx8025->work); |
654 | } | 654 | } |
655 | 655 | ||
656 | rx8025_sysfs_unregister(&client->dev); | 656 | rx8025_sysfs_unregister(&client->dev); |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index deff2c3361e4..fbe361fcd2c0 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include "tape_std.h" | 24 | #include "tape_std.h" |
25 | #include "tape_3590.h" | 25 | #include "tape_3590.h" |
26 | 26 | ||
27 | static struct workqueue_struct *tape_3590_wq; | ||
28 | |||
27 | /* | 29 | /* |
28 | * Pointer to debug area. | 30 | * Pointer to debug area. |
29 | */ | 31 | */ |
@@ -613,7 +615,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op) | |||
613 | p->device = tape_get_device(device); | 615 | p->device = tape_get_device(device); |
614 | p->op = op; | 616 | p->op = op; |
615 | 617 | ||
616 | schedule_work(&p->work); | 618 | queue_work(tape_3590_wq, &p->work); |
617 | return 0; | 619 | return 0; |
618 | } | 620 | } |
619 | 621 | ||
@@ -1629,7 +1631,7 @@ fail_kmalloc: | |||
1629 | static void | 1631 | static void |
1630 | tape_3590_cleanup_device(struct tape_device *device) | 1632 | tape_3590_cleanup_device(struct tape_device *device) |
1631 | { | 1633 | { |
1632 | flush_scheduled_work(); | 1634 | flush_workqueue(tape_3590_wq); |
1633 | tape_std_unassign(device); | 1635 | tape_std_unassign(device); |
1634 | 1636 | ||
1635 | kfree(device->discdata); | 1637 | kfree(device->discdata); |
@@ -1733,11 +1735,17 @@ tape_3590_init(void) | |||
1733 | #endif | 1735 | #endif |
1734 | 1736 | ||
1735 | DBF_EVENT(3, "3590 init\n"); | 1737 | DBF_EVENT(3, "3590 init\n"); |
1738 | |||
1739 | tape_3590_wq = alloc_workqueue("tape_3590", 0, 0); | ||
1740 | if (!tape_3590_wq) | ||
1741 | return -ENOMEM; | ||
1742 | |||
1736 | /* Register driver for 3590 tapes. */ | 1743 | /* Register driver for 3590 tapes. */ |
1737 | rc = ccw_driver_register(&tape_3590_driver); | 1744 | rc = ccw_driver_register(&tape_3590_driver); |
1738 | if (rc) | 1745 | if (rc) { |
1746 | destroy_workqueue(tape_3590_wq); | ||
1739 | DBF_EVENT(3, "3590 init failed\n"); | 1747 | DBF_EVENT(3, "3590 init failed\n"); |
1740 | else | 1748 | } else |
1741 | DBF_EVENT(3, "3590 registered\n"); | 1749 | DBF_EVENT(3, "3590 registered\n"); |
1742 | return rc; | 1750 | return rc; |
1743 | } | 1751 | } |
@@ -1746,7 +1754,7 @@ static void | |||
1746 | tape_3590_exit(void) | 1754 | tape_3590_exit(void) |
1747 | { | 1755 | { |
1748 | ccw_driver_unregister(&tape_3590_driver); | 1756 | ccw_driver_unregister(&tape_3590_driver); |
1749 | 1757 | destroy_workqueue(tape_3590_wq); | |
1750 | debug_unregister(TAPE_DBF_AREA); | 1758 | debug_unregister(TAPE_DBF_AREA); |
1751 | } | 1759 | } |
1752 | 1760 | ||
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index f0fa9ca5cb2c..55d2d0f4eabc 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -264,7 +264,7 @@ cleanup_queue: | |||
264 | void | 264 | void |
265 | tapeblock_cleanup_device(struct tape_device *device) | 265 | tapeblock_cleanup_device(struct tape_device *device) |
266 | { | 266 | { |
267 | flush_scheduled_work(); | 267 | flush_work_sync(&device->blk_data.requeue_task); |
268 | tape_put_device(device); | 268 | tape_put_device(device); |
269 | 269 | ||
270 | if (!device->blk_data.disk) { | 270 | if (!device->blk_data.disk) { |
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index cc8d2840f9b6..56d3a4e5622f 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c | |||
@@ -1325,8 +1325,8 @@ static void pohmelfs_put_super(struct super_block *sb) | |||
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | psb->trans_scan_timeout = psb->drop_scan_timeout = 0; | 1327 | psb->trans_scan_timeout = psb->drop_scan_timeout = 0; |
1328 | cancel_rearming_delayed_work(&psb->dwork); | 1328 | cancel_delayed_work_sync(&psb->dwork); |
1329 | cancel_rearming_delayed_work(&psb->drop_dwork); | 1329 | cancel_delayed_work_sync(&psb->drop_dwork); |
1330 | flush_scheduled_work(); | 1330 | flush_scheduled_work(); |
1331 | 1331 | ||
1332 | dprintk("%s: stopped workqueues.\n", __func__); | 1332 | dprintk("%s: stopped workqueues.\n", __func__); |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index f383cb42b1d7..a845f8b8382f 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -1247,7 +1247,7 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, | |||
1247 | mutex_unlock(&instance->poll_state_serialize); | 1247 | mutex_unlock(&instance->poll_state_serialize); |
1248 | 1248 | ||
1249 | if (is_polling) | 1249 | if (is_polling) |
1250 | cancel_rearming_delayed_work(&instance->poll_work); | 1250 | cancel_delayed_work_sync(&instance->poll_work); |
1251 | 1251 | ||
1252 | usb_kill_urb(instance->snd_urb); | 1252 | usb_kill_urb(instance->snd_urb); |
1253 | usb_kill_urb(instance->rcv_urb); | 1253 | usb_kill_urb(instance->rcv_urb); |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 4716e707de59..0842cfbf60cf 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -139,7 +139,8 @@ struct speedtch_instance_data { | |||
139 | 139 | ||
140 | struct speedtch_params params; /* set in probe, constant afterwards */ | 140 | struct speedtch_params params; /* set in probe, constant afterwards */ |
141 | 141 | ||
142 | struct delayed_work status_checker; | 142 | struct timer_list status_check_timer; |
143 | struct work_struct status_check_work; | ||
143 | 144 | ||
144 | unsigned char last_status; | 145 | unsigned char last_status; |
145 | 146 | ||
@@ -498,7 +499,7 @@ static void speedtch_check_status(struct work_struct *work) | |||
498 | { | 499 | { |
499 | struct speedtch_instance_data *instance = | 500 | struct speedtch_instance_data *instance = |
500 | container_of(work, struct speedtch_instance_data, | 501 | container_of(work, struct speedtch_instance_data, |
501 | status_checker.work); | 502 | status_check_work); |
502 | struct usbatm_data *usbatm = instance->usbatm; | 503 | struct usbatm_data *usbatm = instance->usbatm; |
503 | struct atm_dev *atm_dev = usbatm->atm_dev; | 504 | struct atm_dev *atm_dev = usbatm->atm_dev; |
504 | unsigned char *buf = instance->scratch_buffer; | 505 | unsigned char *buf = instance->scratch_buffer; |
@@ -575,11 +576,11 @@ static void speedtch_status_poll(unsigned long data) | |||
575 | { | 576 | { |
576 | struct speedtch_instance_data *instance = (void *)data; | 577 | struct speedtch_instance_data *instance = (void *)data; |
577 | 578 | ||
578 | schedule_delayed_work(&instance->status_checker, 0); | 579 | schedule_work(&instance->status_check_work); |
579 | 580 | ||
580 | /* The following check is racy, but the race is harmless */ | 581 | /* The following check is racy, but the race is harmless */ |
581 | if (instance->poll_delay < MAX_POLL_DELAY) | 582 | if (instance->poll_delay < MAX_POLL_DELAY) |
582 | mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(instance->poll_delay)); | 583 | mod_timer(&instance->status_check_timer, jiffies + msecs_to_jiffies(instance->poll_delay)); |
583 | else | 584 | else |
584 | atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n"); | 585 | atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n"); |
585 | } | 586 | } |
@@ -595,7 +596,7 @@ static void speedtch_resubmit_int(unsigned long data) | |||
595 | if (int_urb) { | 596 | if (int_urb) { |
596 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); | 597 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); |
597 | if (!ret) | 598 | if (!ret) |
598 | schedule_delayed_work(&instance->status_checker, 0); | 599 | schedule_work(&instance->status_check_work); |
599 | else { | 600 | else { |
600 | atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); | 601 | atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); |
601 | mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); | 602 | mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); |
@@ -624,7 +625,7 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
624 | } | 625 | } |
625 | 626 | ||
626 | if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) { | 627 | if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) { |
627 | del_timer(&instance->status_checker.timer); | 628 | del_timer(&instance->status_check_timer); |
628 | atm_info(usbatm, "DSL line goes up\n"); | 629 | atm_info(usbatm, "DSL line goes up\n"); |
629 | } else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) { | 630 | } else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) { |
630 | atm_info(usbatm, "DSL line goes down\n"); | 631 | atm_info(usbatm, "DSL line goes down\n"); |
@@ -640,7 +641,7 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
640 | 641 | ||
641 | if ((int_urb = instance->int_urb)) { | 642 | if ((int_urb = instance->int_urb)) { |
642 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); | 643 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); |
643 | schedule_delayed_work(&instance->status_checker, 0); | 644 | schedule_work(&instance->status_check_work); |
644 | if (ret < 0) { | 645 | if (ret < 0) { |
645 | atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); | 646 | atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); |
646 | goto fail; | 647 | goto fail; |
@@ -686,7 +687,7 @@ static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_de | |||
686 | } | 687 | } |
687 | 688 | ||
688 | /* Start status polling */ | 689 | /* Start status polling */ |
689 | mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(1000)); | 690 | mod_timer(&instance->status_check_timer, jiffies + msecs_to_jiffies(1000)); |
690 | 691 | ||
691 | return 0; | 692 | return 0; |
692 | } | 693 | } |
@@ -698,7 +699,7 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de | |||
698 | 699 | ||
699 | atm_dbg(usbatm, "%s entered\n", __func__); | 700 | atm_dbg(usbatm, "%s entered\n", __func__); |
700 | 701 | ||
701 | del_timer_sync(&instance->status_checker.timer); | 702 | del_timer_sync(&instance->status_check_timer); |
702 | 703 | ||
703 | /* | 704 | /* |
704 | * Since resubmit_timer and int_urb can schedule themselves and | 705 | * Since resubmit_timer and int_urb can schedule themselves and |
@@ -717,7 +718,7 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de | |||
717 | del_timer_sync(&instance->resubmit_timer); | 718 | del_timer_sync(&instance->resubmit_timer); |
718 | usb_free_urb(int_urb); | 719 | usb_free_urb(int_urb); |
719 | 720 | ||
720 | flush_scheduled_work(); | 721 | flush_work_sync(&instance->status_check_work); |
721 | } | 722 | } |
722 | 723 | ||
723 | static int speedtch_pre_reset(struct usb_interface *intf) | 724 | static int speedtch_pre_reset(struct usb_interface *intf) |
@@ -869,10 +870,11 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
869 | 870 | ||
870 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); | 871 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); |
871 | 872 | ||
872 | INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status); | 873 | INIT_WORK(&instance->status_check_work, speedtch_check_status); |
874 | init_timer(&instance->status_check_timer); | ||
873 | 875 | ||
874 | instance->status_checker.timer.function = speedtch_status_poll; | 876 | instance->status_check_timer.function = speedtch_status_poll; |
875 | instance->status_checker.timer.data = (unsigned long)instance; | 877 | instance->status_check_timer.data = (unsigned long)instance; |
876 | instance->last_status = 0xff; | 878 | instance->last_status = 0xff; |
877 | instance->poll_delay = MIN_POLL_DELAY; | 879 | instance->poll_delay = MIN_POLL_DELAY; |
878 | 880 | ||
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index e3454fe46b47..1eda968b5644 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -839,11 +839,9 @@ void gether_cleanup(void) | |||
839 | return; | 839 | return; |
840 | 840 | ||
841 | unregister_netdev(the_dev->net); | 841 | unregister_netdev(the_dev->net); |
842 | flush_work_sync(&the_dev->work); | ||
842 | free_netdev(the_dev->net); | 843 | free_netdev(the_dev->net); |
843 | 844 | ||
844 | /* assuming we used keventd, it must quiesce too */ | ||
845 | flush_scheduled_work(); | ||
846 | |||
847 | the_dev = NULL; | 845 | the_dev = NULL; |
848 | } | 846 | } |
849 | 847 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9751647665df..759a12ff8048 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -901,7 +901,8 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
901 | 901 | ||
902 | ohci_dump (ohci, 1); | 902 | ohci_dump (ohci, 1); |
903 | 903 | ||
904 | flush_scheduled_work(); | 904 | if (quirk_nec(ohci)) |
905 | flush_work_sync(&ohci->nec_work); | ||
905 | 906 | ||
906 | ohci_usb_reset (ohci); | 907 | ohci_usb_reset (ohci); |
907 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 908 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 456969492410..e00fa1b22ecd 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c | |||
@@ -1247,7 +1247,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c) | |||
1247 | isp->timer.data = 0; | 1247 | isp->timer.data = 0; |
1248 | set_bit(WORK_STOP, &isp->todo); | 1248 | set_bit(WORK_STOP, &isp->todo); |
1249 | del_timer_sync(&isp->timer); | 1249 | del_timer_sync(&isp->timer); |
1250 | flush_scheduled_work(); | 1250 | flush_work_sync(&isp->work); |
1251 | 1251 | ||
1252 | put_device(&i2c->dev); | 1252 | put_device(&i2c->dev); |
1253 | the_transceiver = NULL; | 1253 | the_transceiver = NULL; |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index e199b0f4f99c..5be866bb7a41 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -613,9 +613,8 @@ static void oti6858_close(struct usb_serial_port *port) | |||
613 | dbg("%s(): after buf_clear()", __func__); | 613 | dbg("%s(): after buf_clear()", __func__); |
614 | 614 | ||
615 | /* cancel scheduled setup */ | 615 | /* cancel scheduled setup */ |
616 | cancel_delayed_work(&priv->delayed_setup_work); | 616 | cancel_delayed_work_sync(&priv->delayed_setup_work); |
617 | cancel_delayed_work(&priv->delayed_write_work); | 617 | cancel_delayed_work_sync(&priv->delayed_write_work); |
618 | flush_scheduled_work(); | ||
619 | 618 | ||
620 | /* shutdown our urbs */ | 619 | /* shutdown our urbs */ |
621 | dbg("%s(): shutting down urbs", __func__); | 620 | dbg("%s(): shutting down urbs", __func__); |
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 6b93ef93cb12..804000183c5e 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
@@ -75,7 +75,7 @@ int fb_deferred_io_fsync(struct file *file, int datasync) | |||
75 | return 0; | 75 | return 0; |
76 | 76 | ||
77 | /* Kill off the delayed work */ | 77 | /* Kill off the delayed work */ |
78 | cancel_rearming_delayed_work(&info->deferred_work); | 78 | cancel_delayed_work_sync(&info->deferred_work); |
79 | 79 | ||
80 | /* Run it immediately */ | 80 | /* Run it immediately */ |
81 | return schedule_delayed_work(&info->deferred_work, 0); | 81 | return schedule_delayed_work(&info->deferred_work, 0); |
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c index 64dcc7439c99..90e3bdd1b7ab 100644 --- a/drivers/video/omap/lcd_mipid.c +++ b/drivers/video/omap/lcd_mipid.c | |||
@@ -396,7 +396,7 @@ static void mipid_esd_start_check(struct mipid_device *md) | |||
396 | static void mipid_esd_stop_check(struct mipid_device *md) | 396 | static void mipid_esd_stop_check(struct mipid_device *md) |
397 | { | 397 | { |
398 | if (md->esd_check != NULL) | 398 | if (md->esd_check != NULL) |
399 | cancel_rearming_delayed_workqueue(md->esd_wq, &md->esd_work); | 399 | cancel_delayed_work_sync(&md->esd_work); |
400 | } | 400 | } |
401 | 401 | ||
402 | static void mipid_esd_work(struct work_struct *work) | 402 | static void mipid_esd_work(struct work_struct *work) |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 9531c052d7a4..9b39a5dd4131 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -317,7 +317,12 @@ static void ncp_stop_tasks(struct ncp_server *server) { | |||
317 | sk->sk_write_space = server->write_space; | 317 | sk->sk_write_space = server->write_space; |
318 | release_sock(sk); | 318 | release_sock(sk); |
319 | del_timer_sync(&server->timeout_tm); | 319 | del_timer_sync(&server->timeout_tm); |
320 | flush_scheduled_work(); | 320 | |
321 | flush_work_sync(&server->rcv.tq); | ||
322 | if (sk->sk_socket->type == SOCK_STREAM) | ||
323 | flush_work_sync(&server->tx.tq); | ||
324 | else | ||
325 | flush_work_sync(&server->timeout_tq); | ||
321 | } | 326 | } |
322 | 327 | ||
323 | static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt) | 328 | static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt) |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 116cab970e0f..fbd18c3074bb 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -4336,7 +4336,7 @@ __nfs4_state_shutdown(void) | |||
4336 | void | 4336 | void |
4337 | nfs4_state_shutdown(void) | 4337 | nfs4_state_shutdown(void) |
4338 | { | 4338 | { |
4339 | cancel_rearming_delayed_workqueue(laundry_wq, &laundromat_work); | 4339 | cancel_delayed_work_sync(&laundromat_work); |
4340 | destroy_workqueue(laundry_wq); | 4340 | destroy_workqueue(laundry_wq); |
4341 | locks_end_grace(&nfsd4_manager); | 4341 | locks_end_grace(&nfsd4_manager); |
4342 | nfs4_lock_state(); | 4342 | nfs4_lock_state(); |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 9f26ac9be2a4..9e3d45bcb5fd 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -307,8 +307,7 @@ static void o2hb_arm_write_timeout(struct o2hb_region *reg) | |||
307 | 307 | ||
308 | static void o2hb_disarm_write_timeout(struct o2hb_region *reg) | 308 | static void o2hb_disarm_write_timeout(struct o2hb_region *reg) |
309 | { | 309 | { |
310 | cancel_delayed_work(®->hr_write_timeout_work); | 310 | cancel_delayed_work_sync(®->hr_write_timeout_work); |
311 | flush_scheduled_work(); | ||
312 | } | 311 | } |
313 | 312 | ||
314 | static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc) | 313 | static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc) |
diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index cf3e16696216..a87366750f23 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c | |||
@@ -325,5 +325,7 @@ void o2quo_init(void) | |||
325 | 325 | ||
326 | void o2quo_exit(void) | 326 | void o2quo_exit(void) |
327 | { | 327 | { |
328 | flush_scheduled_work(); | 328 | struct o2quo_state *qs = &o2quo_state; |
329 | |||
330 | flush_work_sync(&qs->qs_work); | ||
329 | } | 331 | } |
diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c index 45ce15dc5b2b..edfa178bafb6 100644 --- a/fs/xfs/xfs_mru_cache.c +++ b/fs/xfs/xfs_mru_cache.c | |||
@@ -408,7 +408,7 @@ xfs_mru_cache_flush( | |||
408 | spin_lock(&mru->lock); | 408 | spin_lock(&mru->lock); |
409 | if (mru->queued) { | 409 | if (mru->queued) { |
410 | spin_unlock(&mru->lock); | 410 | spin_unlock(&mru->lock); |
411 | cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work); | 411 | cancel_delayed_work_sync(&mru->work); |
412 | spin_lock(&mru->lock); | 412 | spin_lock(&mru->lock); |
413 | } | 413 | } |
414 | 414 | ||
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index bd257fee6031..1ac11586a2f5 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -409,7 +409,7 @@ static inline bool __cancel_delayed_work(struct delayed_work *work) | |||
409 | } | 409 | } |
410 | 410 | ||
411 | /* Obsolete. use cancel_delayed_work_sync() */ | 411 | /* Obsolete. use cancel_delayed_work_sync() */ |
412 | static inline | 412 | static inline __deprecated |
413 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, | 413 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, |
414 | struct delayed_work *work) | 414 | struct delayed_work *work) |
415 | { | 415 | { |
@@ -417,7 +417,7 @@ void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, | |||
417 | } | 417 | } |
418 | 418 | ||
419 | /* Obsolete. use cancel_delayed_work_sync() */ | 419 | /* Obsolete. use cancel_delayed_work_sync() */ |
420 | static inline | 420 | static inline __deprecated |
421 | void cancel_rearming_delayed_work(struct delayed_work *work) | 421 | void cancel_rearming_delayed_work(struct delayed_work *work) |
422 | { | 422 | { |
423 | cancel_delayed_work_sync(work); | 423 | cancel_delayed_work_sync(work); |
diff --git a/init/main.c b/init/main.c index ea51770c0170..00799c1d4628 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -777,9 +777,6 @@ static void __init do_initcalls(void) | |||
777 | 777 | ||
778 | for (fn = __early_initcall_end; fn < __initcall_end; fn++) | 778 | for (fn = __early_initcall_end; fn < __initcall_end; fn++) |
779 | do_one_initcall(*fn); | 779 | do_one_initcall(*fn); |
780 | |||
781 | /* Make sure there is no pending stuff from the initcall sequence */ | ||
782 | flush_scheduled_work(); | ||
783 | } | 780 | } |
784 | 781 | ||
785 | /* | 782 | /* |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index e785b0f2aea5..8ee6ec82f88a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -932,6 +932,38 @@ static void insert_work(struct cpu_workqueue_struct *cwq, | |||
932 | wake_up_worker(gcwq); | 932 | wake_up_worker(gcwq); |
933 | } | 933 | } |
934 | 934 | ||
935 | /* | ||
936 | * Test whether @work is being queued from another work executing on the | ||
937 | * same workqueue. This is rather expensive and should only be used from | ||
938 | * cold paths. | ||
939 | */ | ||
940 | static bool is_chained_work(struct workqueue_struct *wq) | ||
941 | { | ||
942 | unsigned long flags; | ||
943 | unsigned int cpu; | ||
944 | |||
945 | for_each_gcwq_cpu(cpu) { | ||
946 | struct global_cwq *gcwq = get_gcwq(cpu); | ||
947 | struct worker *worker; | ||
948 | struct hlist_node *pos; | ||
949 | int i; | ||
950 | |||
951 | spin_lock_irqsave(&gcwq->lock, flags); | ||
952 | for_each_busy_worker(worker, i, pos, gcwq) { | ||
953 | if (worker->task != current) | ||
954 | continue; | ||
955 | spin_unlock_irqrestore(&gcwq->lock, flags); | ||
956 | /* | ||
957 | * I'm @worker, no locking necessary. See if @work | ||
958 | * is headed to the same workqueue. | ||
959 | */ | ||
960 | return worker->current_cwq->wq == wq; | ||
961 | } | ||
962 | spin_unlock_irqrestore(&gcwq->lock, flags); | ||
963 | } | ||
964 | return false; | ||
965 | } | ||
966 | |||
935 | static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | 967 | static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, |
936 | struct work_struct *work) | 968 | struct work_struct *work) |
937 | { | 969 | { |
@@ -943,7 +975,9 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | |||
943 | 975 | ||
944 | debug_work_activate(work); | 976 | debug_work_activate(work); |
945 | 977 | ||
946 | if (WARN_ON_ONCE(wq->flags & WQ_DYING)) | 978 | /* if dying, only works from the same workqueue are allowed */ |
979 | if (unlikely(wq->flags & WQ_DYING) && | ||
980 | WARN_ON_ONCE(!is_chained_work(wq))) | ||
947 | return; | 981 | return; |
948 | 982 | ||
949 | /* determine gcwq to use */ | 983 | /* determine gcwq to use */ |
@@ -2936,11 +2970,35 @@ EXPORT_SYMBOL_GPL(__alloc_workqueue_key); | |||
2936 | */ | 2970 | */ |
2937 | void destroy_workqueue(struct workqueue_struct *wq) | 2971 | void destroy_workqueue(struct workqueue_struct *wq) |
2938 | { | 2972 | { |
2973 | unsigned int flush_cnt = 0; | ||
2939 | unsigned int cpu; | 2974 | unsigned int cpu; |
2940 | 2975 | ||
2976 | /* | ||
2977 | * Mark @wq dying and drain all pending works. Once WQ_DYING is | ||
2978 | * set, only chain queueing is allowed. IOW, only currently | ||
2979 | * pending or running work items on @wq can queue further work | ||
2980 | * items on it. @wq is flushed repeatedly until it becomes empty. | ||
2981 | * The number of flushing is detemined by the depth of chaining and | ||
2982 | * should be relatively short. Whine if it takes too long. | ||
2983 | */ | ||
2941 | wq->flags |= WQ_DYING; | 2984 | wq->flags |= WQ_DYING; |
2985 | reflush: | ||
2942 | flush_workqueue(wq); | 2986 | flush_workqueue(wq); |
2943 | 2987 | ||
2988 | for_each_cwq_cpu(cpu, wq) { | ||
2989 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); | ||
2990 | |||
2991 | if (!cwq->nr_active && list_empty(&cwq->delayed_works)) | ||
2992 | continue; | ||
2993 | |||
2994 | if (++flush_cnt == 10 || | ||
2995 | (flush_cnt % 100 == 0 && flush_cnt <= 1000)) | ||
2996 | printk(KERN_WARNING "workqueue %s: flush on " | ||
2997 | "destruction isn't complete after %u tries\n", | ||
2998 | wq->name, flush_cnt); | ||
2999 | goto reflush; | ||
3000 | } | ||
3001 | |||
2944 | /* | 3002 | /* |
2945 | * wq list is used to freeze wq, remove from list after | 3003 | * wq list is used to freeze wq, remove from list after |
2946 | * flushing is complete in case freeze races us. | 3004 | * flushing is complete in case freeze races us. |
@@ -1293,7 +1293,7 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1293 | * anything expensive but will only modify reap_work | 1293 | * anything expensive but will only modify reap_work |
1294 | * and reschedule the timer. | 1294 | * and reschedule the timer. |
1295 | */ | 1295 | */ |
1296 | cancel_rearming_delayed_work(&per_cpu(slab_reap_work, cpu)); | 1296 | cancel_delayed_work_sync(&per_cpu(slab_reap_work, cpu)); |
1297 | /* Now the cache_reaper is guaranteed to be not running. */ | 1297 | /* Now the cache_reaper is guaranteed to be not running. */ |
1298 | per_cpu(slab_reap_work, cpu).work.func = NULL; | 1298 | per_cpu(slab_reap_work, cpu).work.func = NULL; |
1299 | break; | 1299 | break; |
diff --git a/mm/vmstat.c b/mm/vmstat.c index 8f62f17ee1c7..33c33e7a0f9b 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -1033,7 +1033,7 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, | |||
1033 | break; | 1033 | break; |
1034 | case CPU_DOWN_PREPARE: | 1034 | case CPU_DOWN_PREPARE: |
1035 | case CPU_DOWN_PREPARE_FROZEN: | 1035 | case CPU_DOWN_PREPARE_FROZEN: |
1036 | cancel_rearming_delayed_work(&per_cpu(vmstat_work, cpu)); | 1036 | cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu)); |
1037 | per_cpu(vmstat_work, cpu).work.func = NULL; | 1037 | per_cpu(vmstat_work, cpu).work.func = NULL; |
1038 | break; | 1038 | break; |
1039 | case CPU_DOWN_FAILED: | 1039 | case CPU_DOWN_FAILED: |
diff --git a/net/atm/lec.c b/net/atm/lec.c index 179e04bc99dd..38754fdb88ba 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
@@ -1607,7 +1607,7 @@ static void lec_arp_destroy(struct lec_priv *priv) | |||
1607 | struct lec_arp_table *entry; | 1607 | struct lec_arp_table *entry; |
1608 | int i; | 1608 | int i; |
1609 | 1609 | ||
1610 | cancel_rearming_delayed_work(&priv->lec_arp_work); | 1610 | cancel_delayed_work_sync(&priv->lec_arp_work); |
1611 | 1611 | ||
1612 | /* | 1612 | /* |
1613 | * Remove all entries | 1613 | * Remove all entries |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 72d9b50109fc..02dc2cbcbe86 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -923,7 +923,7 @@ void __netpoll_cleanup(struct netpoll *np) | |||
923 | 923 | ||
924 | skb_queue_purge(&npinfo->arp_tx); | 924 | skb_queue_purge(&npinfo->arp_tx); |
925 | skb_queue_purge(&npinfo->txq); | 925 | skb_queue_purge(&npinfo->txq); |
926 | cancel_rearming_delayed_work(&npinfo->tx_work); | 926 | cancel_delayed_work_sync(&npinfo->tx_work); |
927 | 927 | ||
928 | /* clean after last, unfinished work */ | 928 | /* clean after last, unfinished work */ |
929 | __skb_queue_purge(&npinfo->txq); | 929 | __skb_queue_purge(&npinfo->txq); |
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 6112a12578b2..0c877a74e1f4 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -390,7 +390,7 @@ static int dsa_remove(struct platform_device *pdev) | |||
390 | if (dst->link_poll_needed) | 390 | if (dst->link_poll_needed) |
391 | del_timer_sync(&dst->link_poll_timer); | 391 | del_timer_sync(&dst->link_poll_timer); |
392 | 392 | ||
393 | flush_scheduled_work(); | 393 | flush_work_sync(&dst->link_poll_work); |
394 | 394 | ||
395 | for (i = 0; i < dst->pd->nr_chips; i++) { | 395 | for (i = 0; i < dst->pd->nr_chips; i++) { |
396 | struct dsa_switch *ds = dst->ds[i]; | 396 | struct dsa_switch *ds = dst->ds[i]; |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index c6f293639220..22f7ad5101ab 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -3430,7 +3430,7 @@ void ip_vs_control_cleanup(void) | |||
3430 | { | 3430 | { |
3431 | EnterFunction(2); | 3431 | EnterFunction(2); |
3432 | ip_vs_trash_cleanup(); | 3432 | ip_vs_trash_cleanup(); |
3433 | cancel_rearming_delayed_work(&defense_work); | 3433 | cancel_delayed_work_sync(&defense_work); |
3434 | cancel_work_sync(&defense_work.work); | 3434 | cancel_work_sync(&defense_work.work); |
3435 | ip_vs_kill_estimator(&ip_vs_stats); | 3435 | ip_vs_kill_estimator(&ip_vs_stats); |
3436 | unregister_sysctl_table(sysctl_header); | 3436 | unregister_sysctl_table(sysctl_header); |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index dfcab5ac65af..96549df836ee 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -770,7 +770,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
770 | 770 | ||
771 | dprintk("RPC: xs_destroy xprt %p\n", xprt); | 771 | dprintk("RPC: xs_destroy xprt %p\n", xprt); |
772 | 772 | ||
773 | cancel_rearming_delayed_work(&transport->connect_worker); | 773 | cancel_delayed_work_sync(&transport->connect_worker); |
774 | 774 | ||
775 | xs_close(xprt); | 775 | xs_close(xprt); |
776 | xs_free_peer_addresses(xprt); | 776 | xs_free_peer_addresses(xprt); |