diff options
author | ben@fluff.org.uk <ben@fluff.org.uk> | 2008-10-14 19:17:18 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-10-15 12:05:48 -0400 |
commit | 18280fff663b8ba57e349a81b999604bc1106926 (patch) | |
tree | 4b81883aacc8de3f4febb6aae51b03e81c1b3156 /drivers/mmc | |
parent | 088a78af978d0c8e339071a9b2bca1f4cb368f30 (diff) |
s3cmci: fix continual accesses to host->pio_ptr
The s3cmci driver uses the host->pio_ptr field to
point to the current position into the buffer for data
transfer. During the transfers it does the following:
while (fifo_words--)
*(host->pio_ptr++) = readl(from_ptr);
This is inefficent, as host->pio_ptr is not used in any
other part of the transfer but the compiler emits code
which does the following:
while (fifo_words--) {
u32 *ptr = host->pio_ptr;
*ptr = readl(from_ptr);
ptr++;
host->pio_ptr = ptr;
}
This is obviously a waste of a load and store each time
around the loop, which could be up to 16 times depending
on how much needs to be transfered.
Move the ptr accesses to outside the while loop so that
we do not end up reloading/re-writing the pointer.
Note, this seems to make the code 16 bytes larger.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/s3cmci.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index bb412331e3d7..5211d90d34ef 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -238,6 +238,7 @@ static void do_pio_read(struct s3cmci_host *host) | |||
238 | { | 238 | { |
239 | int res; | 239 | int res; |
240 | u32 fifo; | 240 | u32 fifo; |
241 | u32 *ptr; | ||
241 | u32 fifo_words; | 242 | u32 fifo_words; |
242 | void __iomem *from_ptr; | 243 | void __iomem *from_ptr; |
243 | 244 | ||
@@ -283,8 +284,10 @@ static void do_pio_read(struct s3cmci_host *host) | |||
283 | host->pio_count += fifo; | 284 | host->pio_count += fifo; |
284 | 285 | ||
285 | fifo_words = fifo >> 2; | 286 | fifo_words = fifo >> 2; |
287 | ptr = host->pio_ptr; | ||
286 | while (fifo_words--) | 288 | while (fifo_words--) |
287 | *(host->pio_ptr++) = readl(from_ptr); | 289 | *ptr++ = readl(from_ptr); |
290 | host->pio_ptr = ptr; | ||
288 | 291 | ||
289 | if (fifo & 3) { | 292 | if (fifo & 3) { |
290 | u32 n = fifo & 3; | 293 | u32 n = fifo & 3; |
@@ -319,6 +322,7 @@ static void do_pio_write(struct s3cmci_host *host) | |||
319 | void __iomem *to_ptr; | 322 | void __iomem *to_ptr; |
320 | int res; | 323 | int res; |
321 | u32 fifo; | 324 | u32 fifo; |
325 | u32 *ptr; | ||
322 | 326 | ||
323 | to_ptr = host->base + host->sdidata; | 327 | to_ptr = host->base + host->sdidata; |
324 | 328 | ||
@@ -353,8 +357,10 @@ static void do_pio_write(struct s3cmci_host *host) | |||
353 | host->pio_count += fifo; | 357 | host->pio_count += fifo; |
354 | 358 | ||
355 | fifo = (fifo + 3) >> 2; | 359 | fifo = (fifo + 3) >> 2; |
360 | ptr = host->pio_ptr; | ||
356 | while (fifo--) | 361 | while (fifo--) |
357 | writel(*(host->pio_ptr++), to_ptr); | 362 | writel(*ptr++, to_ptr); |
363 | host->pio_ptr = ptr; | ||
358 | } | 364 | } |
359 | 365 | ||
360 | enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); | 366 | enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); |