uniphier-sd.c (a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0) uniphier-sd.c (921c87ba3893b5d3608e7f248366266b40b86c75)
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (C) 2017-2018 Socionext Inc.
4// Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5
6#include <linux/bitfield.h>
7#include <linux/bitops.h>
8#include <linux/clk.h>

--- 76 unchanged lines hidden (view full) ---

85}
86
87static void uniphier_sd_dma_endisable(struct tmio_mmc_host *host, int enable)
88{
89 sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? DMA_ENABLE_DMASDRW : 0);
90}
91
92/* external DMA engine */
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (C) 2017-2018 Socionext Inc.
4// Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5
6#include <linux/bitfield.h>
7#include <linux/bitops.h>
8#include <linux/clk.h>

--- 76 unchanged lines hidden (view full) ---

85}
86
87static void uniphier_sd_dma_endisable(struct tmio_mmc_host *host, int enable)
88{
89 sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? DMA_ENABLE_DMASDRW : 0);
90}
91
92/* external DMA engine */
93static void uniphier_sd_external_dma_issue(struct tasklet_struct *t)
93static void uniphier_sd_external_dma_issue(struct work_struct *t)
94{
94{
95 struct tmio_mmc_host *host = from_tasklet(host, t, dma_issue);
95 struct tmio_mmc_host *host = from_work(host, t, dma_issue);
96 struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
97
98 uniphier_sd_dma_endisable(host, 1);
99 dma_async_issue_pending(priv->chan);
100}
101
102static void uniphier_sd_external_dma_callback(void *param,
103 const struct dmaengine_result *result)

--- 90 unchanged lines hidden (view full) ---

194 return; /* just use PIO even for -EPROBE_DEFER */
195 }
196
197 /* this driver uses a single channel for both RX an TX */
198 priv->chan = chan;
199 host->chan_rx = chan;
200 host->chan_tx = chan;
201
96 struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
97
98 uniphier_sd_dma_endisable(host, 1);
99 dma_async_issue_pending(priv->chan);
100}
101
102static void uniphier_sd_external_dma_callback(void *param,
103 const struct dmaengine_result *result)

--- 90 unchanged lines hidden (view full) ---

194 return; /* just use PIO even for -EPROBE_DEFER */
195 }
196
197 /* this driver uses a single channel for both RX an TX */
198 priv->chan = chan;
199 host->chan_rx = chan;
200 host->chan_tx = chan;
201
202 tasklet_setup(&host->dma_issue, uniphier_sd_external_dma_issue);
202 INIT_WORK(&host->dma_issue, uniphier_sd_external_dma_issue);
203}
204
205static void uniphier_sd_external_dma_release(struct tmio_mmc_host *host)
206{
207 struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
208
209 if (priv->chan)
210 dma_release_channel(priv->chan);

--- 20 unchanged lines hidden (view full) ---

231 .start = uniphier_sd_external_dma_start,
232 .enable = uniphier_sd_external_dma_enable,
233 .request = uniphier_sd_external_dma_request,
234 .release = uniphier_sd_external_dma_release,
235 .abort = uniphier_sd_external_dma_abort,
236 .dataend = uniphier_sd_external_dma_dataend,
237};
238
203}
204
205static void uniphier_sd_external_dma_release(struct tmio_mmc_host *host)
206{
207 struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
208
209 if (priv->chan)
210 dma_release_channel(priv->chan);

--- 20 unchanged lines hidden (view full) ---

231 .start = uniphier_sd_external_dma_start,
232 .enable = uniphier_sd_external_dma_enable,
233 .request = uniphier_sd_external_dma_request,
234 .release = uniphier_sd_external_dma_release,
235 .abort = uniphier_sd_external_dma_abort,
236 .dataend = uniphier_sd_external_dma_dataend,
237};
238
239static void uniphier_sd_internal_dma_issue(struct tasklet_struct *t)
239static void uniphier_sd_internal_dma_issue(struct work_struct *t)
240{
240{
241 struct tmio_mmc_host *host = from_tasklet(host, t, dma_issue);
241 struct tmio_mmc_host *host = from_work(host, t, dma_issue);
242 unsigned long flags;
243
244 spin_lock_irqsave(&host->lock, flags);
245 tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
246 spin_unlock_irqrestore(&host->lock, flags);
247
248 uniphier_sd_dma_endisable(host, 1);
249 writel(UNIPHIER_SD_DMA_CTL_START, host->ctl + UNIPHIER_SD_DMA_CTL);

--- 62 unchanged lines hidden (view full) ---

312 * Due to a hardware bug, Pro5 cannot use DMA for RX.
313 * We can still use DMA for TX, but PIO for RX.
314 */
315 if (!(priv->caps & UNIPHIER_SD_CAP_BROKEN_DMA_RX))
316 host->chan_rx = (void *)0xdeadbeaf;
317
318 host->chan_tx = (void *)0xdeadbeaf;
319
242 unsigned long flags;
243
244 spin_lock_irqsave(&host->lock, flags);
245 tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
246 spin_unlock_irqrestore(&host->lock, flags);
247
248 uniphier_sd_dma_endisable(host, 1);
249 writel(UNIPHIER_SD_DMA_CTL_START, host->ctl + UNIPHIER_SD_DMA_CTL);

--- 62 unchanged lines hidden (view full) ---

312 * Due to a hardware bug, Pro5 cannot use DMA for RX.
313 * We can still use DMA for TX, but PIO for RX.
314 */
315 if (!(priv->caps & UNIPHIER_SD_CAP_BROKEN_DMA_RX))
316 host->chan_rx = (void *)0xdeadbeaf;
317
318 host->chan_tx = (void *)0xdeadbeaf;
319
320 tasklet_setup(&host->dma_issue, uniphier_sd_internal_dma_issue);
320 INIT_WORK(&host->dma_issue, uniphier_sd_internal_dma_issue);
321}
322
323static void uniphier_sd_internal_dma_release(struct tmio_mmc_host *host)
324{
325 /* Each value is set to zero to assume "disabling" each DMA */
326 host->chan_rx = NULL;
327 host->chan_tx = NULL;
328}

--- 440 unchanged lines hidden ---
321}
322
323static void uniphier_sd_internal_dma_release(struct tmio_mmc_host *host)
324{
325 /* Each value is set to zero to assume "disabling" each DMA */
326 host->chan_rx = NULL;
327 host->chan_tx = NULL;
328}

--- 440 unchanged lines hidden ---