Skip to content

Commit 4a09d38

Browse files
committed
Merge tag 'mmc-v5.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fix from Ulf Hansson: "Use memcpy_to/fromio for dram-access-quirk in the meson-gx host driver" * tag 'mmc-v5.13-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: meson-gx: use memcpy_to/fromio for dram-access-quirk
2 parents 7749b03 + 103a534 commit 4a09d38

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

drivers/mmc/host/meson-gx-mmc.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ struct meson_host {
165165

166166
unsigned int bounce_buf_size;
167167
void *bounce_buf;
168+
void __iomem *bounce_iomem_buf;
168169
dma_addr_t bounce_dma_addr;
169170
struct sd_emmc_desc *descs;
170171
dma_addr_t descs_dma_addr;
@@ -745,6 +746,47 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg)
745746
writel(start, host->regs + SD_EMMC_START);
746747
}
747748

749+
/* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */
750+
static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data,
751+
size_t buflen, bool to_buffer)
752+
{
753+
unsigned int sg_flags = SG_MITER_ATOMIC;
754+
struct scatterlist *sgl = data->sg;
755+
unsigned int nents = data->sg_len;
756+
struct sg_mapping_iter miter;
757+
unsigned int offset = 0;
758+
759+
if (to_buffer)
760+
sg_flags |= SG_MITER_FROM_SG;
761+
else
762+
sg_flags |= SG_MITER_TO_SG;
763+
764+
sg_miter_start(&miter, sgl, nents, sg_flags);
765+
766+
while ((offset < buflen) && sg_miter_next(&miter)) {
767+
unsigned int len;
768+
769+
len = min(miter.length, buflen - offset);
770+
771+
/* When dram_access_quirk, the bounce buffer is a iomem mapping */
772+
if (host->dram_access_quirk) {
773+
if (to_buffer)
774+
memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len);
775+
else
776+
memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len);
777+
} else {
778+
if (to_buffer)
779+
memcpy(host->bounce_buf + offset, miter.addr, len);
780+
else
781+
memcpy(miter.addr, host->bounce_buf + offset, len);
782+
}
783+
784+
offset += len;
785+
}
786+
787+
sg_miter_stop(&miter);
788+
}
789+
748790
static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
749791
{
750792
struct meson_host *host = mmc_priv(mmc);
@@ -788,8 +830,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
788830
if (data->flags & MMC_DATA_WRITE) {
789831
cmd_cfg |= CMD_CFG_DATA_WR;
790832
WARN_ON(xfer_bytes > host->bounce_buf_size);
791-
sg_copy_to_buffer(data->sg, data->sg_len,
792-
host->bounce_buf, xfer_bytes);
833+
meson_mmc_copy_buffer(host, data, xfer_bytes, true);
793834
dma_wmb();
794835
}
795836

@@ -958,8 +999,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
958999
if (meson_mmc_bounce_buf_read(data)) {
9591000
xfer_bytes = data->blksz * data->blocks;
9601001
WARN_ON(xfer_bytes > host->bounce_buf_size);
961-
sg_copy_from_buffer(data->sg, data->sg_len,
962-
host->bounce_buf, xfer_bytes);
1002+
meson_mmc_copy_buffer(host, data, xfer_bytes, false);
9631003
}
9641004

9651005
next_cmd = meson_mmc_get_next_command(cmd);
@@ -1179,7 +1219,7 @@ static int meson_mmc_probe(struct platform_device *pdev)
11791219
* instead of the DDR memory
11801220
*/
11811221
host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN;
1182-
host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF;
1222+
host->bounce_iomem_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF;
11831223
host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF;
11841224
} else {
11851225
/* data bounce buffer */

0 commit comments

Comments
 (0)