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

media: Convert from tasklet to BH workqueue

The only generic interface to execute asynchronously in the BH context is
tasklet; however, it's marked deprecated and has some design flaws. To
replace tasklets, BH workqueue support was recently added. A BH workqueue
behaves similarly to regular workqueues except that the queued work items
are executed in the BH context.

This patch converts drivers/media/* from tasklet to BH workqueue.

Based on the work done by Tejun Heo <tj@kernel.org>

Signed-off-by: Allen Pais <allen.lkml@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

authored by

Allen Pais and committed by
Hans Verkuil
1021dd01 d2ae63c2

+141 -129
+4 -4
drivers/media/pci/bt8xx/bt878.c
··· 300 300 } 301 301 if (astat & BT878_ARISCI) { 302 302 bt->finished_block = (stat & BT878_ARISCS) >> 28; 303 - if (bt->tasklet.callback) 304 - tasklet_schedule(&bt->tasklet); 303 + if (bt->bh_work.func) 304 + queue_work(system_bh_wq, &bt->bh_work); 305 305 break; 306 306 } 307 307 count++; ··· 478 478 btwrite(0, BT878_AINT_MASK); 479 479 bt878_num++; 480 480 481 - if (!bt->tasklet.func) 482 - tasklet_disable(&bt->tasklet); 481 + if (!bt->bh_work.func) 482 + disable_work_sync(&bt->bh_work); 483 483 484 484 return 0; 485 485
+2 -1
drivers/media/pci/bt8xx/bt878.h
··· 14 14 #include <linux/sched.h> 15 15 #include <linux/spinlock.h> 16 16 #include <linux/mutex.h> 17 + #include <linux/workqueue.h> 17 18 18 19 #include "bt848.h" 19 20 #include "bttv.h" ··· 121 120 dma_addr_t risc_dma; 122 121 u32 risc_pos; 123 122 124 - struct tasklet_struct tasklet; 123 + struct work_struct bh_work; 125 124 int shutdown; 126 125 }; 127 126
+4 -4
drivers/media/pci/bt8xx/dvb-bt8xx.c
··· 39 39 40 40 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ 41 41 42 - static void dvb_bt8xx_task(struct tasklet_struct *t) 42 + static void dvb_bt8xx_work(struct work_struct *t) 43 43 { 44 - struct bt878 *bt = from_tasklet(bt, t, tasklet); 44 + struct bt878 *bt = from_work(bt, t, bh_work); 45 45 struct dvb_bt8xx_card *card = dev_get_drvdata(&bt->adapter->dev); 46 46 47 47 dprintk("%d\n", card->bt->finished_block); ··· 782 782 goto err_disconnect_frontend; 783 783 } 784 784 785 - tasklet_setup(&card->bt->tasklet, dvb_bt8xx_task); 785 + INIT_WORK(&card->bt->bh_work, dvb_bt8xx_work); 786 786 787 787 frontend_init(card, type); 788 788 ··· 922 922 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr); 923 923 924 924 bt878_stop(card->bt); 925 - tasklet_kill(&card->bt->tasklet); 925 + cancel_work_sync(&card->bt->bh_work); 926 926 dvb_net_release(&card->dvbnet); 927 927 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); 928 928 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
+1 -1
drivers/media/pci/ddbridge/ddbridge.h
··· 298 298 spinlock_t lock; /* lock link access */ 299 299 struct mutex flash_mutex; /* lock flash access */ 300 300 struct ddb_lnb lnb; 301 - struct tasklet_struct tasklet; 301 + struct work_struct bh_work; 302 302 struct ddb_ids ids; 303 303 304 304 spinlock_t temp_lock; /* lock temp chip access */
+1 -1
drivers/media/pci/mantis/hopper_cards.c
··· 116 116 if (stat & MANTIS_INT_RISCI) { 117 117 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 118 118 mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 119 - tasklet_schedule(&mantis->tasklet); 119 + queue_work(system_bh_wq, &mantis->bh_work); 120 120 } 121 121 if (stat & MANTIS_INT_I2CDONE) { 122 122 dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
+1 -1
drivers/media/pci/mantis/mantis_cards.c
··· 125 125 if (stat & MANTIS_INT_RISCI) { 126 126 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 127 127 mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 128 - tasklet_schedule(&mantis->tasklet); 128 + queue_work(system_bh_wq, &mantis->bh_work); 129 129 } 130 130 if (stat & MANTIS_INT_I2CDONE) { 131 131 dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
+1 -1
drivers/media/pci/mantis/mantis_common.h
··· 125 125 __le32 *risc_cpu; 126 126 dma_addr_t risc_dma; 127 127 128 - struct tasklet_struct tasklet; 128 + struct work_struct bh_work; 129 129 spinlock_t intmask_lock; 130 130 131 131 struct i2c_adapter adapter;
+2 -2
drivers/media/pci/mantis/mantis_dma.c
··· 200 200 } 201 201 202 202 203 - void mantis_dma_xfer(struct tasklet_struct *t) 203 + void mantis_dma_xfer(struct work_struct *t) 204 204 { 205 - struct mantis_pci *mantis = from_tasklet(mantis, t, tasklet); 205 + struct mantis_pci *mantis = from_work(mantis, t, bh_work); 206 206 struct mantis_hwconfig *config = mantis->hwconfig; 207 207 208 208 while (mantis->last_block != mantis->busy_block) {
+1 -1
drivers/media/pci/mantis/mantis_dma.h
··· 13 13 extern int mantis_dma_exit(struct mantis_pci *mantis); 14 14 extern void mantis_dma_start(struct mantis_pci *mantis); 15 15 extern void mantis_dma_stop(struct mantis_pci *mantis); 16 - extern void mantis_dma_xfer(struct tasklet_struct *t); 16 + extern void mantis_dma_xfer(struct work_struct *t); 17 17 18 18 #endif /* __MANTIS_DMA_H */
+6 -6
drivers/media/pci/mantis/mantis_dvb.c
··· 105 105 if (mantis->feeds == 1) { 106 106 dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); 107 107 mantis_dma_start(mantis); 108 - tasklet_enable(&mantis->tasklet); 108 + enable_and_queue_work(system_bh_wq, &mantis->bh_work); 109 109 } 110 110 111 111 return mantis->feeds; ··· 125 125 mantis->feeds--; 126 126 if (mantis->feeds == 0) { 127 127 dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); 128 - tasklet_disable(&mantis->tasklet); 128 + disable_work_sync(&mantis->bh_work); 129 129 mantis_dma_stop(mantis); 130 130 } 131 131 ··· 205 205 } 206 206 207 207 dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); 208 - tasklet_setup(&mantis->tasklet, mantis_dma_xfer); 209 - tasklet_disable(&mantis->tasklet); 208 + INIT_WORK(&mantis->bh_work, mantis_dma_xfer); 209 + disable_work_sync(&mantis->bh_work); 210 210 if (mantis->hwconfig) { 211 211 result = config->frontend_init(mantis, mantis->fe); 212 212 if (result < 0) { ··· 235 235 236 236 /* Error conditions .. */ 237 237 err5: 238 - tasklet_kill(&mantis->tasklet); 238 + cancel_work_sync(&mantis->bh_work); 239 239 dvb_net_release(&mantis->dvbnet); 240 240 if (mantis->fe) { 241 241 dvb_unregister_frontend(mantis->fe); ··· 273 273 dvb_frontend_detach(mantis->fe); 274 274 } 275 275 276 - tasklet_kill(&mantis->tasklet); 276 + cancel_work_sync(&mantis->bh_work); 277 277 dvb_net_release(&mantis->dvbnet); 278 278 279 279 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+11 -11
drivers/media/pci/ngene/ngene-core.c
··· 50 50 /* nGene interrupt handler **************************************************/ 51 51 /****************************************************************************/ 52 52 53 - static void event_tasklet(struct tasklet_struct *t) 53 + static void event_bh_work(struct work_struct *t) 54 54 { 55 - struct ngene *dev = from_tasklet(dev, t, event_tasklet); 55 + struct ngene *dev = from_work(dev, t, event_bh_work); 56 56 57 57 while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) { 58 58 struct EVENT_BUFFER Event = ··· 68 68 } 69 69 } 70 70 71 - static void demux_tasklet(struct tasklet_struct *t) 71 + static void demux_bh_work(struct work_struct *t) 72 72 { 73 - struct ngene_channel *chan = from_tasklet(chan, t, demux_tasklet); 73 + struct ngene_channel *chan = from_work(chan, t, demux_bh_work); 74 74 struct device *pdev = &chan->dev->pci_dev->dev; 75 75 struct SBufferHeader *Cur = chan->nextBuffer; 76 76 ··· 204 204 dev->EventQueueOverflowFlag = 1; 205 205 } 206 206 dev->EventBuffer->EventStatus &= ~0x80; 207 - tasklet_schedule(&dev->event_tasklet); 207 + queue_work(system_bh_wq, &dev->event_bh_work); 208 208 rc = IRQ_HANDLED; 209 209 } 210 210 ··· 217 217 ngeneBuffer.SR.Flags & 0xC0) == 0x80) { 218 218 dev->channel[i].nextBuffer-> 219 219 ngeneBuffer.SR.Flags |= 0x40; 220 - tasklet_schedule( 221 - &dev->channel[i].demux_tasklet); 220 + queue_work(system_bh_wq, 221 + &dev->channel[i].demux_bh_work); 222 222 rc = IRQ_HANDLED; 223 223 } 224 224 } ··· 1181 1181 struct device *pdev = &dev->pci_dev->dev; 1182 1182 int i; 1183 1183 1184 - tasklet_setup(&dev->event_tasklet, event_tasklet); 1184 + INIT_WORK(&dev->event_bh_work, event_bh_work); 1185 1185 1186 1186 memset_io(dev->iomem + 0xc000, 0x00, 0x220); 1187 1187 memset_io(dev->iomem + 0xc400, 0x00, 0x100); ··· 1395 1395 if (chan->running) 1396 1396 set_transfer(chan, 0); 1397 1397 1398 - tasklet_kill(&chan->demux_tasklet); 1398 + cancel_work_sync(&chan->demux_bh_work); 1399 1399 1400 1400 if (chan->ci_dev) { 1401 1401 dvb_unregister_device(chan->ci_dev); ··· 1445 1445 struct ngene_info *ni = dev->card_info; 1446 1446 int io = ni->io_type[nr]; 1447 1447 1448 - tasklet_setup(&chan->demux_tasklet, demux_tasklet); 1448 + INIT_WORK(&chan->demux_bh_work, demux_bh_work); 1449 1449 chan->users = 0; 1450 1450 chan->type = io; 1451 1451 chan->mode = chan->type; /* for now only one mode */ ··· 1649 1649 struct ngene *dev = pci_get_drvdata(pdev); 1650 1650 int i; 1651 1651 1652 - tasklet_kill(&dev->event_tasklet); 1652 + cancel_work_sync(&dev->event_bh_work); 1653 1653 for (i = MAX_STREAM - 1; i >= 0; i--) 1654 1654 release_channel(&dev->channel[i]); 1655 1655 if (dev->ci.en)
+3 -2
drivers/media/pci/ngene/ngene.h
··· 16 16 #include <linux/scatterlist.h> 17 17 18 18 #include <linux/dvb/frontend.h> 19 + #include <linux/workqueue.h> 19 20 20 21 #include <media/dmxdev.h> 21 22 #include <media/dvbdev.h> ··· 622 621 int users; 623 622 struct video_device *v4l_dev; 624 623 struct dvb_device *ci_dev; 625 - struct tasklet_struct demux_tasklet; 624 + struct work_struct demux_bh_work; 626 625 627 626 struct SBufferHeader *nextBuffer; 628 627 enum KSSTATE State; ··· 718 717 struct EVENT_BUFFER EventQueue[EVENT_QUEUE_SIZE]; 719 718 int EventQueueOverflowCount; 720 719 int EventQueueOverflowFlag; 721 - struct tasklet_struct event_tasklet; 720 + struct work_struct event_bh_work; 722 721 struct EVENT_BUFFER *EventBuffer; 723 722 int EventQueueWriteIndex; 724 723 int EventQueueReadIndex;
+9 -9
drivers/media/pci/smipcie/smipcie-main.c
··· 279 279 (port->_dmaInterruptCH0 | port->_dmaInterruptCH1)); 280 280 } 281 281 282 - /* tasklet handler: DMA data to dmx.*/ 283 - static void smi_dma_xfer(struct tasklet_struct *t) 282 + /* BH work handler: DMA data to dmx.*/ 283 + static void smi_dma_xfer(struct work_struct *t) 284 284 { 285 - struct smi_port *port = from_tasklet(port, t, tasklet); 285 + struct smi_port *port = from_work(port, t, bh_work); 286 286 struct smi_dev *dev = port->dev; 287 287 u32 intr_status, finishedData, dmaManagement; 288 288 u8 dmaChan0State, dmaChan1State; ··· 426 426 } 427 427 428 428 smi_port_disableInterrupt(port); 429 - tasklet_setup(&port->tasklet, smi_dma_xfer); 430 - tasklet_disable(&port->tasklet); 429 + INIT_WORK(&port->bh_work, smi_dma_xfer); 430 + disable_work_sync(&port->bh_work); 431 431 port->enable = 1; 432 432 return 0; 433 433 err: ··· 438 438 static void smi_port_exit(struct smi_port *port) 439 439 { 440 440 smi_port_disableInterrupt(port); 441 - tasklet_kill(&port->tasklet); 441 + cancel_work_sync(&port->bh_work); 442 442 smi_port_dma_free(port); 443 443 port->enable = 0; 444 444 } ··· 452 452 smi_port_disableInterrupt(port); 453 453 port->_int_status = int_status; 454 454 smi_port_clearInterrupt(port); 455 - tasklet_schedule(&port->tasklet); 455 + queue_work(system_bh_wq, &port->bh_work); 456 456 handled = 1; 457 457 } 458 458 return handled; ··· 823 823 smi_port_clearInterrupt(port); 824 824 smi_port_enableInterrupt(port); 825 825 smi_write(port->DMA_MANAGEMENT, dmaManagement); 826 - tasklet_enable(&port->tasklet); 826 + enable_and_queue_work(system_bh_wq, &port->bh_work); 827 827 } 828 828 return port->users; 829 829 } ··· 837 837 if (--port->users) 838 838 return port->users; 839 839 840 - tasklet_disable(&port->tasklet); 840 + disable_work_sync(&port->bh_work); 841 841 smi_port_disableInterrupt(port); 842 842 smi_clear(port->DMA_MANAGEMENT, 0x30003); 843 843 return 0;
+2 -1
drivers/media/pci/smipcie/smipcie.h
··· 17 17 #include <linux/pci.h> 18 18 #include <linux/dma-mapping.h> 19 19 #include <linux/slab.h> 20 + #include <linux/workqueue.h> 20 21 #include <media/rc-core.h> 21 22 22 23 #include <media/demux.h> ··· 258 257 u32 _dmaInterruptCH0; 259 258 u32 _dmaInterruptCH1; 260 259 u32 _int_status; 261 - struct tasklet_struct tasklet; 260 + struct work_struct bh_work; 262 261 /* dvb */ 263 262 struct dmx_frontend hw_frontend; 264 263 struct dmx_frontend mem_frontend;
+2 -1
drivers/media/pci/ttpci/budget-av.c
··· 36 36 #include <linux/interrupt.h> 37 37 #include <linux/input.h> 38 38 #include <linux/spinlock.h> 39 + #include <linux/workqueue.h> 39 40 40 41 #include <media/dvb_ca_en50221.h> 41 42 ··· 55 54 struct video_device vd; 56 55 int cur_input; 57 56 int has_saa7113; 58 - struct tasklet_struct ciintf_irq_tasklet; 57 + struct work_struct ciintf_irq_bh_work; 59 58 int slot_status; 60 59 struct dvb_ca_en50221 ca; 61 60 u8 reinitialise_demod:1;
+14 -13
drivers/media/pci/ttpci/budget-ci.c
··· 18 18 #include <linux/slab.h> 19 19 #include <linux/interrupt.h> 20 20 #include <linux/spinlock.h> 21 + #include <linux/workqueue.h> 21 22 #include <media/rc-core.h> 22 23 23 24 #include "budget.h" ··· 82 81 83 82 struct budget_ci_ir { 84 83 struct rc_dev *dev; 85 - struct tasklet_struct msp430_irq_tasklet; 84 + struct work_struct msp430_irq_bh_work; 86 85 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ 87 86 char phys[32]; 88 87 int rc5_device; ··· 93 92 94 93 struct budget_ci { 95 94 struct budget budget; 96 - struct tasklet_struct ciintf_irq_tasklet; 95 + struct work_struct ciintf_irq_bh_work; 97 96 int slot_status; 98 97 int ci_irq; 99 98 struct dvb_ca_en50221 ca; ··· 101 100 u8 tuner_pll_address; /* used for philips_tdm1316l configs */ 102 101 }; 103 102 104 - static void msp430_ir_interrupt(struct tasklet_struct *t) 103 + static void msp430_ir_interrupt(struct work_struct *t) 105 104 { 106 - struct budget_ci_ir *ir = from_tasklet(ir, t, msp430_irq_tasklet); 105 + struct budget_ci_ir *ir = from_work(ir, t, msp430_irq_bh_work); 107 106 struct budget_ci *budget_ci = container_of(ir, typeof(*budget_ci), ir); 108 107 struct rc_dev *dev = budget_ci->ir.dev; 109 108 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; ··· 232 231 233 232 budget_ci->ir.dev = dev; 234 233 235 - tasklet_setup(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt); 234 + INIT_WORK(&budget_ci->ir.msp430_irq_bh_work, msp430_ir_interrupt); 236 235 237 236 SAA7146_IER_ENABLE(saa, MASK_06); 238 237 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); ··· 246 245 247 246 SAA7146_IER_DISABLE(saa, MASK_06); 248 247 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 249 - tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); 248 + cancel_work_sync(&budget_ci->ir.msp430_irq_bh_work); 250 249 251 250 rc_unregister_device(budget_ci->ir.dev); 252 251 } ··· 350 349 return 0; 351 350 } 352 351 353 - static void ciintf_interrupt(struct tasklet_struct *t) 352 + static void ciintf_interrupt(struct work_struct *t) 354 353 { 355 - struct budget_ci *budget_ci = from_tasklet(budget_ci, t, 356 - ciintf_irq_tasklet); 354 + struct budget_ci *budget_ci = from_work(budget_ci, t, 355 + ciintf_irq_bh_work); 357 356 struct saa7146_dev *saa = budget_ci->budget.dev; 358 357 unsigned int flags; 359 358 ··· 492 491 493 492 // Setup CI slot IRQ 494 493 if (budget_ci->ci_irq) { 495 - tasklet_setup(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt); 494 + INIT_WORK(&budget_ci->ciintf_irq_bh_work, ciintf_interrupt); 496 495 if (budget_ci->slot_status != SLOTSTATUS_NONE) 497 496 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); 498 497 else ··· 531 530 if (budget_ci->ci_irq) { 532 531 SAA7146_IER_DISABLE(saa, MASK_03); 533 532 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); 534 - tasklet_kill(&budget_ci->ciintf_irq_tasklet); 533 + cancel_work_sync(&budget_ci->ciintf_irq_bh_work); 535 534 } 536 535 537 536 // reset interface ··· 557 556 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci); 558 557 559 558 if (*isr & MASK_06) 560 - tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet); 559 + queue_work(system_bh_wq, &budget_ci->ir.msp430_irq_bh_work); 561 560 562 561 if (*isr & MASK_10) 563 562 ttpci_budget_irq10_handler(dev, isr); 564 563 565 564 if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) 566 - tasklet_schedule(&budget_ci->ciintf_irq_tasklet); 565 + queue_work(system_bh_wq, &budget_ci->ciintf_irq_bh_work); 567 566 } 568 567 569 568 static u8 philips_su1278_tt_inittab[] = {
+5 -5
drivers/media/pci/ttpci/budget-core.c
··· 172 172 return ret; 173 173 } 174 174 175 - static void vpeirq(struct tasklet_struct *t) 175 + static void vpeirq(struct work_struct *t) 176 176 { 177 - struct budget *budget = from_tasklet(budget, t, vpe_tasklet); 177 + struct budget *budget = from_work(budget, t, vpe_bh_work); 178 178 u8 *mem = (u8 *) (budget->grabbing); 179 179 u32 olddma = budget->ttbp; 180 180 u32 newdma = saa7146_read(budget->dev, PCI_VDP3); ··· 525 525 /* upload all */ 526 526 saa7146_write(dev, GPIO_CTRL, 0x000000); 527 527 528 - tasklet_setup(&budget->vpe_tasklet, vpeirq); 528 + INIT_WORK(&budget->vpe_bh_work, vpeirq); 529 529 530 530 /* frontend power on */ 531 531 if (bi->type != BUDGET_FS_ACTIVY) ··· 565 565 566 566 budget_unregister(budget); 567 567 568 - tasklet_kill(&budget->vpe_tasklet); 568 + cancel_work_sync(&budget->vpe_bh_work); 569 569 570 570 saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); 571 571 ··· 584 584 dprintk(8, "dev: %p, budget: %p\n", dev, budget); 585 585 586 586 if (*isr & MASK_10) 587 - tasklet_schedule(&budget->vpe_tasklet); 587 + queue_work(system_bh_wq, &budget->vpe_bh_work); 588 588 } 589 589 EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); 590 590
+3 -2
drivers/media/pci/ttpci/budget.h
··· 18 18 19 19 #include <linux/module.h> 20 20 #include <linux/mutex.h> 21 + #include <linux/workqueue.h> 21 22 22 23 #include <media/drv-intf/saa7146.h> 23 24 ··· 55 54 unsigned char *grabbing; 56 55 struct saa7146_pgtable pt; 57 56 58 - struct tasklet_struct fidb_tasklet; 59 - struct tasklet_struct vpe_tasklet; 57 + struct work_struct fidb_bh_work; 58 + struct work_struct vpe_bh_work; 60 59 61 60 struct dmxdev dmxdev; 62 61 struct dvb_demux demux;
+1 -1
drivers/media/pci/tw5864/tw5864-core.c
··· 144 144 cur_frame->gop_seqno = input->frame_gop_seqno; 145 145 146 146 dev->h264_buf_w_index = next_frame_index; 147 - tasklet_schedule(&dev->tasklet); 147 + queue_work(system_bh_wq, &dev->bh_work); 148 148 149 149 cur_frame = next_frame; 150 150
+7 -6
drivers/media/pci/tw5864/tw5864-video.c
··· 6 6 */ 7 7 8 8 #include <linux/module.h> 9 + #include <linux/workqueue.h> 9 10 #include <media/v4l2-common.h> 10 11 #include <media/v4l2-event.h> 11 12 #include <media/videobuf2-dma-contig.h> ··· 176 175 static v4l2_std_id tw5864_get_v4l2_std(enum tw5864_vid_std std); 177 176 static enum tw5864_vid_std tw5864_from_v4l2_std(v4l2_std_id v4l2_std); 178 177 179 - static void tw5864_handle_frame_task(struct tasklet_struct *t); 178 + static void tw5864_handle_frame_work(struct work_struct *t); 180 179 static void tw5864_handle_frame(struct tw5864_h264_frame *frame); 181 180 static void tw5864_frame_interval_set(struct tw5864_input *input); 182 181 ··· 1063 1062 dev->irqmask |= TW5864_INTR_VLC_DONE | TW5864_INTR_TIMER; 1064 1063 tw5864_irqmask_apply(dev); 1065 1064 1066 - tasklet_setup(&dev->tasklet, tw5864_handle_frame_task); 1065 + INIT_WORK(&dev->bh_work, tw5864_handle_frame_work); 1067 1066 1068 1067 for (i = 0; i < TW5864_INPUTS; i++) { 1069 1068 dev->inputs[i].root = dev; ··· 1080 1079 for (i = last_input_nr_registered; i >= 0; i--) 1081 1080 tw5864_video_input_fini(&dev->inputs[i]); 1082 1081 1083 - tasklet_kill(&dev->tasklet); 1082 + cancel_work_sync(&dev->bh_work); 1084 1083 1085 1084 free_dma: 1086 1085 for (i = last_dma_allocated; i >= 0; i--) { ··· 1199 1198 { 1200 1199 int i; 1201 1200 1202 - tasklet_kill(&dev->tasklet); 1201 + cancel_work_sync(&dev->bh_work); 1203 1202 1204 1203 for (i = 0; i < TW5864_INPUTS; i++) 1205 1204 tw5864_video_input_fini(&dev->inputs[i]); ··· 1316 1315 return detected; 1317 1316 } 1318 1317 1319 - static void tw5864_handle_frame_task(struct tasklet_struct *t) 1318 + static void tw5864_handle_frame_work(struct work_struct *t) 1320 1319 { 1321 - struct tw5864_dev *dev = from_tasklet(dev, t, tasklet); 1320 + struct tw5864_dev *dev = from_work(dev, t, bh_work); 1322 1321 unsigned long flags; 1323 1322 int batch_size = H264_BUF_CNT; 1324 1323
+4 -3
drivers/media/pci/tw5864/tw5864.h
··· 12 12 #include <linux/mutex.h> 13 13 #include <linux/io.h> 14 14 #include <linux/interrupt.h> 15 + #include <linux/workqueue.h> 15 16 16 17 #include <media/v4l2-common.h> 17 18 #include <media/v4l2-ioctl.h> ··· 86 85 int nr; /* input number */ 87 86 struct tw5864_dev *root; 88 87 struct mutex lock; /* used for vidq and vdev */ 89 - spinlock_t slock; /* used for sync between ISR, tasklet & V4L2 API */ 88 + spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */ 90 89 struct video_device vdev; 91 90 struct v4l2_ctrl_handler hdl; 92 91 struct vb2_queue vidq; ··· 143 142 144 143 /* global device status */ 145 144 struct tw5864_dev { 146 - spinlock_t slock; /* used for sync between ISR, tasklet & V4L2 API */ 145 + spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */ 147 146 struct v4l2_device v4l2_dev; 148 147 struct tw5864_input inputs[TW5864_INPUTS]; 149 148 #define H264_BUF_CNT 4 ··· 151 150 int h264_buf_r_index; 152 151 int h264_buf_w_index; 153 152 154 - struct tasklet_struct tasklet; 153 + struct work_struct bh_work; 155 154 156 155 int encoder_busy; 157 156 /* Input number to check next for ready raw picture (in RR fashion) */
+8 -7
drivers/media/platform/intel/pxa_camera.c
··· 43 43 #include <linux/videodev2.h> 44 44 45 45 #include <linux/platform_data/media/camera-pxa.h> 46 + #include <linux/workqueue.h> 46 47 47 48 #define PXA_CAM_VERSION "0.0.6" 48 49 #define PXA_CAM_DRV_NAME "pxa27x-camera" ··· 684 683 unsigned int buf_sequence; 685 684 686 685 struct pxa_buffer *active; 687 - struct tasklet_struct task_eof; 686 + struct work_struct eof_bh_work; 688 687 689 688 u32 save_cicr[5]; 690 689 }; ··· 1147 1146 clk_disable_unprepare(pcdev->clk); 1148 1147 } 1149 1148 1150 - static void pxa_camera_eof(struct tasklet_struct *t) 1149 + static void pxa_camera_eof_bh_work(struct work_struct *t) 1151 1150 { 1152 - struct pxa_camera_dev *pcdev = from_tasklet(pcdev, t, task_eof); 1151 + struct pxa_camera_dev *pcdev = from_work(pcdev, t, eof_bh_work); 1153 1152 unsigned long cifr; 1154 1153 struct pxa_buffer *buf; 1155 1154 ··· 1186 1185 if (status & CISR_EOF) { 1187 1186 cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM; 1188 1187 __raw_writel(cicr0, pcdev->base + CICR0); 1189 - tasklet_schedule(&pcdev->task_eof); 1188 + queue_work(system_bh_wq, &pcdev->eof_bh_work); 1190 1189 } 1191 1190 1192 1191 return IRQ_HANDLED; ··· 2384 2383 } 2385 2384 } 2386 2385 2387 - tasklet_setup(&pcdev->task_eof, pxa_camera_eof); 2386 + INIT_WORK(&pcdev->eof_bh_work, pxa_camera_eof_bh_work); 2388 2387 2389 2388 pxa_camera_activate(pcdev); 2390 2389 ··· 2410 2409 return 0; 2411 2410 exit_deactivate: 2412 2411 pxa_camera_deactivate(pcdev); 2413 - tasklet_kill(&pcdev->task_eof); 2412 + cancel_work_sync(&pcdev->eof_bh_work); 2414 2413 exit_free_dma: 2415 2414 dma_release_channel(pcdev->dma_chans[2]); 2416 2415 exit_free_dma_u: ··· 2429 2428 struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); 2430 2429 2431 2430 pxa_camera_deactivate(pcdev); 2432 - tasklet_kill(&pcdev->task_eof); 2431 + cancel_work_sync(&pcdev->eof_bh_work); 2433 2432 dma_release_channel(pcdev->dma_chans[0]); 2434 2433 dma_release_channel(pcdev->dma_chans[1]); 2435 2434 dma_release_channel(pcdev->dma_chans[2]);
+4 -4
drivers/media/platform/marvell/mcam-core.c
··· 439 439 /* 440 440 * Copy data out to user space in the vmalloc case 441 441 */ 442 - static void mcam_frame_tasklet(struct tasklet_struct *t) 442 + static void mcam_frame_work(struct work_struct *t) 443 443 { 444 - struct mcam_camera *cam = from_tasklet(cam, t, s_tasklet); 444 + struct mcam_camera *cam = from_work(cam, t, s_bh_work); 445 445 int i; 446 446 unsigned long flags; 447 447 struct mcam_vb_buffer *buf; ··· 493 493 494 494 static void mcam_vmalloc_done(struct mcam_camera *cam, int frame) 495 495 { 496 - tasklet_schedule(&cam->s_tasklet); 496 + queue_work(system_bh_wq, &cam->s_bh_work); 497 497 } 498 498 499 499 #else /* MCAM_MODE_VMALLOC */ ··· 1305 1305 break; 1306 1306 case B_vmalloc: 1307 1307 #ifdef MCAM_MODE_VMALLOC 1308 - tasklet_setup(&cam->s_tasklet, mcam_frame_tasklet); 1308 + INIT_WORK(&cam->s_bh_work, mcam_frame_work); 1309 1309 vq->ops = &mcam_vb2_ops; 1310 1310 vq->mem_ops = &vb2_vmalloc_memops; 1311 1311 cam->dma_setup = mcam_ctlr_dma_vmalloc;
+2 -1
drivers/media/platform/marvell/mcam-core.h
··· 9 9 10 10 #include <linux/list.h> 11 11 #include <linux/clk-provider.h> 12 + #include <linux/workqueue.h> 12 13 #include <media/v4l2-common.h> 13 14 #include <media/v4l2-ctrls.h> 14 15 #include <media/v4l2-dev.h> ··· 168 167 unsigned int dma_buf_size; /* allocated size */ 169 168 void *dma_bufs[MAX_DMA_BUFS]; /* Internal buffer addresses */ 170 169 dma_addr_t dma_handles[MAX_DMA_BUFS]; /* Buffer bus addresses */ 171 - struct tasklet_struct s_tasklet; 170 + struct work_struct s_bh_work; 172 171 #endif 173 172 unsigned int sequence; /* Frame sequence number */ 174 173 unsigned int buf_seq[MAX_DMA_BUFS]; /* Sequence for individual bufs */
+7 -7
drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
··· 72 72 73 73 /* is this descriptor initialised and TP enabled */ 74 74 if (channel->irec && readl(channel->irec + DMA_PRDS_TPENABLE)) 75 - tasklet_schedule(&channel->tsklet); 75 + queue_work(system_bh_wq, &channel->bh_work); 76 76 } 77 77 78 78 fei->timer.expires = jiffies + msecs_to_jiffies(POLL_MSECS); 79 79 add_timer(&fei->timer); 80 80 } 81 81 82 - static void channel_swdemux_tsklet(struct tasklet_struct *t) 82 + static void channel_swdemux_bh_work(struct work_struct *t) 83 83 { 84 - struct channel_info *channel = from_tasklet(channel, t, tsklet); 84 + struct channel_info *channel = from_work(channel, t, bh_work); 85 85 struct c8sectpfei *fei; 86 86 unsigned long wp, rp; 87 87 int pos, num_packets, n, size; ··· 210 210 211 211 dev_dbg(fei->dev, "Starting channel=%p\n", channel); 212 212 213 - tasklet_setup(&channel->tsklet, channel_swdemux_tsklet); 213 + INIT_WORK(&channel->bh_work, channel_swdemux_bh_work); 214 214 215 215 /* Reset the internal inputblock sram pointers */ 216 216 writel(channel->fifo, ··· 303 303 /* disable this channels descriptor */ 304 304 writel(0, channel->irec + DMA_PRDS_TPENABLE); 305 305 306 - tasklet_disable(&channel->tsklet); 306 + disable_work_sync(&channel->bh_work); 307 307 308 308 /* now request memdma channel goes idle */ 309 309 idlereq = (1 << channel->tsin_id) | IDLEREQ; ··· 630 630 writel(tsin->back_buffer_busaddr, tsin->irec + DMA_PRDS_BUSWP_TP(0)); 631 631 writel(tsin->back_buffer_busaddr, tsin->irec + DMA_PRDS_BUSRP_TP(0)); 632 632 633 - /* initialize tasklet */ 634 - tasklet_setup(&tsin->tsklet, channel_swdemux_tsklet); 633 + /* initialize bh work */ 634 + INIT_WORK(&tsin->bh_work, channel_swdemux_bh_work); 635 635 636 636 return 0; 637 637
+1 -1
drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.h
··· 51 51 unsigned long fifo; 52 52 53 53 struct completion idle_completion; 54 - struct tasklet_struct tsklet; 54 + struct work_struct bh_work; 55 55 56 56 struct c8sectpfei *fei; 57 57 void __iomem *irec;
+3 -2
drivers/media/radio/wl128x/fmdrv.h
··· 15 15 #include <sound/core.h> 16 16 #include <sound/initval.h> 17 17 #include <linux/timer.h> 18 + #include <linux/workqueue.h> 18 19 #include <media/v4l2-ioctl.h> 19 20 #include <media/v4l2-common.h> 20 21 #include <media/v4l2-device.h> ··· 201 200 int streg_cbdata; /* status of ST registration */ 202 201 203 202 struct sk_buff_head rx_q; /* RX queue */ 204 - struct tasklet_struct rx_task; /* RX Tasklet */ 203 + struct work_struct rx_bh_work; /* RX BH Work */ 205 204 206 205 struct sk_buff_head tx_q; /* TX queue */ 207 - struct tasklet_struct tx_task; /* TX Tasklet */ 206 + struct work_struct tx_bh_work; /* TX BH Work */ 208 207 unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */ 209 208 atomic_t tx_cnt; /* Number of packets can send at a time */ 210 209
+20 -20
drivers/media/radio/wl128x/fmdrv_common.c
··· 9 9 * one Channel-8 command to be sent to the chip). 10 10 * 2) Sending each Channel-8 command to the chip and reading 11 11 * response back over Shared Transport. 12 - * 3) Managing TX and RX Queues and Tasklets. 12 + * 3) Managing TX and RX Queues and BH bh Works. 13 13 * 4) Handling FM Interrupt packet and taking appropriate action. 14 14 * 5) Loading FM firmware to the chip (common, FM TX, and FM RX 15 15 * firmware files based on mode selection) ··· 244 244 } 245 245 246 246 /* 247 - * FM common sub-module will schedule this tasklet whenever it receives 247 + * FM common sub-module will queue this bh work whenever it receives 248 248 * FM packet from ST driver. 249 249 */ 250 - static void recv_tasklet(struct tasklet_struct *t) 250 + static void recv_bh_work(struct work_struct *t) 251 251 { 252 252 struct fmdev *fmdev; 253 253 struct fm_irq *irq_info; ··· 256 256 u8 num_fm_hci_cmds; 257 257 unsigned long flags; 258 258 259 - fmdev = from_tasklet(fmdev, t, tx_task); 259 + fmdev = from_work(fmdev, t, tx_bh_work); 260 260 irq_info = &fmdev->irq_info; 261 261 /* Process all packets in the RX queue */ 262 262 while ((skb = skb_dequeue(&fmdev->rx_q))) { ··· 322 322 323 323 /* 324 324 * Check flow control field. If Num_FM_HCI_Commands field is 325 - * not zero, schedule FM TX tasklet. 325 + * not zero, queue FM TX bh work. 326 326 */ 327 327 if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt)) 328 328 if (!skb_queue_empty(&fmdev->tx_q)) 329 - tasklet_schedule(&fmdev->tx_task); 329 + queue_work(system_bh_wq, &fmdev->tx_bh_work); 330 330 } 331 331 } 332 332 333 - /* FM send tasklet: is scheduled when FM packet has to be sent to chip */ 334 - static void send_tasklet(struct tasklet_struct *t) 333 + /* FM send_bh_work: is scheduled when FM packet has to be sent to chip */ 334 + static void send_bh_work(struct work_struct *t) 335 335 { 336 336 struct fmdev *fmdev; 337 337 struct sk_buff *skb; 338 338 int len; 339 339 340 - fmdev = from_tasklet(fmdev, t, tx_task); 340 + fmdev = from_work(fmdev, t, tx_bh_work); 341 341 342 342 if (!atomic_read(&fmdev->tx_cnt)) 343 343 return; ··· 366 366 if (len < 0) { 367 367 kfree_skb(skb); 368 368 fmdev->resp_comp = NULL; 369 - fmerr("TX tasklet failed to send skb(%p)\n", skb); 369 + fmerr("TX bh work failed to send skb(%p)\n", skb); 370 370 atomic_set(&fmdev->tx_cnt, 1); 371 371 } else { 372 372 fmdev->last_tx_jiffies = jiffies; ··· 374 374 } 375 375 376 376 /* 377 - * Queues FM Channel-8 packet to FM TX queue and schedules FM TX tasklet for 377 + * Queues FM Channel-8 packet to FM TX queue and schedules FM TX bh work for 378 378 * transmission 379 379 */ 380 380 static int fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, ··· 440 440 441 441 fm_cb(skb)->completion = wait_completion; 442 442 skb_queue_tail(&fmdev->tx_q, skb); 443 - tasklet_schedule(&fmdev->tx_task); 443 + queue_work(system_bh_wq, &fmdev->tx_bh_work); 444 444 445 445 return 0; 446 446 } ··· 462 462 463 463 if (!wait_for_completion_timeout(&fmdev->maintask_comp, 464 464 FM_DRV_TX_TIMEOUT)) { 465 - fmerr("Timeout(%d sec),didn't get regcompletion signal from RX tasklet\n", 465 + fmerr("Timeout(%d sec),didn't get regcompletion signal from RX bh work\n", 466 466 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); 467 467 return -ETIMEDOUT; 468 468 } ··· 1455 1455 1456 1456 memcpy(skb_push(skb, 1), &skb->cb[0], 1); 1457 1457 skb_queue_tail(&fmdev->rx_q, skb); 1458 - tasklet_schedule(&fmdev->rx_task); 1458 + queue_work(system_bh_wq, &fmdev->rx_bh_work); 1459 1459 1460 1460 return 0; 1461 1461 } ··· 1537 1537 spin_lock_init(&fmdev->rds_buff_lock); 1538 1538 spin_lock_init(&fmdev->resp_skb_lock); 1539 1539 1540 - /* Initialize TX queue and TX tasklet */ 1540 + /* Initialize TX queue and TX bh work */ 1541 1541 skb_queue_head_init(&fmdev->tx_q); 1542 - tasklet_setup(&fmdev->tx_task, send_tasklet); 1542 + INIT_WORK(&fmdev->tx_bh_work, send_bh_work); 1543 1543 1544 - /* Initialize RX Queue and RX tasklet */ 1544 + /* Initialize RX Queue and RX bh work */ 1545 1545 skb_queue_head_init(&fmdev->rx_q); 1546 - tasklet_setup(&fmdev->rx_task, recv_tasklet); 1546 + INIT_WORK(&fmdev->rx_bh_work, recv_bh_work); 1547 1547 1548 1548 fmdev->irq_info.stage = 0; 1549 1549 atomic_set(&fmdev->tx_cnt, 1); ··· 1589 1589 /* Service pending read */ 1590 1590 wake_up_interruptible(&fmdev->rx.rds.read_queue); 1591 1591 1592 - tasklet_kill(&fmdev->tx_task); 1593 - tasklet_kill(&fmdev->rx_task); 1592 + cancel_work_sync(&fmdev->tx_bh_work); 1593 + cancel_work_sync(&fmdev->rx_bh_work); 1594 1594 1595 1595 skb_queue_purge(&fmdev->tx_q); 1596 1596 skb_queue_purge(&fmdev->rx_q);
+1 -1
drivers/media/rc/mceusb.c
··· 773 773 774 774 /* 775 775 * Schedule work that can't be done in interrupt handlers 776 - * (mceusb_dev_recv() and mce_write_callback()) nor tasklets. 776 + * (mceusb_dev_recv() and mce_write_callback()) nor BH work. 777 777 * Invokes mceusb_deferred_kevent() for recovering from 778 778 * error events specified by the kevent bit field. 779 779 */
+11 -10
drivers/media/usb/ttusb-dec/ttusb_dec.c
··· 19 19 #include <linux/input.h> 20 20 21 21 #include <linux/mutex.h> 22 + #include <linux/workqueue.h> 22 23 23 24 #include <media/dmxdev.h> 24 25 #include <media/dvb_demux.h> ··· 140 139 int v_pes_postbytes; 141 140 142 141 struct list_head urb_frame_list; 143 - struct tasklet_struct urb_tasklet; 142 + struct work_struct urb_bh_work; 144 143 spinlock_t urb_frame_list_lock; 145 144 146 145 struct dvb_demux_filter *audio_filter; ··· 767 766 } 768 767 } 769 768 770 - static void ttusb_dec_process_urb_frame_list(struct tasklet_struct *t) 769 + static void ttusb_dec_process_urb_frame_list(struct work_struct *t) 771 770 { 772 - struct ttusb_dec *dec = from_tasklet(dec, t, urb_tasklet); 771 + struct ttusb_dec *dec = from_work(dec, t, urb_bh_work); 773 772 struct list_head *item; 774 773 struct urb_frame *frame; 775 774 unsigned long flags; ··· 823 822 spin_unlock_irqrestore(&dec->urb_frame_list_lock, 824 823 flags); 825 824 826 - tasklet_schedule(&dec->urb_tasklet); 825 + queue_work(system_bh_wq, &dec->urb_bh_work); 827 826 } 828 827 } 829 828 } else { ··· 1199 1198 return 0; 1200 1199 } 1201 1200 1202 - static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) 1201 + static void ttusb_dec_init_bh_work(struct ttusb_dec *dec) 1203 1202 { 1204 1203 spin_lock_init(&dec->urb_frame_list_lock); 1205 1204 INIT_LIST_HEAD(&dec->urb_frame_list); 1206 - tasklet_setup(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list); 1205 + INIT_WORK(&dec->urb_bh_work, ttusb_dec_process_urb_frame_list); 1207 1206 } 1208 1207 1209 1208 static int ttusb_init_rc( struct ttusb_dec *dec) ··· 1589 1588 ttusb_dec_free_iso_urbs(dec); 1590 1589 } 1591 1590 1592 - static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec) 1591 + static void ttusb_dec_exit_bh_work(struct ttusb_dec *dec) 1593 1592 { 1594 1593 struct list_head *item; 1595 1594 struct urb_frame *frame; 1596 1595 1597 - tasklet_kill(&dec->urb_tasklet); 1596 + cancel_work_sync(&dec->urb_bh_work); 1598 1597 1599 1598 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) { 1600 1599 frame = list_entry(item, struct urb_frame, urb_frame_list); ··· 1704 1703 1705 1704 ttusb_dec_init_v_pes(dec); 1706 1705 ttusb_dec_init_filters(dec); 1707 - ttusb_dec_init_tasklet(dec); 1706 + ttusb_dec_init_bh_work(dec); 1708 1707 1709 1708 dec->active = 1; 1710 1709 ··· 1730 1729 dprintk("%s\n", __func__); 1731 1730 1732 1731 if (dec->active) { 1733 - ttusb_dec_exit_tasklet(dec); 1732 + ttusb_dec_exit_bh_work(dec); 1734 1733 ttusb_dec_exit_filters(dec); 1735 1734 if(enable_rc) 1736 1735 ttusb_dec_exit_rc(dec);