diff options
author | Allen Pais <allen.lkml@gmail.com> | 2024-06-18 15:52:27 -0700 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2024-06-21 08:57:09 +0200 |
commit | 1021dd010d212ccd770b89c7aff2e2031dc97619 (patch) | |
tree | df821d42380494de2153e637af32a9f1562d5882 /drivers/media/pci | |
parent | d2ae63c2f6a34e0104c046dcf5e03675867e0ad3 (diff) |
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>
Diffstat (limited to 'drivers/media/pci')
21 files changed, 84 insertions, 76 deletions
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 5c9ba4bfc1be..62a6c4a80bed 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -300,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & BT878_ARISCI) { bt->finished_block = (stat & BT878_ARISCS) >> 28; - if (bt->tasklet.callback) - tasklet_schedule(&bt->tasklet); + if (bt->bh_work.func) + queue_work(system_bh_wq, &bt->bh_work); break; } count++; @@ -478,8 +478,8 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btwrite(0, BT878_AINT_MASK); bt878_num++; - if (!bt->tasklet.func) - tasklet_disable(&bt->tasklet); + if (!bt->bh_work.func) + disable_work_sync(&bt->bh_work); return 0; diff --git a/drivers/media/pci/bt8xx/bt878.h b/drivers/media/pci/bt8xx/bt878.h index fde8db293c54..5b1c7f56e553 100644 --- a/drivers/media/pci/bt8xx/bt878.h +++ b/drivers/media/pci/bt8xx/bt878.h @@ -14,6 +14,7 @@ #include <linux/sched.h> #include <linux/spinlock.h> #include <linux/mutex.h> +#include <linux/workqueue.h> #include "bt848.h" #include "bttv.h" @@ -120,7 +121,7 @@ struct bt878 { dma_addr_t risc_dma; u32 risc_pos; - struct tasklet_struct tasklet; + struct work_struct bh_work; int shutdown; }; diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c index 390cbba6c065..f0fbb468aea2 100644 --- a/drivers/media/pci/bt8xx/dvb-bt8xx.c +++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c @@ -39,9 +39,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ -static void dvb_bt8xx_task(struct tasklet_struct *t) +static void dvb_bt8xx_work(struct work_struct *t) { - struct bt878 *bt = from_tasklet(bt, t, tasklet); + struct bt878 *bt = from_work(bt, t, bh_work); struct dvb_bt8xx_card *card = dev_get_drvdata(&bt->adapter->dev); dprintk("%d\n", card->bt->finished_block); @@ -782,7 +782,7 @@ static int dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) goto err_disconnect_frontend; } - tasklet_setup(&card->bt->tasklet, dvb_bt8xx_task); + INIT_WORK(&card->bt->bh_work, dvb_bt8xx_work); frontend_init(card, type); @@ -922,7 +922,7 @@ static void dvb_bt8xx_remove(struct bttv_sub_device *sub) dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr); bt878_stop(card->bt); - tasklet_kill(&card->bt->tasklet); + cancel_work_sync(&card->bt->bh_work); dvb_net_release(&card->dvbnet); card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index f3699dbd193f..f01ecdb0b627 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -298,7 +298,7 @@ struct ddb_link { spinlock_t lock; /* lock link access */ struct mutex flash_mutex; /* lock flash access */ struct ddb_lnb lnb; - struct tasklet_struct tasklet; + struct work_struct bh_work; struct ddb_ids ids; spinlock_t temp_lock; /* lock temp chip access */ diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c index c0bd5d7e148b..b85aef4e2b24 100644 --- a/drivers/media/pci/mantis/hopper_cards.c +++ b/drivers/media/pci/mantis/hopper_cards.c @@ -116,7 +116,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) if (stat & MANTIS_INT_RISCI) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; - tasklet_schedule(&mantis->tasklet); + queue_work(system_bh_wq, &mantis->bh_work); } if (stat & MANTIS_INT_I2CDONE) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index 906e4500d87d..b44b4cf42f86 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -125,7 +125,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id) if (stat & MANTIS_INT_RISCI) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; - tasklet_schedule(&mantis->tasklet); + queue_work(system_bh_wq, &mantis->bh_work); } if (stat & MANTIS_INT_I2CDONE) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h index d88ac280226c..6e563ecd94e8 100644 --- a/drivers/media/pci/mantis/mantis_common.h +++ b/drivers/media/pci/mantis/mantis_common.h @@ -125,7 +125,7 @@ struct mantis_pci { __le32 *risc_cpu; dma_addr_t risc_dma; - struct tasklet_struct tasklet; + struct work_struct bh_work; spinlock_t intmask_lock; struct i2c_adapter adapter; diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c index 80c843936493..eeb210a2862f 100644 --- a/drivers/media/pci/mantis/mantis_dma.c +++ b/drivers/media/pci/mantis/mantis_dma.c @@ -200,9 +200,9 @@ void mantis_dma_stop(struct mantis_pci *mantis) } -void mantis_dma_xfer(struct tasklet_struct *t) +void mantis_dma_xfer(struct work_struct *t) { - struct mantis_pci *mantis = from_tasklet(mantis, t, tasklet); + struct mantis_pci *mantis = from_work(mantis, t, bh_work); struct mantis_hwconfig *config = mantis->hwconfig; while (mantis->last_block != mantis->busy_block) { diff --git a/drivers/media/pci/mantis/mantis_dma.h b/drivers/media/pci/mantis/mantis_dma.h index 37da982c9c29..5db0d3728f15 100644 --- a/drivers/media/pci/mantis/mantis_dma.h +++ b/drivers/media/pci/mantis/mantis_dma.h @@ -13,6 +13,6 @@ extern int mantis_dma_init(struct mantis_pci *mantis); extern int mantis_dma_exit(struct mantis_pci *mantis); extern void mantis_dma_start(struct mantis_pci *mantis); extern void mantis_dma_stop(struct mantis_pci *mantis); -extern void mantis_dma_xfer(struct tasklet_struct *t); +extern void mantis_dma_xfer(struct work_struct *t); #endif /* __MANTIS_DMA_H */ diff --git a/drivers/media/pci/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c index c7ba4a76e608..398e32f44692 100644 --- a/drivers/media/pci/mantis/mantis_dvb.c +++ b/drivers/media/pci/mantis/mantis_dvb.c @@ -105,7 +105,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) if (mantis->feeds == 1) { dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); mantis_dma_start(mantis); - tasklet_enable(&mantis->tasklet); + enable_and_queue_work(system_bh_wq, &mantis->bh_work); } return mantis->feeds; @@ -125,7 +125,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) mantis->feeds--; if (mantis->feeds == 0) { dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); - tasklet_disable(&mantis->tasklet); + disable_work_sync(&mantis->bh_work); mantis_dma_stop(mantis); } @@ -205,8 +205,8 @@ int mantis_dvb_init(struct mantis_pci *mantis) } dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); - tasklet_setup(&mantis->tasklet, mantis_dma_xfer); - tasklet_disable(&mantis->tasklet); + INIT_WORK(&mantis->bh_work, mantis_dma_xfer); + disable_work_sync(&mantis->bh_work); if (mantis->hwconfig) { result = config->frontend_init(mantis, mantis->fe); if (result < 0) { @@ -235,7 +235,7 @@ int mantis_dvb_init(struct mantis_pci *mantis) /* Error conditions .. */ err5: - tasklet_kill(&mantis->tasklet); + cancel_work_sync(&mantis->bh_work); dvb_net_release(&mantis->dvbnet); if (mantis->fe) { dvb_unregister_frontend(mantis->fe); @@ -273,7 +273,7 @@ int mantis_dvb_exit(struct mantis_pci *mantis) dvb_frontend_detach(mantis->fe); } - tasklet_kill(&mantis->tasklet); + cancel_work_sync(&mantis->bh_work); dvb_net_release(&mantis->dvbnet); mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 24ec576dc3bf..db6796240bce 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -50,9 +50,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* nGene interrupt handler **************************************************/ /****************************************************************************/ -static void event_tasklet(struct tasklet_struct *t) +static void event_bh_work(struct work_struct *t) { - struct ngene *dev = from_tasklet(dev, t, event_tasklet); + struct ngene *dev = from_work(dev, t, event_bh_work); while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) { struct EVENT_BUFFER Event = @@ -68,9 +68,9 @@ static void event_tasklet(struct tasklet_struct *t) } } -static void demux_tasklet(struct tasklet_struct *t) +static void demux_bh_work(struct work_struct *t) { - struct ngene_channel *chan = from_tasklet(chan, t, demux_tasklet); + struct ngene_channel *chan = from_work(chan, t, demux_bh_work); struct device *pdev = &chan->dev->pci_dev->dev; struct SBufferHeader *Cur = chan->nextBuffer; @@ -204,7 +204,7 @@ static irqreturn_t irq_handler(int irq, void *dev_id) dev->EventQueueOverflowFlag = 1; } dev->EventBuffer->EventStatus &= ~0x80; - tasklet_schedule(&dev->event_tasklet); + queue_work(system_bh_wq, &dev->event_bh_work); rc = IRQ_HANDLED; } @@ -217,8 +217,8 @@ static irqreturn_t irq_handler(int irq, void *dev_id) ngeneBuffer.SR.Flags & 0xC0) == 0x80) { dev->channel[i].nextBuffer-> ngeneBuffer.SR.Flags |= 0x40; - tasklet_schedule( - &dev->channel[i].demux_tasklet); + queue_work(system_bh_wq, + &dev->channel[i].demux_bh_work); rc = IRQ_HANDLED; } } @@ -1181,7 +1181,7 @@ static void ngene_init(struct ngene *dev) struct device *pdev = &dev->pci_dev->dev; int i; - tasklet_setup(&dev->event_tasklet, event_tasklet); + INIT_WORK(&dev->event_bh_work, event_bh_work); memset_io(dev->iomem + 0xc000, 0x00, 0x220); memset_io(dev->iomem + 0xc400, 0x00, 0x100); @@ -1395,7 +1395,7 @@ static void release_channel(struct ngene_channel *chan) if (chan->running) set_transfer(chan, 0); - tasklet_kill(&chan->demux_tasklet); + cancel_work_sync(&chan->demux_bh_work); if (chan->ci_dev) { dvb_unregister_device(chan->ci_dev); @@ -1445,7 +1445,7 @@ static int init_channel(struct ngene_channel *chan) struct ngene_info *ni = dev->card_info; int io = ni->io_type[nr]; - tasklet_setup(&chan->demux_tasklet, demux_tasklet); + INIT_WORK(&chan->demux_bh_work, demux_bh_work); chan->users = 0; chan->type = io; chan->mode = chan->type; /* for now only one mode */ @@ -1649,7 +1649,7 @@ void ngene_remove(struct pci_dev *pdev) struct ngene *dev = pci_get_drvdata(pdev); int i; - tasklet_kill(&dev->event_tasklet); + cancel_work_sync(&dev->event_bh_work); for (i = MAX_STREAM - 1; i >= 0; i--) release_channel(&dev->channel[i]); if (dev->ci.en) diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h index d1d7da84cd9d..9f989420b9e7 100644 --- a/drivers/media/pci/ngene/ngene.h +++ b/drivers/media/pci/ngene/ngene.h @@ -16,6 +16,7 @@ #include <linux/scatterlist.h> #include <linux/dvb/frontend.h> +#include <linux/workqueue.h> #include <media/dmxdev.h> #include <media/dvbdev.h> @@ -621,7 +622,7 @@ struct ngene_channel { int users; struct video_device *v4l_dev; struct dvb_device *ci_dev; - struct tasklet_struct demux_tasklet; + struct work_struct demux_bh_work; struct SBufferHeader *nextBuffer; enum KSSTATE State; @@ -717,7 +718,7 @@ struct ngene { struct EVENT_BUFFER EventQueue[EVENT_QUEUE_SIZE]; int EventQueueOverflowCount; int EventQueueOverflowFlag; - struct tasklet_struct event_tasklet; + struct work_struct event_bh_work; struct EVENT_BUFFER *EventBuffer; int EventQueueWriteIndex; int EventQueueReadIndex; diff --git a/drivers/media/pci/smipcie/smipcie-main.c b/drivers/media/pci/smipcie/smipcie-main.c index 0c300d019d9c..7db6d443fc54 100644 --- a/drivers/media/pci/smipcie/smipcie-main.c +++ b/drivers/media/pci/smipcie/smipcie-main.c @@ -279,10 +279,10 @@ static void smi_port_clearInterrupt(struct smi_port *port) (port->_dmaInterruptCH0 | port->_dmaInterruptCH1)); } -/* tasklet handler: DMA data to dmx.*/ -static void smi_dma_xfer(struct tasklet_struct *t) +/* BH work handler: DMA data to dmx.*/ +static void smi_dma_xfer(struct work_struct *t) { - struct smi_port *port = from_tasklet(port, t, tasklet); + struct smi_port *port = from_work(port, t, bh_work); struct smi_dev *dev = port->dev; u32 intr_status, finishedData, dmaManagement; u8 dmaChan0State, dmaChan1State; @@ -426,8 +426,8 @@ static int smi_port_init(struct smi_port *port, int dmaChanUsed) } smi_port_disableInterrupt(port); - tasklet_setup(&port->tasklet, smi_dma_xfer); - tasklet_disable(&port->tasklet); + INIT_WORK(&port->bh_work, smi_dma_xfer); + disable_work_sync(&port->bh_work); port->enable = 1; return 0; err: @@ -438,7 +438,7 @@ err: static void smi_port_exit(struct smi_port *port) { smi_port_disableInterrupt(port); - tasklet_kill(&port->tasklet); + cancel_work_sync(&port->bh_work); smi_port_dma_free(port); port->enable = 0; } @@ -452,7 +452,7 @@ static int smi_port_irq(struct smi_port *port, u32 int_status) smi_port_disableInterrupt(port); port->_int_status = int_status; smi_port_clearInterrupt(port); - tasklet_schedule(&port->tasklet); + queue_work(system_bh_wq, &port->bh_work); handled = 1; } return handled; @@ -823,7 +823,7 @@ static int smi_start_feed(struct dvb_demux_feed *dvbdmxfeed) smi_port_clearInterrupt(port); smi_port_enableInterrupt(port); smi_write(port->DMA_MANAGEMENT, dmaManagement); - tasklet_enable(&port->tasklet); + enable_and_queue_work(system_bh_wq, &port->bh_work); } return port->users; } @@ -837,7 +837,7 @@ static int smi_stop_feed(struct dvb_demux_feed *dvbdmxfeed) if (--port->users) return port->users; - tasklet_disable(&port->tasklet); + disable_work_sync(&port->bh_work); smi_port_disableInterrupt(port); smi_clear(port->DMA_MANAGEMENT, 0x30003); return 0; diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h index 2b5e0154814c..98e44edaab9e 100644 --- a/drivers/media/pci/smipcie/smipcie.h +++ b/drivers/media/pci/smipcie/smipcie.h @@ -17,6 +17,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/slab.h> +#include <linux/workqueue.h> #include <media/rc-core.h> #include <media/demux.h> @@ -257,7 +258,7 @@ struct smi_port { u32 _dmaInterruptCH0; u32 _dmaInterruptCH1; u32 _int_status; - struct tasklet_struct tasklet; + struct work_struct bh_work; /* dvb */ struct dmx_frontend hw_frontend; struct dmx_frontend mem_frontend; diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index 2e62c938e2cb..69f5e810f9b5 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -36,6 +36,7 @@ #include <linux/interrupt.h> #include <linux/input.h> #include <linux/spinlock.h> +#include <linux/workqueue.h> #include <media/dvb_ca_en50221.h> @@ -54,7 +55,7 @@ struct budget_av { struct video_device vd; int cur_input; int has_saa7113; - struct tasklet_struct ciintf_irq_tasklet; + struct work_struct ciintf_irq_bh_work; int slot_status; struct dvb_ca_en50221 ca; u8 reinitialise_demod:1; diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index 76de40e3c802..33f08adf4feb 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/spinlock.h> +#include <linux/workqueue.h> #include <media/rc-core.h> #include "budget.h" @@ -81,7 +82,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct budget_ci_ir { struct rc_dev *dev; - struct tasklet_struct msp430_irq_tasklet; + struct work_struct msp430_irq_bh_work; char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ char phys[32]; int rc5_device; @@ -92,7 +93,7 @@ struct budget_ci_ir { struct budget_ci { struct budget budget; - struct tasklet_struct ciintf_irq_tasklet; + struct work_struct ciintf_irq_bh_work; int slot_status; int ci_irq; struct dvb_ca_en50221 ca; @@ -100,9 +101,9 @@ struct budget_ci { u8 tuner_pll_address; /* used for philips_tdm1316l configs */ }; -static void msp430_ir_interrupt(struct tasklet_struct *t) +static void msp430_ir_interrupt(struct work_struct *t) { - struct budget_ci_ir *ir = from_tasklet(ir, t, msp430_irq_tasklet); + struct budget_ci_ir *ir = from_work(ir, t, msp430_irq_bh_work); struct budget_ci *budget_ci = container_of(ir, typeof(*budget_ci), ir); struct rc_dev *dev = budget_ci->ir.dev; u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; @@ -231,7 +232,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) budget_ci->ir.dev = dev; - tasklet_setup(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt); + INIT_WORK(&budget_ci->ir.msp430_irq_bh_work, msp430_ir_interrupt); SAA7146_IER_ENABLE(saa, MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); @@ -245,7 +246,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) SAA7146_IER_DISABLE(saa, MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); + cancel_work_sync(&budget_ci->ir.msp430_irq_bh_work); rc_unregister_device(budget_ci->ir.dev); } @@ -349,10 +350,10 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) return 0; } -static void ciintf_interrupt(struct tasklet_struct *t) +static void ciintf_interrupt(struct work_struct *t) { - struct budget_ci *budget_ci = from_tasklet(budget_ci, t, - ciintf_irq_tasklet); + struct budget_ci *budget_ci = from_work(budget_ci, t, + ciintf_irq_bh_work); struct saa7146_dev *saa = budget_ci->budget.dev; unsigned int flags; @@ -491,7 +492,7 @@ static int ciintf_init(struct budget_ci *budget_ci) // Setup CI slot IRQ if (budget_ci->ci_irq) { - tasklet_setup(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt); + INIT_WORK(&budget_ci->ciintf_irq_bh_work, ciintf_interrupt); if (budget_ci->slot_status != SLOTSTATUS_NONE) saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); else @@ -530,7 +531,7 @@ static void ciintf_deinit(struct budget_ci *budget_ci) if (budget_ci->ci_irq) { SAA7146_IER_DISABLE(saa, MASK_03); saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ciintf_irq_tasklet); + cancel_work_sync(&budget_ci->ciintf_irq_bh_work); } // reset interface @@ -556,13 +557,13 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 *isr) dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci); if (*isr & MASK_06) - tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet); + queue_work(system_bh_wq, &budget_ci->ir.msp430_irq_bh_work); if (*isr & MASK_10) ttpci_budget_irq10_handler(dev, isr); if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) - tasklet_schedule(&budget_ci->ciintf_irq_tasklet); + queue_work(system_bh_wq, &budget_ci->ciintf_irq_bh_work); } static u8 philips_su1278_tt_inittab[] = { diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c index 6d41fc997655..29531d9c9db0 100644 --- a/drivers/media/pci/ttpci/budget-core.c +++ b/drivers/media/pci/ttpci/budget-core.c @@ -172,9 +172,9 @@ static int budget_read_fe_status(struct dvb_frontend *fe, return ret; } -static void vpeirq(struct tasklet_struct *t) +static void vpeirq(struct work_struct *t) { - struct budget *budget = from_tasklet(budget, t, vpe_tasklet); + struct budget *budget = from_work(budget, t, vpe_bh_work); u8 *mem = (u8 *) (budget->grabbing); u32 olddma = budget->ttbp; u32 newdma = saa7146_read(budget->dev, PCI_VDP3); @@ -525,7 +525,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, /* upload all */ saa7146_write(dev, GPIO_CTRL, 0x000000); - tasklet_setup(&budget->vpe_tasklet, vpeirq); + INIT_WORK(&budget->vpe_bh_work, vpeirq); /* frontend power on */ if (bi->type != BUDGET_FS_ACTIVY) @@ -565,7 +565,7 @@ int ttpci_budget_deinit(struct budget *budget) budget_unregister(budget); - tasklet_kill(&budget->vpe_tasklet); + cancel_work_sync(&budget->vpe_bh_work); saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); @@ -584,7 +584,7 @@ void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 *isr) dprintk(8, "dev: %p, budget: %p\n", dev, budget); if (*isr & MASK_10) - tasklet_schedule(&budget->vpe_tasklet); + queue_work(system_bh_wq, &budget->vpe_bh_work); } EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h index 83ead34dc766..e933764ac4e3 100644 --- a/drivers/media/pci/ttpci/budget.h +++ b/drivers/media/pci/ttpci/budget.h @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/mutex.h> +#include <linux/workqueue.h> #include <media/drv-intf/saa7146.h> @@ -54,8 +55,8 @@ struct budget { unsigned char *grabbing; struct saa7146_pgtable pt; - struct tasklet_struct fidb_tasklet; - struct tasklet_struct vpe_tasklet; + struct work_struct fidb_bh_work; + struct work_struct vpe_bh_work; struct dmxdev dmxdev; struct dvb_demux demux; diff --git a/drivers/media/pci/tw5864/tw5864-core.c b/drivers/media/pci/tw5864/tw5864-core.c index 560ff1ddcc83..4d33caf83307 100644 --- a/drivers/media/pci/tw5864/tw5864-core.c +++ b/drivers/media/pci/tw5864/tw5864-core.c @@ -144,7 +144,7 @@ static void tw5864_h264_isr(struct tw5864_dev *dev) cur_frame->gop_seqno = input->frame_gop_seqno; dev->h264_buf_w_index = next_frame_index; - tasklet_schedule(&dev->tasklet); + queue_work(system_bh_wq, &dev->bh_work); cur_frame = next_frame; diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c index 8b1aae4b6319..4f35c159efe5 100644 --- a/drivers/media/pci/tw5864/tw5864-video.c +++ b/drivers/media/pci/tw5864/tw5864-video.c @@ -6,6 +6,7 @@ */ #include <linux/module.h> +#include <linux/workqueue.h> #include <media/v4l2-common.h> #include <media/v4l2-event.h> #include <media/videobuf2-dma-contig.h> @@ -175,7 +176,7 @@ static const unsigned int intra4x4_lambda3[] = { static v4l2_std_id tw5864_get_v4l2_std(enum tw5864_vid_std std); static enum tw5864_vid_std tw5864_from_v4l2_std(v4l2_std_id v4l2_std); -static void tw5864_handle_frame_task(struct tasklet_struct *t); +static void tw5864_handle_frame_work(struct work_struct *t); static void tw5864_handle_frame(struct tw5864_h264_frame *frame); static void tw5864_frame_interval_set(struct tw5864_input *input); @@ -1062,7 +1063,7 @@ int tw5864_video_init(struct tw5864_dev *dev, int *video_nr) dev->irqmask |= TW5864_INTR_VLC_DONE | TW5864_INTR_TIMER; tw5864_irqmask_apply(dev); - tasklet_setup(&dev->tasklet, tw5864_handle_frame_task); + INIT_WORK(&dev->bh_work, tw5864_handle_frame_work); for (i = 0; i < TW5864_INPUTS; i++) { dev->inputs[i].root = dev; @@ -1079,7 +1080,7 @@ fini_video_inputs: for (i = last_input_nr_registered; i >= 0; i--) tw5864_video_input_fini(&dev->inputs[i]); - tasklet_kill(&dev->tasklet); + cancel_work_sync(&dev->bh_work); free_dma: for (i = last_dma_allocated; i >= 0; i--) { @@ -1198,7 +1199,7 @@ void tw5864_video_fini(struct tw5864_dev *dev) { int i; - tasklet_kill(&dev->tasklet); + cancel_work_sync(&dev->bh_work); for (i = 0; i < TW5864_INPUTS; i++) tw5864_video_input_fini(&dev->inputs[i]); @@ -1315,9 +1316,9 @@ static int tw5864_is_motion_triggered(struct tw5864_h264_frame *frame) return detected; } -static void tw5864_handle_frame_task(struct tasklet_struct *t) +static void tw5864_handle_frame_work(struct work_struct *t) { - struct tw5864_dev *dev = from_tasklet(dev, t, tasklet); + struct tw5864_dev *dev = from_work(dev, t, bh_work); unsigned long flags; int batch_size = H264_BUF_CNT; diff --git a/drivers/media/pci/tw5864/tw5864.h b/drivers/media/pci/tw5864/tw5864.h index a8b6fbd5b710..2da5f4215fd9 100644 --- a/drivers/media/pci/tw5864/tw5864.h +++ b/drivers/media/pci/tw5864/tw5864.h @@ -12,6 +12,7 @@ #include <linux/mutex.h> #include <linux/io.h> #include <linux/interrupt.h> +#include <linux/workqueue.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> @@ -85,7 +86,7 @@ struct tw5864_input { int nr; /* input number */ struct tw5864_dev *root; struct mutex lock; /* used for vidq and vdev */ - spinlock_t slock; /* used for sync between ISR, tasklet & V4L2 API */ + spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */ struct video_device vdev; struct v4l2_ctrl_handler hdl; struct vb2_queue vidq; @@ -142,7 +143,7 @@ struct tw5864_h264_frame { /* global device status */ struct tw5864_dev { - spinlock_t slock; /* used for sync between ISR, tasklet & V4L2 API */ + spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */ struct v4l2_device v4l2_dev; struct tw5864_input inputs[TW5864_INPUTS]; #define H264_BUF_CNT 4 @@ -150,7 +151,7 @@ struct tw5864_dev { int h264_buf_r_index; int h264_buf_w_index; - struct tasklet_struct tasklet; + struct work_struct bh_work; int encoder_busy; /* Input number to check next for ready raw picture (in RR fashion) */ |