mmc: sdhci: avoid sync'ing the SG if there's no misalignment
authorRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 25 Apr 2014 11:58:29 +0000 (12:58 +0100)
committerChris Ball <chris@printf.net>
Thu, 22 May 2014 11:26:29 +0000 (07:26 -0400)
On read, we don't need to sync the whole scatterlist and then check
whether any segments need copying - if we check first, we avoid
potentially expensive cache handling.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
drivers/mmc/host/sdhci.c

index 074157e8e73d616bb8b8f566dd52fafafa69953c..4f878bcfaa2d0f1e4c6523f294d9651982edeab3 100644 (file)
@@ -602,6 +602,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
        u8 *align;
        char *buffer;
        unsigned long flags;
+       bool has_unaligned;
 
        if (data->flags & MMC_DATA_READ)
                direction = DMA_FROM_DEVICE;
@@ -614,7 +615,15 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
        dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
                128 * 4, direction);
 
-       if (data->flags & MMC_DATA_READ) {
+       /* Do a quick scan of the SG list for any unaligned mappings */
+       has_unaligned = false;
+       for_each_sg(data->sg, sg, host->sg_count, i)
+               if (sg_dma_address(sg) & 3) {
+                       has_unaligned = true;
+                       break;
+               }
+
+       if (has_unaligned && data->flags & MMC_DATA_READ) {
                dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
                        data->sg_len, direction);