summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/dw_mmc.c
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2015-03-25 12:27:52 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2015-04-09 09:08:15 +0200
commit76184ac17edf3c640390b0eddc3aa7be1095fb9f (patch)
tree6de305bc6530a70b743c2a9262c88628ff36da8f /drivers/mmc/host/dw_mmc.c
parentmmc: dw_mmc: change idmac descriptor files to __le32 (diff)
downloadlinux-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.c59
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,