ARM: 7230/1: mmc: mmci: Fix PIO read for small SDIO packets
authorUlf Hansson <ulf.hansson@stericsson.com>
Tue, 13 Dec 2011 16:08:04 +0000 (17:08 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 20 Jan 2012 00:00:59 +0000 (00:00 +0000)
Corrects a bug in MMCI host driver which silently causes
small reads (< 4 bytes as only used in SDIO) from PL-18X to fail.

Signed-off-by: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com>
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: Fredrik Soderstedt <fredrik.soderstedt@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/mmc/host/mmci.c

index b09ccb7223e54d6b285ce5fd8e25be2ae6bc30b6..1f8832699cdf63873a81856009da456874135a59 100644 (file)
@@ -794,7 +794,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
                if (count <= 0)
                        break;
 
-               readsl(base + MMCIFIFO, ptr, count >> 2);
+               /*
+                * SDIO especially may want to send something that is
+                * not divisible by 4 (as opposed to card sectors
+                * etc). Therefore make sure to always read the last bytes
+                * while only doing full 32-bit reads towards the FIFO.
+                */
+               if (unlikely(count & 0x3)) {
+                       if (count < 4) {
+                               unsigned char buf[4];
+                               readsl(base + MMCIFIFO, buf, 1);
+                               memcpy(ptr, buf, count);
+                       } else {
+                               readsl(base + MMCIFIFO, ptr, count >> 2);
+                               count &= ~0x3;
+                       }
+               } else {
+                       readsl(base + MMCIFIFO, ptr, count >> 2);
+               }
 
                ptr += count;
                remain -= count;