aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kamensky <victor.kamensky@linaro.org>2013-11-08 15:58:46 -0800
committerGary S. Robertson <gary.robertson@linaro.org>2015-06-16 14:33:03 -0500
commite262b04deb8efe603bb1c1f5ab48a9437d68b73c (patch)
tree0a42261c214dfb2d0c707b731f1c033ca51f110a
parent1b47a5518ec7d3db40086b29794f7688c14e962b (diff)
mmc: dw_mmc endian fix
Need to use endian neutral functions to read/write h/w registers. I.e __raw_readl replaced with readl_relaxed and __raw_writel replaced with writel_relaxed. The relaxed version of function will read/write LE h/w register and byteswap it if host operates in BE mode. However in case of this file __raw_read(wlq) and __raw_write(wlq) are also used to transfer data from uchar buffer into h/w mmc host register. And in this case byteswap is not need - bytes of data buffer should go into h/w register in the same order as they are in memory. So we need to split control mci_readl/mci_writel macros from one that operates on data mci_readw_data, mci_readl_data, mci_readq_data, mci_writew, mci_writel_data, mci_writeq_data. The latter one do not do byte swaps. Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c42
-rw-r--r--drivers/mmc/host/dw_mmc.h26
2 files changed, 37 insertions, 31 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index f7c95abc8c11..f9a2e50c0c59 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1588,7 +1588,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),
+ mci_writew_data(host, DATA(host->data_offset),
host->part_buf16);
host->part_buf_count = 0;
}
@@ -1606,7 +1606,7 @@ 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),
+ mci_writew_data(host, DATA(host->data_offset),
aligned_buf[i]);
}
} else
@@ -1614,7 +1614,7 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
{
u16 *pdata = buf;
for (; cnt >= 2; cnt -= 2)
- mci_writew(host, DATA(host->data_offset), *pdata++);
+ mci_writew_data(host, DATA(host->data_offset), *pdata++);
buf = pdata;
}
/* put anything remaining in the part_buf */
@@ -1623,7 +1623,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),
+ mci_writew_data(host, DATA(host->data_offset),
host->part_buf16);
}
}
@@ -1639,7 +1639,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,
+ aligned_buf[i] = mci_readw_data(host,
DATA(host->data_offset));
/* memcpy from aligned buffer into output buffer */
memcpy(buf, aligned_buf, len);
@@ -1651,11 +1651,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_readw_data(host, DATA(host->data_offset));
buf = pdata;
}
if (cnt) {
- host->part_buf16 = mci_readw(host, DATA(host->data_offset));
+ host->part_buf16 = mci_readw_data(host, DATA(host->data_offset));
dw_mci_pull_final_bytes(host, buf, cnt);
}
}
@@ -1671,7 +1671,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),
+ mci_writel_data(host, DATA(host->data_offset),
host->part_buf32);
host->part_buf_count = 0;
}
@@ -1689,7 +1689,7 @@ 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),
+ mci_writel_data(host, DATA(host->data_offset),
aligned_buf[i]);
}
} else
@@ -1697,7 +1697,7 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
{
u32 *pdata = buf;
for (; cnt >= 4; cnt -= 4)
- mci_writel(host, DATA(host->data_offset), *pdata++);
+ mci_writel_data(host, DATA(host->data_offset), *pdata++);
buf = pdata;
}
/* put anything remaining in the part_buf */
@@ -1706,7 +1706,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),
+ mci_writel_data(host, DATA(host->data_offset),
host->part_buf32);
}
}
@@ -1722,7 +1722,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,
+ aligned_buf[i] = mci_readl_data(host,
DATA(host->data_offset));
/* memcpy from aligned buffer into output buffer */
memcpy(buf, aligned_buf, len);
@@ -1734,11 +1734,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_readl_data(host, DATA(host->data_offset));
buf = pdata;
}
if (cnt) {
- host->part_buf32 = mci_readl(host, DATA(host->data_offset));
+ host->part_buf32 = mci_readl_data(host, DATA(host->data_offset));
dw_mci_pull_final_bytes(host, buf, cnt);
}
}
@@ -1755,7 +1755,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),
+ mci_writeq_data(host, DATA(host->data_offset),
host->part_buf);
host->part_buf_count = 0;
}
@@ -1773,7 +1773,7 @@ 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),
+ mci_writeq_data(host, DATA(host->data_offset),
aligned_buf[i]);
}
} else
@@ -1781,7 +1781,7 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
{
u64 *pdata = buf;
for (; cnt >= 8; cnt -= 8)
- mci_writeq(host, DATA(host->data_offset), *pdata++);
+ mci_writeq_data(host, DATA(host->data_offset), *pdata++);
buf = pdata;
}
/* put anything remaining in the part_buf */
@@ -1790,7 +1790,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),
+ mci_writeq_data(host, DATA(host->data_offset),
host->part_buf);
}
}
@@ -1806,7 +1806,7 @@ 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,
+ aligned_buf[i] = mci_readq_data(host,
DATA(host->data_offset));
/* memcpy from aligned buffer into output buffer */
memcpy(buf, aligned_buf, len);
@@ -1818,11 +1818,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_readq_data(host, DATA(host->data_offset));
buf = pdata;
}
if (cnt) {
- host->part_buf = mci_readq(host, DATA(host->data_offset));
+ host->part_buf = mci_readq_data(host, DATA(host->data_offset));
dw_mci_pull_final_bytes(host, buf, cnt);
}
}
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 01b99e8a9190..dbc54f30afc5 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -160,21 +160,27 @@
/* Register access macros */
#define mci_readl(dev, reg) \
- __raw_readl((dev)->regs + SDMMC_##reg)
+ readl_relaxed((dev)->regs + SDMMC_##reg)
#define mci_writel(dev, reg, value) \
- __raw_writel((value), (dev)->regs + SDMMC_##reg)
+ writel_relaxed((value), (dev)->regs + SDMMC_##reg)
/* 16-bit FIFO access macros */
-#define mci_readw(dev, reg) \
+#define mci_readw_data(dev, reg) \
__raw_readw((dev)->regs + SDMMC_##reg)
-#define mci_writew(dev, reg, value) \
+#define mci_writew_data(dev, reg, value) \
__raw_writew((value), (dev)->regs + SDMMC_##reg)
+/* 32-bit FIFO access macros */
+#define mci_readl_data(dev, reg) \
+ __raw_readl((dev)->regs + SDMMC_##reg)
+#define mci_writel_data(dev, reg, value) \
+ __raw_writel((value), (dev)->regs + SDMMC_##reg)
+
/* 64-bit FIFO access macros */
#ifdef readq
-#define mci_readq(dev, reg) \
+#define mci_readq_data(dev, reg) \
__raw_readq((dev)->regs + SDMMC_##reg)
-#define mci_writeq(dev, reg, value) \
+#define mci_writeq_data(dev, reg, value) \
__raw_writeq((value), (dev)->regs + SDMMC_##reg)
#else
/*
@@ -185,10 +191,10 @@
* executed on those machines. Defining these macros here keeps the
* rest of the code free from ifdefs.
*/
-#define mci_readq(dev, reg) \
- (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg))
-#define mci_writeq(dev, reg, value) \
- (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg) = (value))
+#define mci_readq_data(dev, reg) \
+ ({ u64 __r = le64_to_cpu(*(volatile u64 __force *)((dev)->regs + SDMMC_##reg)); __r; })
+#define mci_writeq_data(dev, reg, value) \
+ (*(volatile u64 __force *)((dev)->regs + SDMMC_##reg) = (cpu_to_le64(value)))
#endif
extern int dw_mci_probe(struct dw_mci *host);