aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/renesas_sdhi_internal_dmac.c17
-rw-r--r--drivers/mmc/host/tmio_mmc_core.c13
2 files changed, 23 insertions, 7 deletions
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index f905f2361d12..8bae88a150fd 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -146,11 +146,8 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
146 WARN_ON(host->sg_len > 1); 146 WARN_ON(host->sg_len > 1);
147 147
148 /* This DMAC cannot handle if buffer is not 8-bytes alignment */ 148 /* This DMAC cannot handle if buffer is not 8-bytes alignment */
149 if (!IS_ALIGNED(sg->offset, 8)) { 149 if (!IS_ALIGNED(sg->offset, 8))
150 host->force_pio = true; 150 goto force_pio;
151 renesas_sdhi_internal_dmac_enable_dma(host, false);
152 return;
153 }
154 151
155 if (data->flags & MMC_DATA_READ) { 152 if (data->flags & MMC_DATA_READ) {
156 dtran_mode |= DTRAN_MODE_CH_NUM_CH1; 153 dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
@@ -163,8 +160,8 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
163 } 160 }
164 161
165 ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir); 162 ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir);
166 if (ret < 0) 163 if (ret == 0)
167 return; 164 goto force_pio;
168 165
169 renesas_sdhi_internal_dmac_enable_dma(host, true); 166 renesas_sdhi_internal_dmac_enable_dma(host, true);
170 167
@@ -176,6 +173,12 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
176 dtran_mode); 173 dtran_mode);
177 renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, 174 renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR,
178 sg->dma_address); 175 sg->dma_address);
176
177 return;
178
179force_pio:
180 host->force_pio = true;
181 renesas_sdhi_internal_dmac_enable_dma(host, false);
179} 182}
180 183
181static void renesas_sdhi_internal_dmac_issue_tasklet_fn(unsigned long arg) 184static void renesas_sdhi_internal_dmac_issue_tasklet_fn(unsigned long arg)
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index a7293e186e03..9c4e6199b854 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -47,6 +47,7 @@
47#include <linux/mmc/sdio.h> 47#include <linux/mmc/sdio.h>
48#include <linux/scatterlist.h> 48#include <linux/scatterlist.h>
49#include <linux/spinlock.h> 49#include <linux/spinlock.h>
50#include <linux/swiotlb.h>
50#include <linux/workqueue.h> 51#include <linux/workqueue.h>
51 52
52#include "tmio_mmc.h" 53#include "tmio_mmc.h"
@@ -1215,6 +1216,18 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
1215 mmc->max_blk_count = pdata->max_blk_count ? : 1216 mmc->max_blk_count = pdata->max_blk_count ? :
1216 (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs; 1217 (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs;
1217 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; 1218 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
1219 /*
1220 * Since swiotlb has memory size limitation, this will calculate
1221 * the maximum size locally (because we don't have any APIs for it now)
1222 * and check the current max_req_size. And then, this will update
1223 * the max_req_size if needed as a workaround.
1224 */
1225 if (swiotlb_max_segment()) {
1226 unsigned int max_size = (1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE;
1227
1228 if (mmc->max_req_size > max_size)
1229 mmc->max_req_size = max_size;
1230 }
1218 mmc->max_seg_size = mmc->max_req_size; 1231 mmc->max_seg_size = mmc->max_req_size;
1219 1232
1220 _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD || 1233 _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||