forked from mirrors/linux
		
	mmc: sdhci-of-esdhc: support both BE and LE host controller
To support little endian eSDHC controller, we redefine both BE and LE IO accessors. In the new accessors, use ioread*/iowrite* instead of in_be32/out_be32 and will select accessors according to endian mode in probe function. Signed-off-by: Yangbo Lu <yangbo.lu@freescale.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
		
							parent
							
								
									e38eeca5c2
								
							
						
					
					
						commit
						f4932cfd22
					
				
					 2 changed files with 344 additions and 115 deletions
				
			
		| 
						 | 
					@ -24,6 +24,8 @@
 | 
				
			||||||
				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
 | 
									SDHCI_QUIRK_PIO_NEEDS_DELAY | \
 | 
				
			||||||
				SDHCI_QUIRK_NO_HISPD_BIT)
 | 
									SDHCI_QUIRK_NO_HISPD_BIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ESDHC_PROCTL		0x28
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ESDHC_SYSTEM_CONTROL	0x2c
 | 
					#define ESDHC_SYSTEM_CONTROL	0x2c
 | 
				
			||||||
#define ESDHC_CLOCK_MASK	0x0000fff0
 | 
					#define ESDHC_CLOCK_MASK	0x0000fff0
 | 
				
			||||||
#define ESDHC_PREDIV_SHIFT	8
 | 
					#define ESDHC_PREDIV_SHIFT	8
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,122 +24,318 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VENDOR_V_22	0x12
 | 
					#define VENDOR_V_22	0x12
 | 
				
			||||||
#define VENDOR_V_23	0x13
 | 
					#define VENDOR_V_23	0x13
 | 
				
			||||||
static u32 esdhc_readl(struct sdhci_host *host, int reg)
 | 
					
 | 
				
			||||||
 | 
					struct sdhci_esdhc {
 | 
				
			||||||
 | 
						u8 vendor_ver;
 | 
				
			||||||
 | 
						u8 spec_ver;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register
 | 
				
			||||||
 | 
					 *		       to make it compatible with SD spec.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @host: pointer to sdhci_host
 | 
				
			||||||
 | 
					 * @spec_reg: SD spec register address
 | 
				
			||||||
 | 
					 * @value: 32bit eSDHC register value on spec_reg address
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
 | 
				
			||||||
 | 
					 * registers are 32 bits. There are differences in register size, register
 | 
				
			||||||
 | 
					 * address, register function, bit position and function between eSDHC spec
 | 
				
			||||||
 | 
					 * and SD spec.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return a fixed up register value
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static u32 esdhc_readl_fixup(struct sdhci_host *host,
 | 
				
			||||||
 | 
									     int spec_reg, u32 value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 | 
				
			||||||
 | 
						struct sdhci_esdhc *esdhc = pltfm_host->priv;
 | 
				
			||||||
	u32 ret;
 | 
						u32 ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = in_be32(host->ioaddr + reg);
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * The bit of ADMA flag in eSDHC is not compatible with standard
 | 
						 * The bit of ADMA flag in eSDHC is not compatible with standard
 | 
				
			||||||
	 * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
 | 
						 * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
 | 
				
			||||||
	 * supported by eSDHC.
 | 
						 * supported by eSDHC.
 | 
				
			||||||
	 * And for many FSL eSDHC controller, the reset value of field
 | 
						 * And for many FSL eSDHC controller, the reset value of field
 | 
				
			||||||
	 * SDHCI_CAN_DO_ADMA1 is one, but some of them can't support ADMA,
 | 
						 * SDHCI_CAN_DO_ADMA1 is 1, but some of them can't support ADMA,
 | 
				
			||||||
	 * only these vendor version is greater than 2.2/0x12 support ADMA.
 | 
						 * only these vendor version is greater than 2.2/0x12 support ADMA.
 | 
				
			||||||
	 * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the
 | 
					 | 
				
			||||||
	 * the verdor version number, oxFE is SDHCI_HOST_VERSION.
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) {
 | 
						if ((spec_reg == SDHCI_CAPABILITIES) && (value & SDHCI_CAN_DO_ADMA1)) {
 | 
				
			||||||
		u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
 | 
							if (esdhc->vendor_ver > VENDOR_V_22) {
 | 
				
			||||||
		tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
 | 
								ret = value | SDHCI_CAN_DO_ADMA2;
 | 
				
			||||||
		if (tmp > VENDOR_V_22)
 | 
								return ret;
 | 
				
			||||||
			ret |= SDHCI_CAN_DO_ADMA2;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = value;
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u16 esdhc_readw(struct sdhci_host *host, int reg)
 | 
					static u16 esdhc_readw_fixup(struct sdhci_host *host,
 | 
				
			||||||
 | 
									     int spec_reg, u32 value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 ret;
 | 
						u16 ret;
 | 
				
			||||||
	int base = reg & ~0x3;
 | 
						int shift = (spec_reg & 0x2) * 8;
 | 
				
			||||||
	int shift = (reg & 0x2) * 8;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(reg == SDHCI_HOST_VERSION))
 | 
						if (spec_reg == SDHCI_HOST_VERSION)
 | 
				
			||||||
		ret = in_be32(host->ioaddr + base) & 0xffff;
 | 
							ret = value & 0xffff;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		ret = (in_be32(host->ioaddr + base) >> shift) & 0xffff;
 | 
							ret = (value >> shift) & 0xffff;
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 esdhc_readb(struct sdhci_host *host, int reg)
 | 
					static u8 esdhc_readb_fixup(struct sdhci_host *host,
 | 
				
			||||||
 | 
									     int spec_reg, u32 value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int base = reg & ~0x3;
 | 
						u8 ret;
 | 
				
			||||||
	int shift = (reg & 0x3) * 8;
 | 
						u8 dma_bits;
 | 
				
			||||||
	u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff;
 | 
						int shift = (spec_reg & 0x3) * 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = (value >> shift) & 0xff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * "DMA select" locates at offset 0x28 in SD specification, but on
 | 
						 * "DMA select" locates at offset 0x28 in SD specification, but on
 | 
				
			||||||
	 * P5020 or P3041, it locates at 0x29.
 | 
						 * P5020 or P3041, it locates at 0x29.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (reg == SDHCI_HOST_CONTROL) {
 | 
						if (spec_reg == SDHCI_HOST_CONTROL) {
 | 
				
			||||||
		u32 dma_bits;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		dma_bits = in_be32(host->ioaddr + reg);
 | 
					 | 
				
			||||||
		/* DMA select is 22,23 bits in Protocol Control Register */
 | 
							/* DMA select is 22,23 bits in Protocol Control Register */
 | 
				
			||||||
		dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK;
 | 
							dma_bits = (value >> 5) & SDHCI_CTRL_DMA_MASK;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* fixup the result */
 | 
							/* fixup the result */
 | 
				
			||||||
		ret &= ~SDHCI_CTRL_DMA_MASK;
 | 
							ret &= ~SDHCI_CTRL_DMA_MASK;
 | 
				
			||||||
		ret |= dma_bits;
 | 
							ret |= dma_bits;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * esdhc_write*_fixup - Fixup the SD spec register value so that it could be
 | 
				
			||||||
 | 
					 *			written into eSDHC register.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @host: pointer to sdhci_host
 | 
				
			||||||
 | 
					 * @spec_reg: SD spec register address
 | 
				
			||||||
 | 
					 * @value: 8/16/32bit SD spec register value that would be written
 | 
				
			||||||
 | 
					 * @old_value: 32bit eSDHC register value on spec_reg address
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
 | 
				
			||||||
 | 
					 * registers are 32 bits. There are differences in register size, register
 | 
				
			||||||
 | 
					 * address, register function, bit position and function between eSDHC spec
 | 
				
			||||||
 | 
					 * and SD spec.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return a fixed up register value
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static u32 esdhc_writel_fixup(struct sdhci_host *host,
 | 
				
			||||||
 | 
									     int spec_reg, u32 value, u32 old_value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Enabling IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
 | 
				
			||||||
 | 
						 * when SYSCTL[RSTD] is set for some special operations.
 | 
				
			||||||
 | 
						 * No any impact on other operation.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (spec_reg == SDHCI_INT_ENABLE)
 | 
				
			||||||
 | 
							ret = value | SDHCI_INT_BLK_GAP;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ret = value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
 | 
					static u32 esdhc_writew_fixup(struct sdhci_host *host,
 | 
				
			||||||
 | 
									     int spec_reg, u16 value, u32 old_value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*
 | 
						struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 | 
				
			||||||
	 * Enable IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
 | 
						int shift = (spec_reg & 0x2) * 8;
 | 
				
			||||||
	 * when SYSCTL[RSTD]) is set for some special operations.
 | 
						u32 ret;
 | 
				
			||||||
	 * No any impact other operation.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (reg == SDHCI_INT_ENABLE)
 | 
					 | 
				
			||||||
		val |= SDHCI_INT_BLK_GAP;
 | 
					 | 
				
			||||||
	sdhci_be32bs_writel(host, val, reg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
 | 
						switch (spec_reg) {
 | 
				
			||||||
{
 | 
						case SDHCI_TRANSFER_MODE:
 | 
				
			||||||
	if (reg == SDHCI_BLOCK_SIZE) {
 | 
							/*
 | 
				
			||||||
 | 
							 * Postpone this write, we must do it together with a
 | 
				
			||||||
 | 
							 * command write that is down below. Return old value.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							pltfm_host->xfer_mode_shadow = value;
 | 
				
			||||||
 | 
							return old_value;
 | 
				
			||||||
 | 
						case SDHCI_COMMAND:
 | 
				
			||||||
 | 
							ret = (value << 16) | pltfm_host->xfer_mode_shadow;
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = old_value & (~(0xffff << shift));
 | 
				
			||||||
 | 
						ret |= (value << shift);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (spec_reg == SDHCI_BLOCK_SIZE) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Two last DMA bits are reserved, and first one is used for
 | 
							 * Two last DMA bits are reserved, and first one is used for
 | 
				
			||||||
		 * non-standard blksz of 4096 bytes that we don't support
 | 
							 * non-standard blksz of 4096 bytes that we don't support
 | 
				
			||||||
		 * yet. So clear the DMA boundary bits.
 | 
							 * yet. So clear the DMA boundary bits.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
 | 
							ret &= (~SDHCI_MAKE_BLKSZ(0x7, 0));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sdhci_be32bs_writew(host, val, reg);
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 | 
					static u32 esdhc_writeb_fixup(struct sdhci_host *host,
 | 
				
			||||||
 | 
									     int spec_reg, u8 value, u32 old_value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
						u32 dma_bits;
 | 
				
			||||||
 | 
						u8 tmp;
 | 
				
			||||||
 | 
						int shift = (spec_reg & 0x3) * 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * "DMA select" location is offset 0x28 in SD specification, but on
 | 
						 * "DMA select" location is offset 0x28 in SD specification, but on
 | 
				
			||||||
	 * P5020 or P3041, it's located at 0x29.
 | 
						 * P5020 or P3041, it's located at 0x29.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (reg == SDHCI_HOST_CONTROL) {
 | 
						if (spec_reg == SDHCI_HOST_CONTROL) {
 | 
				
			||||||
		u32 dma_bits;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * If host control register is not standard, exit
 | 
							 * If host control register is not standard, exit
 | 
				
			||||||
		 * this function
 | 
							 * this function
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
 | 
							if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
 | 
				
			||||||
			return;
 | 
								return old_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* DMA select is 22,23 bits in Protocol Control Register */
 | 
							/* DMA select is 22,23 bits in Protocol Control Register */
 | 
				
			||||||
		dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
 | 
							dma_bits = (value & SDHCI_CTRL_DMA_MASK) << 5;
 | 
				
			||||||
		clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
 | 
							ret = (old_value & (~(SDHCI_CTRL_DMA_MASK << 5))) | dma_bits;
 | 
				
			||||||
			dma_bits);
 | 
							tmp = (value & (~SDHCI_CTRL_DMA_MASK)) |
 | 
				
			||||||
		val &= ~SDHCI_CTRL_DMA_MASK;
 | 
							      (old_value & SDHCI_CTRL_DMA_MASK);
 | 
				
			||||||
		val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK;
 | 
							ret = (ret & (~0xff)) | tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Prevent SDHCI core from writing reserved bits (e.g. HISPD) */
 | 
				
			||||||
 | 
							ret &= ~ESDHC_HOST_CONTROL_RES;
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
 | 
						ret = (old_value & (~(0xff << shift))) | (value << shift);
 | 
				
			||||||
	if (reg == SDHCI_HOST_CONTROL)
 | 
						return ret;
 | 
				
			||||||
		val &= ~ESDHC_HOST_CONTROL_RES;
 | 
					}
 | 
				
			||||||
	sdhci_be32bs_writeb(host, val, reg);
 | 
					
 | 
				
			||||||
 | 
					static u32 esdhc_be_readl(struct sdhci_host *host, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32be(host->ioaddr + reg);
 | 
				
			||||||
 | 
						ret = esdhc_readl_fixup(host, reg, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u32 esdhc_le_readl(struct sdhci_host *host, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32(host->ioaddr + reg);
 | 
				
			||||||
 | 
						ret = esdhc_readl_fixup(host, reg, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u16 esdhc_be_readw(struct sdhci_host *host, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 ret;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32be(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_readw_fixup(host, reg, value);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u16 esdhc_le_readw(struct sdhci_host *host, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 ret;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_readw_fixup(host, reg, value);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u8 esdhc_be_readb(struct sdhci_host *host, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 ret;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32be(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_readb_fixup(host, reg, value);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u8 esdhc_le_readb(struct sdhci_host *host, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 ret;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_readb_fixup(host, reg, value);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_be_writel(struct sdhci_host *host, u32 val, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = esdhc_writel_fixup(host, reg, val, 0);
 | 
				
			||||||
 | 
						iowrite32be(value, host->ioaddr + reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_le_writel(struct sdhci_host *host, u32 val, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = esdhc_writel_fixup(host, reg, val, 0);
 | 
				
			||||||
 | 
						iowrite32(value, host->ioaddr + reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32be(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_writew_fixup(host, reg, val, value);
 | 
				
			||||||
 | 
						if (reg != SDHCI_TRANSFER_MODE)
 | 
				
			||||||
 | 
							iowrite32be(ret, host->ioaddr + base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_writew_fixup(host, reg, val, value);
 | 
				
			||||||
 | 
						if (reg != SDHCI_TRANSFER_MODE)
 | 
				
			||||||
 | 
							iowrite32(ret, host->ioaddr + base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32be(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_writeb_fixup(host, reg, val, value);
 | 
				
			||||||
 | 
						iowrite32be(ret, host->ioaddr + base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_le_writeb(struct sdhci_host *host, u8 val, int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int base = reg & ~0x3;
 | 
				
			||||||
 | 
						u32 value;
 | 
				
			||||||
 | 
						u32 ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = ioread32(host->ioaddr + base);
 | 
				
			||||||
 | 
						ret = esdhc_writeb_fixup(host, reg, val, value);
 | 
				
			||||||
 | 
						iowrite32(ret, host->ioaddr + base);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -149,19 +345,17 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 | 
				
			||||||
 * For Continue, apply soft reset for data(SYSCTL[RSTD]);
 | 
					 * For Continue, apply soft reset for data(SYSCTL[RSTD]);
 | 
				
			||||||
 * and re-issue the entire read transaction from beginning.
 | 
					 * and re-issue the entire read transaction from beginning.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
 | 
					static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 tmp;
 | 
						struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 | 
				
			||||||
 | 
						struct sdhci_esdhc *esdhc = pltfm_host->priv;
 | 
				
			||||||
	bool applicable;
 | 
						bool applicable;
 | 
				
			||||||
	dma_addr_t dmastart;
 | 
						dma_addr_t dmastart;
 | 
				
			||||||
	dma_addr_t dmanow;
 | 
						dma_addr_t dmanow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
 | 
					 | 
				
			||||||
	tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	applicable = (intmask & SDHCI_INT_DATA_END) &&
 | 
						applicable = (intmask & SDHCI_INT_DATA_END) &&
 | 
				
			||||||
		     (intmask & SDHCI_INT_BLK_GAP) &&
 | 
							     (intmask & SDHCI_INT_BLK_GAP) &&
 | 
				
			||||||
		(tmp == VENDOR_V_23);
 | 
							     (esdhc->vendor_ver == VENDOR_V_23);
 | 
				
			||||||
	if (!applicable)
 | 
						if (!applicable)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,7 +373,11 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int esdhc_of_enable_dma(struct sdhci_host *host)
 | 
					static int esdhc_of_enable_dma(struct sdhci_host *host)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
 | 
						u32 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = sdhci_readl(host, ESDHC_DMA_SYSCTL);
 | 
				
			||||||
 | 
						value |= ESDHC_DMA_SNOOP;
 | 
				
			||||||
 | 
						sdhci_writel(host, value, ESDHC_DMA_SYSCTL);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,6 +397,8 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 | 
					static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 | 
				
			||||||
 | 
						struct sdhci_esdhc *esdhc = pltfm_host->priv;
 | 
				
			||||||
	int pre_div = 1;
 | 
						int pre_div = 1;
 | 
				
			||||||
	int div = 1;
 | 
						int div = 1;
 | 
				
			||||||
	u32 temp;
 | 
						u32 temp;
 | 
				
			||||||
| 
						 | 
					@ -209,9 +409,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
 | 
						/* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
 | 
				
			||||||
	temp = esdhc_readw(host, SDHCI_HOST_VERSION);
 | 
						if (esdhc->vendor_ver < VENDOR_V_23)
 | 
				
			||||||
	temp = (temp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
 | 
					 | 
				
			||||||
	if (temp < VENDOR_V_23)
 | 
					 | 
				
			||||||
		pre_div = 2;
 | 
							pre_div = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Workaround to reduce the clock frequency for p1010 esdhc */
 | 
						/* Workaround to reduce the clock frequency for p1010 esdhc */
 | 
				
			||||||
| 
						 | 
					@ -247,39 +445,26 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 | 
				
			||||||
	mdelay(1);
 | 
						mdelay(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void esdhc_of_platform_init(struct sdhci_host *host)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 vvn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
 | 
					 | 
				
			||||||
	vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
 | 
					 | 
				
			||||||
	if (vvn == VENDOR_V_22)
 | 
					 | 
				
			||||||
		host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (vvn > VENDOR_V_22)
 | 
					 | 
				
			||||||
		host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 | 
					static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 ctrl;
 | 
						u32 ctrl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctrl = sdhci_readl(host, ESDHC_PROCTL);
 | 
				
			||||||
 | 
						ctrl &= (~ESDHC_CTRL_BUSWIDTH_MASK);
 | 
				
			||||||
	switch (width) {
 | 
						switch (width) {
 | 
				
			||||||
	case MMC_BUS_WIDTH_8:
 | 
						case MMC_BUS_WIDTH_8:
 | 
				
			||||||
		ctrl = ESDHC_CTRL_8BITBUS;
 | 
							ctrl |= ESDHC_CTRL_8BITBUS;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case MMC_BUS_WIDTH_4:
 | 
						case MMC_BUS_WIDTH_4:
 | 
				
			||||||
		ctrl = ESDHC_CTRL_4BITBUS;
 | 
							ctrl |= ESDHC_CTRL_4BITBUS;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ctrl = 0;
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
 | 
						sdhci_writel(host, ctrl, ESDHC_PROCTL);
 | 
				
			||||||
			ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void esdhc_reset(struct sdhci_host *host, u8 mask)
 | 
					static void esdhc_reset(struct sdhci_host *host, u8 mask)
 | 
				
			||||||
| 
						 | 
					@ -290,32 +475,13 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
 | 
				
			||||||
	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 | 
						sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct sdhci_ops sdhci_esdhc_ops = {
 | 
					 | 
				
			||||||
	.read_l = esdhc_readl,
 | 
					 | 
				
			||||||
	.read_w = esdhc_readw,
 | 
					 | 
				
			||||||
	.read_b = esdhc_readb,
 | 
					 | 
				
			||||||
	.write_l = esdhc_writel,
 | 
					 | 
				
			||||||
	.write_w = esdhc_writew,
 | 
					 | 
				
			||||||
	.write_b = esdhc_writeb,
 | 
					 | 
				
			||||||
	.set_clock = esdhc_of_set_clock,
 | 
					 | 
				
			||||||
	.enable_dma = esdhc_of_enable_dma,
 | 
					 | 
				
			||||||
	.get_max_clock = esdhc_of_get_max_clock,
 | 
					 | 
				
			||||||
	.get_min_clock = esdhc_of_get_min_clock,
 | 
					 | 
				
			||||||
	.platform_init = esdhc_of_platform_init,
 | 
					 | 
				
			||||||
	.adma_workaround = esdhci_of_adma_workaround,
 | 
					 | 
				
			||||||
	.set_bus_width = esdhc_pltfm_set_bus_width,
 | 
					 | 
				
			||||||
	.reset = esdhc_reset,
 | 
					 | 
				
			||||||
	.set_uhs_signaling = sdhci_set_uhs_signaling,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_PM
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					 | 
				
			||||||
static u32 esdhc_proctl;
 | 
					static u32 esdhc_proctl;
 | 
				
			||||||
static int esdhc_of_suspend(struct device *dev)
 | 
					static int esdhc_of_suspend(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sdhci_host *host = dev_get_drvdata(dev);
 | 
						struct sdhci_host *host = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
 | 
						esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sdhci_suspend_host(host);
 | 
						return sdhci_suspend_host(host);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -328,9 +494,8 @@ static int esdhc_of_resume(struct device *dev)
 | 
				
			||||||
	if (ret == 0) {
 | 
						if (ret == 0) {
 | 
				
			||||||
		/* Isn't this already done by sdhci_resume_host() ? --rmk */
 | 
							/* Isn't this already done by sdhci_resume_host() ? --rmk */
 | 
				
			||||||
		esdhc_of_enable_dma(host);
 | 
							esdhc_of_enable_dma(host);
 | 
				
			||||||
		sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
 | 
							sdhci_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -343,30 +508,92 @@ static const struct dev_pm_ops esdhc_pmops = {
 | 
				
			||||||
#define ESDHC_PMOPS NULL
 | 
					#define ESDHC_PMOPS NULL
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
 | 
					static const struct sdhci_ops sdhci_esdhc_be_ops = {
 | 
				
			||||||
	/*
 | 
						.read_l = esdhc_be_readl,
 | 
				
			||||||
	 * card detection could be handled via GPIO
 | 
						.read_w = esdhc_be_readw,
 | 
				
			||||||
	 * eSDHC cannot support End Attribute in NOP ADMA descriptor
 | 
						.read_b = esdhc_be_readb,
 | 
				
			||||||
	 */
 | 
						.write_l = esdhc_be_writel,
 | 
				
			||||||
 | 
						.write_w = esdhc_be_writew,
 | 
				
			||||||
 | 
						.write_b = esdhc_be_writeb,
 | 
				
			||||||
 | 
						.set_clock = esdhc_of_set_clock,
 | 
				
			||||||
 | 
						.enable_dma = esdhc_of_enable_dma,
 | 
				
			||||||
 | 
						.get_max_clock = esdhc_of_get_max_clock,
 | 
				
			||||||
 | 
						.get_min_clock = esdhc_of_get_min_clock,
 | 
				
			||||||
 | 
						.adma_workaround = esdhc_of_adma_workaround,
 | 
				
			||||||
 | 
						.set_bus_width = esdhc_pltfm_set_bus_width,
 | 
				
			||||||
 | 
						.reset = esdhc_reset,
 | 
				
			||||||
 | 
						.set_uhs_signaling = sdhci_set_uhs_signaling,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sdhci_ops sdhci_esdhc_le_ops = {
 | 
				
			||||||
 | 
						.read_l = esdhc_le_readl,
 | 
				
			||||||
 | 
						.read_w = esdhc_le_readw,
 | 
				
			||||||
 | 
						.read_b = esdhc_le_readb,
 | 
				
			||||||
 | 
						.write_l = esdhc_le_writel,
 | 
				
			||||||
 | 
						.write_w = esdhc_le_writew,
 | 
				
			||||||
 | 
						.write_b = esdhc_le_writeb,
 | 
				
			||||||
 | 
						.set_clock = esdhc_of_set_clock,
 | 
				
			||||||
 | 
						.enable_dma = esdhc_of_enable_dma,
 | 
				
			||||||
 | 
						.get_max_clock = esdhc_of_get_max_clock,
 | 
				
			||||||
 | 
						.get_min_clock = esdhc_of_get_min_clock,
 | 
				
			||||||
 | 
						.adma_workaround = esdhc_of_adma_workaround,
 | 
				
			||||||
 | 
						.set_bus_width = esdhc_pltfm_set_bus_width,
 | 
				
			||||||
 | 
						.reset = esdhc_reset,
 | 
				
			||||||
 | 
						.set_uhs_signaling = sdhci_set_uhs_signaling,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = {
 | 
				
			||||||
	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
 | 
						.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
 | 
				
			||||||
		| SDHCI_QUIRK_NO_CARD_NO_RESET
 | 
							| SDHCI_QUIRK_NO_CARD_NO_RESET
 | 
				
			||||||
		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 | 
							| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 | 
				
			||||||
	.ops = &sdhci_esdhc_ops,
 | 
						.ops = &sdhci_esdhc_be_ops,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = {
 | 
				
			||||||
 | 
						.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
 | 
				
			||||||
 | 
							| SDHCI_QUIRK_NO_CARD_NO_RESET
 | 
				
			||||||
 | 
							| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 | 
				
			||||||
 | 
						.ops = &sdhci_esdhc_le_ops,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sdhci_pltfm_host *pltfm_host;
 | 
				
			||||||
 | 
						struct sdhci_esdhc *esdhc;
 | 
				
			||||||
 | 
						u16 host_ver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pltfm_host = sdhci_priv(host);
 | 
				
			||||||
 | 
						esdhc = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_esdhc),
 | 
				
			||||||
 | 
								     GFP_KERNEL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						host_ver = sdhci_readw(host, SDHCI_HOST_VERSION);
 | 
				
			||||||
 | 
						esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
 | 
				
			||||||
 | 
								     SDHCI_VENDOR_VER_SHIFT;
 | 
				
			||||||
 | 
						esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pltfm_host->priv = esdhc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sdhci_esdhc_probe(struct platform_device *pdev)
 | 
					static int sdhci_esdhc_probe(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sdhci_host *host;
 | 
						struct sdhci_host *host;
 | 
				
			||||||
	struct device_node *np;
 | 
						struct device_node *np;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0);
 | 
						np = pdev->dev.of_node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (of_get_property(np, "little-endian", NULL))
 | 
				
			||||||
 | 
							host = sdhci_pltfm_init(pdev, &sdhci_esdhc_le_pdata, 0);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							host = sdhci_pltfm_init(pdev, &sdhci_esdhc_be_pdata, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (IS_ERR(host))
 | 
						if (IS_ERR(host))
 | 
				
			||||||
		return PTR_ERR(host);
 | 
							return PTR_ERR(host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						esdhc_init(pdev, host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdhci_get_of_property(pdev);
 | 
						sdhci_get_of_property(pdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	np = pdev->dev.of_node;
 | 
					 | 
				
			||||||
	if (of_device_is_compatible(np, "fsl,p5040-esdhc") ||
 | 
						if (of_device_is_compatible(np, "fsl,p5040-esdhc") ||
 | 
				
			||||||
	    of_device_is_compatible(np, "fsl,p5020-esdhc") ||
 | 
						    of_device_is_compatible(np, "fsl,p5020-esdhc") ||
 | 
				
			||||||
	    of_device_is_compatible(np, "fsl,p4080-esdhc") ||
 | 
						    of_device_is_compatible(np, "fsl,p4080-esdhc") ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue