summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-pltfm.h
diff options
context:
space:
mode:
authorHaijun Zhang <Haijun.Zhang@freescale.com>2014-05-09 03:04:28 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:37:50 (GMT)
commit53a3bb65a928123d2a001840ecb774408cfc1ce0 (patch)
tree0cc65b0f2e7101b3b08e3d8b3d99922ccbdbad8c /drivers/mmc/host/sdhci-pltfm.h
parent3338d67019795bd214211932045e17baff22d5f3 (diff)
downloadlinux-fsl-qoriq-53a3bb65a928123d2a001840ecb774408cfc1ce0.tar.xz
mmc:esdhc: add esdhc support on ls1021a-qds
Ls1021a-qds has the same ip block as esdhc on powerpc platform. But they have diferent endian mode and different IO entry. So we change the IO entry to generic IO to support working on different architecture with different endian mode. Also add some properties to support esdhc on ls1021a-qds. Signed-off-by: Qiu WeiJie <B49553@freescale.com> Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com> --- This patch has sent to linux-mmc maillist. URL: https://patchwork.kernel.org/patch/3976141/ Change-Id: I4959b07bf9e38a442316f0f45425018fa7d6f579 Reviewed-on: http://git.am.freescale.net:8181/14824 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Xiaobo Xie <X.Xie@freescale.com> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'drivers/mmc/host/sdhci-pltfm.h')
-rw-r--r--drivers/mmc/host/sdhci-pltfm.h74
1 files changed, 53 insertions, 21 deletions
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index e15ced79..c31aa94 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -28,6 +28,10 @@ struct sdhci_pltfm_host {
/* migrate from sdhci_of_host */
unsigned int clock;
u16 xfer_mode_shadow;
+ enum endian_mode {
+ LITTLE_ENDIAN_MODE,
+ BIG_ENDIAN_MODE,
+ } endian_mode;
unsigned long private[0] ____cacheline_aligned;
};
@@ -37,33 +41,61 @@ struct sdhci_pltfm_host {
* These accessors are designed for big endian hosts doing I/O to
* little endian controllers incorporating a 32-bit hardware byte swapper.
*/
-static inline u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
+static inline void sdhci_clrsetbits(struct sdhci_host *host, u32 mask,
+ u32 val, int reg)
{
- return in_be32(host->ioaddr + reg);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ void __iomem *base = host->ioaddr + (reg & ~0x3);
+ u32 shift = (reg & 0x3) * 8;
+
+ if (pltfm_host->endian_mode == BIG_ENDIAN_MODE)
+ iowrite32be(((ioread32be(base) & ~(mask << shift)) |
+ (val << shift)), base);
+ else
+ iowrite32(((ioread32(base) & ~(mask << shift)) |
+ (val << shift)), base);
}
-static inline u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
+static inline u32 sdhci_32bs_readl(struct sdhci_host *host, int reg)
{
- return in_be16(host->ioaddr + (reg ^ 0x2));
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ if (pltfm_host->endian_mode == BIG_ENDIAN_MODE)
+ return ioread32be(host->ioaddr + reg);
+ else
+ return ioread32(host->ioaddr + reg);
}
-static inline u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
+static inline u16 sdhci_32bs_readw(struct sdhci_host *host, int reg)
{
- return in_8(host->ioaddr + (reg ^ 0x3));
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ if (pltfm_host->endian_mode == BIG_ENDIAN_MODE)
+ return ioread16be(host->ioaddr + (reg ^ 0x2));
+ else
+ return ioread16(host->ioaddr + (reg ^ 0x2));
}
-static inline void sdhci_be32bs_writel(struct sdhci_host *host,
- u32 val, int reg)
+static inline u8 sdhci_32bs_readb(struct sdhci_host *host, int reg)
{
- out_be32(host->ioaddr + reg, val);
+ return ioread8(host->ioaddr + (reg ^ 0x3));
}
-static inline void sdhci_be32bs_writew(struct sdhci_host *host,
+static inline void sdhci_32bs_writel(struct sdhci_host *host,
+ u32 val, int reg)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ if (pltfm_host->endian_mode == BIG_ENDIAN_MODE)
+ iowrite32be(val, host->ioaddr + reg);
+ else
+ iowrite32(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_32bs_writew(struct sdhci_host *host,
u16 val, int reg)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- int base = reg & ~0x3;
- int shift = (reg & 0x2) * 8;
switch (reg) {
case SDHCI_TRANSFER_MODE:
@@ -74,20 +106,20 @@ static inline void sdhci_be32bs_writew(struct sdhci_host *host,
pltfm_host->xfer_mode_shadow = val;
return;
case SDHCI_COMMAND:
- sdhci_be32bs_writel(host,
- val << 16 | pltfm_host->xfer_mode_shadow,
- SDHCI_TRANSFER_MODE);
+ if (pltfm_host->endian_mode == BIG_ENDIAN_MODE)
+ iowrite32be(val << 16 | pltfm_host->xfer_mode_shadow,
+ host->ioaddr + SDHCI_TRANSFER_MODE);
+ else
+ iowrite32(val << 16 | pltfm_host->xfer_mode_shadow,
+ host->ioaddr + SDHCI_TRANSFER_MODE);
return;
}
- clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+ sdhci_clrsetbits(host, 0xffff, val, reg);
}
-static inline void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
+static inline void sdhci_32bs_writeb(struct sdhci_host *host, u8 val, int reg)
{
- int base = reg & ~0x3;
- int shift = (reg & 0x3) * 8;
-
- clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+ sdhci_clrsetbits(host, 0xff, val, reg);
}
#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */