Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'fixes' into next

+45 -5
+45 -5
drivers/mmc/host/meson-gx-mmc.c
··· 165 165 166 166 unsigned int bounce_buf_size; 167 167 void *bounce_buf; 168 + void __iomem *bounce_iomem_buf; 168 169 dma_addr_t bounce_dma_addr; 169 170 struct sd_emmc_desc *descs; 170 171 dma_addr_t descs_dma_addr; ··· 746 745 writel(start, host->regs + SD_EMMC_START); 747 746 } 748 747 748 + /* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */ 749 + static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, 750 + size_t buflen, bool to_buffer) 751 + { 752 + unsigned int sg_flags = SG_MITER_ATOMIC; 753 + struct scatterlist *sgl = data->sg; 754 + unsigned int nents = data->sg_len; 755 + struct sg_mapping_iter miter; 756 + unsigned int offset = 0; 757 + 758 + if (to_buffer) 759 + sg_flags |= SG_MITER_FROM_SG; 760 + else 761 + sg_flags |= SG_MITER_TO_SG; 762 + 763 + sg_miter_start(&miter, sgl, nents, sg_flags); 764 + 765 + while ((offset < buflen) && sg_miter_next(&miter)) { 766 + unsigned int len; 767 + 768 + len = min(miter.length, buflen - offset); 769 + 770 + /* When dram_access_quirk, the bounce buffer is a iomem mapping */ 771 + if (host->dram_access_quirk) { 772 + if (to_buffer) 773 + memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len); 774 + else 775 + memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len); 776 + } else { 777 + if (to_buffer) 778 + memcpy(host->bounce_buf + offset, miter.addr, len); 779 + else 780 + memcpy(miter.addr, host->bounce_buf + offset, len); 781 + } 782 + 783 + offset += len; 784 + } 785 + 786 + sg_miter_stop(&miter); 787 + } 788 + 749 789 static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) 750 790 { 751 791 struct meson_host *host = mmc_priv(mmc); ··· 830 788 if (data->flags & MMC_DATA_WRITE) { 831 789 cmd_cfg |= CMD_CFG_DATA_WR; 832 790 WARN_ON(xfer_bytes > host->bounce_buf_size); 833 - sg_copy_to_buffer(data->sg, data->sg_len, 834 - host->bounce_buf, xfer_bytes); 791 + meson_mmc_copy_buffer(host, data, xfer_bytes, true); 835 792 dma_wmb(); 836 793 } 837 794 ··· 999 958 if (meson_mmc_bounce_buf_read(data)) { 1000 959 xfer_bytes = data->blksz * data->blocks; 1001 960 WARN_ON(xfer_bytes > host->bounce_buf_size); 1002 - sg_copy_from_buffer(data->sg, data->sg_len, 1003 - host->bounce_buf, xfer_bytes); 961 + meson_mmc_copy_buffer(host, data, xfer_bytes, false); 1004 962 } 1005 963 1006 964 next_cmd = meson_mmc_get_next_command(cmd); ··· 1219 1179 * instead of the DDR memory 1220 1180 */ 1221 1181 host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN; 1222 - host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; 1182 + host->bounce_iomem_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; 1223 1183 host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF; 1224 1184 } else { 1225 1185 /* data bounce buffer */