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/radio | |
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/radio')
-rw-r--r-- | drivers/media/radio/wl128x/fmdrv.h | 5 | ||||
-rw-r--r-- | drivers/media/radio/wl128x/fmdrv_common.c | 40 |
2 files changed, 23 insertions, 22 deletions
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h index da8920169df8..03117a41dbd4 100644 --- a/drivers/media/radio/wl128x/fmdrv.h +++ b/drivers/media/radio/wl128x/fmdrv.h @@ -15,6 +15,7 @@ #include <sound/core.h> #include <sound/initval.h> #include <linux/timer.h> +#include <linux/workqueue.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-common.h> #include <media/v4l2-device.h> @@ -200,10 +201,10 @@ struct fmdev { int streg_cbdata; /* status of ST registration */ struct sk_buff_head rx_q; /* RX queue */ - struct tasklet_struct rx_task; /* RX Tasklet */ + struct work_struct rx_bh_work; /* RX BH Work */ struct sk_buff_head tx_q; /* TX queue */ - struct tasklet_struct tx_task; /* TX Tasklet */ + struct work_struct tx_bh_work; /* TX BH Work */ unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */ atomic_t tx_cnt; /* Number of packets can send at a time */ diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 3da8e5102bec..3d36f323a8f8 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -9,7 +9,7 @@ * one Channel-8 command to be sent to the chip). * 2) Sending each Channel-8 command to the chip and reading * response back over Shared Transport. - * 3) Managing TX and RX Queues and Tasklets. + * 3) Managing TX and RX Queues and BH bh Works. * 4) Handling FM Interrupt packet and taking appropriate action. * 5) Loading FM firmware to the chip (common, FM TX, and FM RX * firmware files based on mode selection) @@ -244,10 +244,10 @@ void fmc_update_region_info(struct fmdev *fmdev, u8 region_to_set) } /* - * FM common sub-module will schedule this tasklet whenever it receives + * FM common sub-module will queue this bh work whenever it receives * FM packet from ST driver. */ -static void recv_tasklet(struct tasklet_struct *t) +static void recv_bh_work(struct work_struct *t) { struct fmdev *fmdev; struct fm_irq *irq_info; @@ -256,7 +256,7 @@ static void recv_tasklet(struct tasklet_struct *t) u8 num_fm_hci_cmds; unsigned long flags; - fmdev = from_tasklet(fmdev, t, tx_task); + fmdev = from_work(fmdev, t, tx_bh_work); irq_info = &fmdev->irq_info; /* Process all packets in the RX queue */ while ((skb = skb_dequeue(&fmdev->rx_q))) { @@ -322,22 +322,22 @@ static void recv_tasklet(struct tasklet_struct *t) /* * Check flow control field. If Num_FM_HCI_Commands field is - * not zero, schedule FM TX tasklet. + * not zero, queue FM TX bh work. */ if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt)) if (!skb_queue_empty(&fmdev->tx_q)) - tasklet_schedule(&fmdev->tx_task); + queue_work(system_bh_wq, &fmdev->tx_bh_work); } } -/* FM send tasklet: is scheduled when FM packet has to be sent to chip */ -static void send_tasklet(struct tasklet_struct *t) +/* FM send_bh_work: is scheduled when FM packet has to be sent to chip */ +static void send_bh_work(struct work_struct *t) { struct fmdev *fmdev; struct sk_buff *skb; int len; - fmdev = from_tasklet(fmdev, t, tx_task); + fmdev = from_work(fmdev, t, tx_bh_work); if (!atomic_read(&fmdev->tx_cnt)) return; @@ -366,7 +366,7 @@ static void send_tasklet(struct tasklet_struct *t) if (len < 0) { kfree_skb(skb); fmdev->resp_comp = NULL; - fmerr("TX tasklet failed to send skb(%p)\n", skb); + fmerr("TX bh work failed to send skb(%p)\n", skb); atomic_set(&fmdev->tx_cnt, 1); } else { fmdev->last_tx_jiffies = jiffies; @@ -374,7 +374,7 @@ static void send_tasklet(struct tasklet_struct *t) } /* - * Queues FM Channel-8 packet to FM TX queue and schedules FM TX tasklet for + * Queues FM Channel-8 packet to FM TX queue and schedules FM TX bh work for * transmission */ static int fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, @@ -440,7 +440,7 @@ static int fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, fm_cb(skb)->completion = wait_completion; skb_queue_tail(&fmdev->tx_q, skb); - tasklet_schedule(&fmdev->tx_task); + queue_work(system_bh_wq, &fmdev->tx_bh_work); return 0; } @@ -462,7 +462,7 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, if (!wait_for_completion_timeout(&fmdev->maintask_comp, FM_DRV_TX_TIMEOUT)) { - fmerr("Timeout(%d sec),didn't get regcompletion signal from RX tasklet\n", + fmerr("Timeout(%d sec),didn't get regcompletion signal from RX bh work\n", jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); return -ETIMEDOUT; } @@ -1455,7 +1455,7 @@ static long fm_st_receive(void *arg, struct sk_buff *skb) memcpy(skb_push(skb, 1), &skb->cb[0], 1); skb_queue_tail(&fmdev->rx_q, skb); - tasklet_schedule(&fmdev->rx_task); + queue_work(system_bh_wq, &fmdev->rx_bh_work); return 0; } @@ -1537,13 +1537,13 @@ int fmc_prepare(struct fmdev *fmdev) spin_lock_init(&fmdev->rds_buff_lock); spin_lock_init(&fmdev->resp_skb_lock); - /* Initialize TX queue and TX tasklet */ + /* Initialize TX queue and TX bh work */ skb_queue_head_init(&fmdev->tx_q); - tasklet_setup(&fmdev->tx_task, send_tasklet); + INIT_WORK(&fmdev->tx_bh_work, send_bh_work); - /* Initialize RX Queue and RX tasklet */ + /* Initialize RX Queue and RX bh work */ skb_queue_head_init(&fmdev->rx_q); - tasklet_setup(&fmdev->rx_task, recv_tasklet); + INIT_WORK(&fmdev->rx_bh_work, recv_bh_work); fmdev->irq_info.stage = 0; atomic_set(&fmdev->tx_cnt, 1); @@ -1589,8 +1589,8 @@ int fmc_release(struct fmdev *fmdev) /* Service pending read */ wake_up_interruptible(&fmdev->rx.rds.read_queue); - tasklet_kill(&fmdev->tx_task); - tasklet_kill(&fmdev->rx_task); + cancel_work_sync(&fmdev->tx_bh_work); + cancel_work_sync(&fmdev->rx_bh_work); skb_queue_purge(&fmdev->tx_q); skb_queue_purge(&fmdev->rx_q); |