diff options
-rw-r--r-- | drivers/mmc/host/mmci.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b09ccb7223e5..1f8832699cdf 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -794,7 +794,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema | |||
794 | if (count <= 0) | 794 | if (count <= 0) |
795 | break; | 795 | break; |
796 | 796 | ||
797 | readsl(base + MMCIFIFO, ptr, count >> 2); | 797 | /* |
798 | * SDIO especially may want to send something that is | ||
799 | * not divisible by 4 (as opposed to card sectors | ||
800 | * etc). Therefore make sure to always read the last bytes | ||
801 | * while only doing full 32-bit reads towards the FIFO. | ||
802 | */ | ||
803 | if (unlikely(count & 0x3)) { | ||
804 | if (count < 4) { | ||
805 | unsigned char buf[4]; | ||
806 | readsl(base + MMCIFIFO, buf, 1); | ||
807 | memcpy(ptr, buf, count); | ||
808 | } else { | ||
809 | readsl(base + MMCIFIFO, ptr, count >> 2); | ||
810 | count &= ~0x3; | ||
811 | } | ||
812 | } else { | ||
813 | readsl(base + MMCIFIFO, ptr, count >> 2); | ||
814 | } | ||
798 | 815 | ||
799 | ptr += count; | 816 | ptr += count; |
800 | remain -= count; | 817 | remain -= count; |