diff options
author | Ben Dooks <ben.dooks@codethink.co.uk> | 2015-03-25 12:27:52 +0100 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2015-04-09 09:08:15 +0200 |
commit | 76184ac17edf3c640390b0eddc3aa7be1095fb9f (patch) | |
tree | 6de305bc6530a70b743c2a9262c88628ff36da8f /drivers/mmc/host/dw_mmc.c | |
parent | mmc: dw_mmc: change idmac descriptor files to __le32 (diff) | |
download | linux-76184ac17edf3c640390b0eddc3aa7be1095fb9f.tar.xz linux-76184ac17edf3c640390b0eddc3aa7be1095fb9f.zip |
mmc: dw_mmc: fix fifo ordering in big endian
The dw_mmc driver changes to make the IO accesors endian agnostic did not
take into account the fifo accesses do not need to be swapped. To fix this
add a mmci_fifo_read/write wrapper to allow these to be passed through the
IO without being swapped.
Since these are now specific functions, it would be easier just to store
the pointer to the fifo registers in the host block instead of the offset
to them. So change the host->data_offset to host->fifo_reg (which also
means we catch all the places this is read or written).
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 59 |
1 files changed, 24 insertions, 35 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a09840d0c221..8ce9a52d365b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1757,8 +1757,7 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt) buf += len; cnt -= len; if (host->part_buf_count == 2) { - mci_writew(host, DATA(host->data_offset), - host->part_buf16); + mci_fifo_writew(host->fifo_reg, host->part_buf16); host->part_buf_count = 0; } } @@ -1775,15 +1774,14 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt) cnt -= len; /* push data from aligned buffer into fifo */ for (i = 0; i < items; ++i) - mci_writew(host, DATA(host->data_offset), - aligned_buf[i]); + mci_fifo_writew(host->fifo_reg, aligned_buf[i]); } } else #endif { u16 *pdata = buf; for (; cnt >= 2; cnt -= 2) - mci_writew(host, DATA(host->data_offset), *pdata++); + mci_fifo_writew(host->fifo_reg, *pdata++); buf = pdata; } /* put anything remaining in the part_buf */ @@ -1792,8 +1790,7 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt) /* Push data if we have reached the expected data length */ if ((data->bytes_xfered + init_cnt) == (data->blksz * data->blocks)) - mci_writew(host, DATA(host->data_offset), - host->part_buf16); + mci_fifo_writew(host->fifo_reg, host->part_buf16); } } @@ -1808,8 +1805,7 @@ static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt) int items = len >> 1; int i; for (i = 0; i < items; ++i) - aligned_buf[i] = mci_readw(host, - DATA(host->data_offset)); + aligned_buf[i] = mci_fifo_readw(host->fifo_reg); /* memcpy from aligned buffer into output buffer */ memcpy(buf, aligned_buf, len); buf += len; @@ -1820,11 +1816,11 @@ static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt) { u16 *pdata = buf; for (; cnt >= 2; cnt -= 2) - *pdata++ = mci_readw(host, DATA(host->data_offset)); + *pdata++ = mci_fifo_readw(host->fifo_reg); buf = pdata; } if (cnt) { - host->part_buf16 = mci_readw(host, DATA(host->data_offset)); + host->part_buf16 = mci_fifo_readw(host->fifo_reg); dw_mci_pull_final_bytes(host, buf, cnt); } } @@ -1840,8 +1836,7 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt) buf += len; cnt -= len; if (host->part_buf_count == 4) { - mci_writel(host, DATA(host->data_offset), - host->part_buf32); + mci_fifo_writel(host->fifo_reg, host->part_buf32); host->part_buf_count = 0; } } @@ -1858,15 +1853,14 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt) cnt -= len; /* push data from aligned buffer into fifo */ for (i = 0; i < items; ++i) - mci_writel(host, DATA(host->data_offset), - aligned_buf[i]); + mci_fifo_writel(host->fifo_reg, aligned_buf[i]); } } else #endif { u32 *pdata = buf; for (; cnt >= 4; cnt -= 4) - mci_writel(host, DATA(host->data_offset), *pdata++); + mci_fifo_writel(host->fifo_reg, *pdata++); buf = pdata; } /* put anything remaining in the part_buf */ @@ -1875,8 +1869,7 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt) /* Push data if we have reached the expected data length */ if ((data->bytes_xfered + init_cnt) == (data->blksz * data->blocks)) - mci_writel(host, DATA(host->data_offset), - host->part_buf32); + mci_fifo_writel(host->fifo_reg, host->part_buf32); } } @@ -1891,8 +1884,7 @@ static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt) int items = len >> 2; int i; for (i = 0; i < items; ++i) - aligned_buf[i] = mci_readl(host, - DATA(host->data_offset)); + aligned_buf[i] = mci_fifo_readl(host->fifo_reg); /* memcpy from aligned buffer into output buffer */ memcpy(buf, aligned_buf, len); buf += len; @@ -1903,11 +1895,11 @@ static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt) { u32 *pdata = buf; for (; cnt >= 4; cnt -= 4) - *pdata++ = mci_readl(host, DATA(host->data_offset)); + *pdata++ = mci_fifo_readl(host->fifo_reg); buf = pdata; } if (cnt) { - host->part_buf32 = mci_readl(host, DATA(host->data_offset)); + host->part_buf32 = mci_fifo_readl(host->fifo_reg); dw_mci_pull_final_bytes(host, buf, cnt); } } @@ -1924,8 +1916,7 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt) cnt -= len; if (host->part_buf_count == 8) { - mci_writeq(host, DATA(host->data_offset), - host->part_buf); + mci_fifo_writeq(host->fifo_reg, host->part_buf); host->part_buf_count = 0; } } @@ -1942,15 +1933,14 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt) cnt -= len; /* push data from aligned buffer into fifo */ for (i = 0; i < items; ++i) - mci_writeq(host, DATA(host->data_offset), - aligned_buf[i]); + mci_fifo_writeq(host->fifo_reg, aligned_buf[i]); } } else #endif { u64 *pdata = buf; for (; cnt >= 8; cnt -= 8) - mci_writeq(host, DATA(host->data_offset), *pdata++); + mci_fifo_writeq(host->fifo_reg, *pdata++); buf = pdata; } /* put anything remaining in the part_buf */ @@ -1959,8 +1949,7 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt) /* Push data if we have reached the expected data length */ if ((data->bytes_xfered + init_cnt) == (data->blksz * data->blocks)) - mci_writeq(host, DATA(host->data_offset), - host->part_buf); + mci_fifo_writeq(host->fifo_reg, host->part_buf); } } @@ -1975,8 +1964,8 @@ static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt) int items = len >> 3; int i; for (i = 0; i < items; ++i) - aligned_buf[i] = mci_readq(host, - DATA(host->data_offset)); + aligned_buf[i] = mci_fifo_readq(host->fifo_reg); + /* memcpy from aligned buffer into output buffer */ memcpy(buf, aligned_buf, len); buf += len; @@ -1987,11 +1976,11 @@ static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt) { u64 *pdata = buf; for (; cnt >= 8; cnt -= 8) - *pdata++ = mci_readq(host, DATA(host->data_offset)); + *pdata++ = mci_fifo_readq(host->fifo_reg); buf = pdata; } if (cnt) { - host->part_buf = mci_readq(host, DATA(host->data_offset)); + host->part_buf = mci_fifo_readq(host->fifo_reg); dw_mci_pull_final_bytes(host, buf, cnt); } } @@ -2852,9 +2841,9 @@ int dw_mci_probe(struct dw_mci *host) dev_info(host->dev, "Version ID is %04x\n", host->verid); if (host->verid < DW_MMC_240A) - host->data_offset = DATA_OFFSET; + host->fifo_reg = host->regs + DATA_OFFSET; else - host->data_offset = DATA_240A_OFFSET; + host->fifo_reg = host->regs + DATA_240A_OFFSET; tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host); ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, |