diff options
author | Allen Pais <allen.lkml@gmail.com> | 2024-07-01 12:07:33 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2024-07-08 11:41:30 +0200 |
commit | 921c87ba3893b5d3608e7f248366266b40b86c75 (patch) | |
tree | 46d8d628a666d161233a05c9a7a2fd953c9d226c /drivers/mmc/host/via-sdmmc.c | |
parent | mmc: sdhi: Convert from tasklet to BH workqueue (diff) | |
download | linux-921c87ba3893b5d3608e7f248366266b40b86c75.tar.xz linux-921c87ba3893b5d3608e7f248366266b40b86c75.zip |
mmc: 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/mmc/* from tasklet to BH workqueue.
Based on the work done by Tejun Heo <tj@kernel.org>
Tested-by: Christian Loehle <christian.loehle@arm.com>
Tested-by: Aubin Constans <aubin.constans@microchip.com>
Acked-by: Aubin Constans <aubin.constans@microchip.com>
Acked-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Reviewed-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
Link: https://lore.kernel.org/r/20240701100736.4001658-1-allen.lkml@gmail.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/via-sdmmc.c')
-rw-r--r-- | drivers/mmc/host/via-sdmmc.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index ba6044b16e07..f77457105ec3 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c @@ -12,6 +12,7 @@ #include <linux/interrupt.h> #include <linux/mmc/host.h> +#include <linux/workqueue.h> #define DRV_NAME "via_sdmmc" @@ -307,7 +308,7 @@ struct via_crdr_mmc_host { struct sdhcreg pm_sdhc_reg; struct work_struct carddet_work; - struct tasklet_struct finish_tasklet; + struct work_struct finish_bh_work; struct timer_list timer; spinlock_t lock; @@ -643,7 +644,7 @@ static void via_sdc_finish_data(struct via_crdr_mmc_host *host) if (data->stop) via_sdc_send_command(host, data->stop); else - tasklet_schedule(&host->finish_tasklet); + queue_work(system_bh_wq, &host->finish_bh_work); } static void via_sdc_finish_command(struct via_crdr_mmc_host *host) @@ -653,7 +654,7 @@ static void via_sdc_finish_command(struct via_crdr_mmc_host *host) host->cmd->error = 0; if (!host->cmd->data) - tasklet_schedule(&host->finish_tasklet); + queue_work(system_bh_wq, &host->finish_bh_work); host->cmd = NULL; } @@ -682,7 +683,7 @@ static void via_sdc_request(struct mmc_host *mmc, struct mmc_request *mrq) status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS); if (!(status & VIA_CRDR_SDSTS_SLOTG) || host->reject) { host->mrq->cmd->error = -ENOMEDIUM; - tasklet_schedule(&host->finish_tasklet); + queue_work(system_bh_wq, &host->finish_bh_work); } else { via_sdc_send_command(host, mrq->cmd); } @@ -848,7 +849,7 @@ static void via_sdc_cmd_isr(struct via_crdr_mmc_host *host, u16 intmask) host->cmd->error = -EILSEQ; if (host->cmd->error) - tasklet_schedule(&host->finish_tasklet); + queue_work(system_bh_wq, &host->finish_bh_work); else if (intmask & VIA_CRDR_SDSTS_CRD) via_sdc_finish_command(host); } @@ -955,16 +956,16 @@ static void via_sdc_timeout(struct timer_list *t) sdhost->cmd->error = -ETIMEDOUT; else sdhost->mrq->cmd->error = -ETIMEDOUT; - tasklet_schedule(&sdhost->finish_tasklet); + queue_work(system_bh_wq, &sdhost->finish_bh_work); } } spin_unlock_irqrestore(&sdhost->lock, flags); } -static void via_sdc_tasklet_finish(struct tasklet_struct *t) +static void via_sdc_finish_bh_work(struct work_struct *t) { - struct via_crdr_mmc_host *host = from_tasklet(host, t, finish_tasklet); + struct via_crdr_mmc_host *host = from_work(host, t, finish_bh_work); unsigned long flags; struct mmc_request *mrq; @@ -1005,7 +1006,7 @@ static void via_sdc_card_detect(struct work_struct *work) pr_err("%s: Card removed during transfer!\n", mmc_hostname(host->mmc)); host->mrq->cmd->error = -ENOMEDIUM; - tasklet_schedule(&host->finish_tasklet); + queue_work(system_bh_wq, &host->finish_bh_work); } spin_unlock_irqrestore(&host->lock, flags); @@ -1051,7 +1052,7 @@ static void via_init_mmc_host(struct via_crdr_mmc_host *host) INIT_WORK(&host->carddet_work, via_sdc_card_detect); - tasklet_setup(&host->finish_tasklet, via_sdc_tasklet_finish); + INIT_WORK(&host->finish_bh_work, via_sdc_finish_bh_work); addrbase = host->sdhc_mmiobase; writel(0x0, addrbase + VIA_CRDR_SDINTMASK); @@ -1193,7 +1194,7 @@ static void via_sd_remove(struct pci_dev *pcidev) sdhost->mrq->cmd->error = -ENOMEDIUM; if (sdhost->mrq->stop) sdhost->mrq->stop->error = -ENOMEDIUM; - tasklet_schedule(&sdhost->finish_tasklet); + queue_work(system_bh_wq, &sdhost->finish_bh_work); } spin_unlock_irqrestore(&sdhost->lock, flags); @@ -1203,7 +1204,7 @@ static void via_sd_remove(struct pci_dev *pcidev) del_timer_sync(&sdhost->timer); - tasklet_kill(&sdhost->finish_tasklet); + cancel_work_sync(&sdhost->finish_bh_work); /* switch off power */ gatt = readb(sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT); |