Skip to content

Commit 85683fb

Browse files
Allen Paisstorulf
authored andcommitted
mmc: sdhi: 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 the SDHI driver from tasklet to BH workqueue. Based on the work done by Tejun Heo <[email protected]> Signed-off-by: Allen Pais <[email protected]> [wsa: fixed build faliures, corrected whitespace issues] Signed-off-by: Wolfram Sang <[email protected]> Reviewed-by: Niklas Söderlund <[email protected]> Tested-by: Lad Prabhakar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent a1382d1 commit 85683fb

File tree

6 files changed

+26
-22
lines changed

6 files changed

+26
-22
lines changed

drivers/mmc/host/renesas_sdhi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/dmaengine.h>
1313
#include <linux/platform_device.h>
14+
#include <linux/workqueue.h>
1415
#include "tmio_mmc.h"
1516

1617
struct renesas_sdhi_scc {
@@ -67,7 +68,7 @@ struct renesas_sdhi_dma {
6768
dma_filter_fn filter;
6869
void (*enable)(struct tmio_mmc_host *host, bool enable);
6970
struct completion dma_dataend;
70-
struct tasklet_struct dma_complete;
71+
struct work_struct dma_complete;
7172
};
7273

7374
struct renesas_sdhi {
@@ -93,6 +94,7 @@ struct renesas_sdhi {
9394
unsigned int tap_set;
9495

9596
struct reset_control *rstc;
97+
struct tmio_mmc_host *host;
9698
};
9799

98100
#define host_to_priv(host) \

drivers/mmc/host/renesas_sdhi_core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
970970
if (IS_ERR(host))
971971
return PTR_ERR(host);
972972

973+
priv->host = host;
974+
973975
if (of_data) {
974976
mmc_data->flags |= of_data->tmio_flags;
975977
mmc_data->ocr_mask = of_data->tmio_ocr_mask;

drivers/mmc/host/renesas_sdhi_internal_dmac.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ static bool renesas_sdhi_internal_dmac_dma_irq(struct tmio_mmc_host *host)
337337
writel(status ^ dma_irqs, host->ctl + DM_CM_INFO1);
338338
set_bit(SDHI_DMA_END_FLAG_DMA, &dma_priv->end_flags);
339339
if (test_bit(SDHI_DMA_END_FLAG_ACCESS, &dma_priv->end_flags))
340-
tasklet_schedule(&dma_priv->dma_complete);
340+
queue_work(system_bh_wq, &dma_priv->dma_complete);
341341
}
342342

343343
return status & dma_irqs;
@@ -352,7 +352,7 @@ renesas_sdhi_internal_dmac_dataend_dma(struct tmio_mmc_host *host)
352352
set_bit(SDHI_DMA_END_FLAG_ACCESS, &dma_priv->end_flags);
353353
if (test_bit(SDHI_DMA_END_FLAG_DMA, &dma_priv->end_flags) ||
354354
host->data->error)
355-
tasklet_schedule(&dma_priv->dma_complete);
355+
queue_work(system_bh_wq, &dma_priv->dma_complete);
356356
}
357357

358358
/*
@@ -440,9 +440,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
440440
renesas_sdhi_internal_dmac_enable_dma(host, false);
441441
}
442442

443-
static void renesas_sdhi_internal_dmac_issue_tasklet_fn(unsigned long arg)
443+
static void renesas_sdhi_internal_dmac_issue_work_fn(struct work_struct *work)
444444
{
445-
struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
445+
struct tmio_mmc_host *host = from_work(host, work, dma_issue);
446446
struct renesas_sdhi *priv = host_to_priv(host);
447447

448448
tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
@@ -454,7 +454,7 @@ static void renesas_sdhi_internal_dmac_issue_tasklet_fn(unsigned long arg)
454454
/* on CMD errors, simulate DMA end immediately */
455455
set_bit(SDHI_DMA_END_FLAG_DMA, &priv->dma_priv.end_flags);
456456
if (test_bit(SDHI_DMA_END_FLAG_ACCESS, &priv->dma_priv.end_flags))
457-
tasklet_schedule(&priv->dma_priv.dma_complete);
457+
queue_work(system_bh_wq, &priv->dma_priv.dma_complete);
458458
}
459459
}
460460

@@ -484,9 +484,11 @@ static bool renesas_sdhi_internal_dmac_complete(struct tmio_mmc_host *host)
484484
return true;
485485
}
486486

487-
static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
487+
static void renesas_sdhi_internal_dmac_complete_work_fn(struct work_struct *work)
488488
{
489-
struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
489+
struct renesas_sdhi_dma *dma_priv = from_work(dma_priv, work, dma_complete);
490+
struct renesas_sdhi *priv = container_of(dma_priv, typeof(*priv), dma_priv);
491+
struct tmio_mmc_host *host = priv->host;
490492

491493
spin_lock_irq(&host->lock);
492494
if (!renesas_sdhi_internal_dmac_complete(host))
@@ -544,12 +546,10 @@ renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
544546
/* Each value is set to non-zero to assume "enabling" each DMA */
545547
host->chan_rx = host->chan_tx = (void *)0xdeadbeaf;
546548

547-
tasklet_init(&priv->dma_priv.dma_complete,
548-
renesas_sdhi_internal_dmac_complete_tasklet_fn,
549-
(unsigned long)host);
550-
tasklet_init(&host->dma_issue,
551-
renesas_sdhi_internal_dmac_issue_tasklet_fn,
552-
(unsigned long)host);
549+
INIT_WORK(&priv->dma_priv.dma_complete,
550+
renesas_sdhi_internal_dmac_complete_work_fn);
551+
INIT_WORK(&host->dma_issue,
552+
renesas_sdhi_internal_dmac_issue_work_fn);
553553

554554
/* Add pre_req and post_req */
555555
host->ops.pre_req = renesas_sdhi_internal_dmac_pre_req;

drivers/mmc/host/renesas_sdhi_sys_dmac.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,9 @@ static void renesas_sdhi_sys_dmac_start_dma(struct tmio_mmc_host *host,
312312
}
313313
}
314314

315-
static void renesas_sdhi_sys_dmac_issue_tasklet_fn(unsigned long priv)
315+
static void renesas_sdhi_sys_dmac_issue_work_fn(struct work_struct *work)
316316
{
317-
struct tmio_mmc_host *host = (struct tmio_mmc_host *)priv;
317+
struct tmio_mmc_host *host = from_work(host, work, dma_issue);
318318
struct dma_chan *chan = NULL;
319319

320320
spin_lock_irq(&host->lock);
@@ -401,9 +401,8 @@ static void renesas_sdhi_sys_dmac_request_dma(struct tmio_mmc_host *host,
401401
goto ebouncebuf;
402402

403403
init_completion(&priv->dma_priv.dma_dataend);
404-
tasklet_init(&host->dma_issue,
405-
renesas_sdhi_sys_dmac_issue_tasklet_fn,
406-
(unsigned long)host);
404+
INIT_WORK(&host->dma_issue,
405+
renesas_sdhi_sys_dmac_issue_work_fn);
407406
}
408407

409408
renesas_sdhi_sys_dmac_enable_dma(host, true);

drivers/mmc/host/tmio_mmc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/scatterlist.h>
2222
#include <linux/spinlock.h>
2323
#include <linux/interrupt.h>
24+
#include <linux/workqueue.h>
2425

2526
#define CTL_SD_CMD 0x00
2627
#define CTL_ARG_REG 0x04
@@ -153,7 +154,7 @@ struct tmio_mmc_host {
153154
bool dma_on;
154155
struct dma_chan *chan_rx;
155156
struct dma_chan *chan_tx;
156-
struct tasklet_struct dma_issue;
157+
struct work_struct dma_issue;
157158
struct scatterlist bounce_sg;
158159
u8 *bounce_buf;
159160

drivers/mmc/host/tmio_mmc_core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -608,15 +608,15 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat)
608608
} else {
609609
tmio_mmc_disable_mmc_irqs(host,
610610
TMIO_MASK_READOP);
611-
tasklet_schedule(&host->dma_issue);
611+
queue_work(system_bh_wq, &host->dma_issue);
612612
}
613613
} else {
614614
if (!host->dma_on) {
615615
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
616616
} else {
617617
tmio_mmc_disable_mmc_irqs(host,
618618
TMIO_MASK_WRITEOP);
619-
tasklet_schedule(&host->dma_issue);
619+
queue_work(system_bh_wq, &host->dma_issue);
620620
}
621621
}
622622
} else {

0 commit comments

Comments
 (0)