Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

authored by

yangbo lu and committed by
Ulf Hansson
f4932cfd e38eeca5

+344 -115
+2
drivers/mmc/host/sdhci-esdhc.h
··· 24 24 SDHCI_QUIRK_PIO_NEEDS_DELAY | \ 25 25 SDHCI_QUIRK_NO_HISPD_BIT) 26 26 27 + #define ESDHC_PROCTL 0x28 28 + 27 29 #define ESDHC_SYSTEM_CONTROL 0x2c 28 30 #define ESDHC_CLOCK_MASK 0x0000fff0 29 31 #define ESDHC_PREDIV_SHIFT 8
+342 -115
drivers/mmc/host/sdhci-of-esdhc.c
··· 24 24 25 25 #define VENDOR_V_22 0x12 26 26 #define VENDOR_V_23 0x13 27 - static u32 esdhc_readl(struct sdhci_host *host, int reg) 27 + 28 + struct sdhci_esdhc { 29 + u8 vendor_ver; 30 + u8 spec_ver; 31 + }; 32 + 33 + /** 34 + * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register 35 + * to make it compatible with SD spec. 36 + * 37 + * @host: pointer to sdhci_host 38 + * @spec_reg: SD spec register address 39 + * @value: 32bit eSDHC register value on spec_reg address 40 + * 41 + * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC 42 + * registers are 32 bits. There are differences in register size, register 43 + * address, register function, bit position and function between eSDHC spec 44 + * and SD spec. 45 + * 46 + * Return a fixed up register value 47 + */ 48 + static u32 esdhc_readl_fixup(struct sdhci_host *host, 49 + int spec_reg, u32 value) 28 50 { 51 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 52 + struct sdhci_esdhc *esdhc = pltfm_host->priv; 29 53 u32 ret; 30 54 31 - ret = in_be32(host->ioaddr + reg); 32 55 /* 33 56 * The bit of ADMA flag in eSDHC is not compatible with standard 34 57 * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is 35 58 * supported by eSDHC. 36 59 * And for many FSL eSDHC controller, the reset value of field 37 - * SDHCI_CAN_DO_ADMA1 is one, but some of them can't support ADMA, 60 + * SDHCI_CAN_DO_ADMA1 is 1, but some of them can't support ADMA, 38 61 * only these vendor version is greater than 2.2/0x12 support ADMA. 39 - * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the 40 - * the verdor version number, oxFE is SDHCI_HOST_VERSION. 41 62 */ 42 - if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) { 43 - u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); 44 - tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; 45 - if (tmp > VENDOR_V_22) 46 - ret |= SDHCI_CAN_DO_ADMA2; 63 + if ((spec_reg == SDHCI_CAPABILITIES) && (value & SDHCI_CAN_DO_ADMA1)) { 64 + if (esdhc->vendor_ver > VENDOR_V_22) { 65 + ret = value | SDHCI_CAN_DO_ADMA2; 66 + return ret; 67 + } 47 68 } 48 - 69 + ret = value; 49 70 return ret; 50 71 } 51 72 52 - static u16 esdhc_readw(struct sdhci_host *host, int reg) 73 + static u16 esdhc_readw_fixup(struct sdhci_host *host, 74 + int spec_reg, u32 value) 53 75 { 54 76 u16 ret; 55 - int base = reg & ~0x3; 56 - int shift = (reg & 0x2) * 8; 77 + int shift = (spec_reg & 0x2) * 8; 57 78 58 - if (unlikely(reg == SDHCI_HOST_VERSION)) 59 - ret = in_be32(host->ioaddr + base) & 0xffff; 79 + if (spec_reg == SDHCI_HOST_VERSION) 80 + ret = value & 0xffff; 60 81 else 61 - ret = (in_be32(host->ioaddr + base) >> shift) & 0xffff; 82 + ret = (value >> shift) & 0xffff; 62 83 return ret; 63 84 } 64 85 65 - static u8 esdhc_readb(struct sdhci_host *host, int reg) 86 + static u8 esdhc_readb_fixup(struct sdhci_host *host, 87 + int spec_reg, u32 value) 66 88 { 67 - int base = reg & ~0x3; 68 - int shift = (reg & 0x3) * 8; 69 - u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff; 89 + u8 ret; 90 + u8 dma_bits; 91 + int shift = (spec_reg & 0x3) * 8; 92 + 93 + ret = (value >> shift) & 0xff; 70 94 71 95 /* 72 96 * "DMA select" locates at offset 0x28 in SD specification, but on 73 97 * P5020 or P3041, it locates at 0x29. 74 98 */ 75 - if (reg == SDHCI_HOST_CONTROL) { 76 - u32 dma_bits; 77 - 78 - dma_bits = in_be32(host->ioaddr + reg); 99 + if (spec_reg == SDHCI_HOST_CONTROL) { 79 100 /* DMA select is 22,23 bits in Protocol Control Register */ 80 - dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK; 81 - 101 + dma_bits = (value >> 5) & SDHCI_CTRL_DMA_MASK; 82 102 /* fixup the result */ 83 103 ret &= ~SDHCI_CTRL_DMA_MASK; 84 104 ret |= dma_bits; 85 105 } 106 + return ret; 107 + } 108 + 109 + /** 110 + * esdhc_write*_fixup - Fixup the SD spec register value so that it could be 111 + * written into eSDHC register. 112 + * 113 + * @host: pointer to sdhci_host 114 + * @spec_reg: SD spec register address 115 + * @value: 8/16/32bit SD spec register value that would be written 116 + * @old_value: 32bit eSDHC register value on spec_reg address 117 + * 118 + * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC 119 + * registers are 32 bits. There are differences in register size, register 120 + * address, register function, bit position and function between eSDHC spec 121 + * and SD spec. 122 + * 123 + * Return a fixed up register value 124 + */ 125 + static u32 esdhc_writel_fixup(struct sdhci_host *host, 126 + int spec_reg, u32 value, u32 old_value) 127 + { 128 + u32 ret; 129 + 130 + /* 131 + * Enabling IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE] 132 + * when SYSCTL[RSTD] is set for some special operations. 133 + * No any impact on other operation. 134 + */ 135 + if (spec_reg == SDHCI_INT_ENABLE) 136 + ret = value | SDHCI_INT_BLK_GAP; 137 + else 138 + ret = value; 86 139 87 140 return ret; 88 141 } 89 142 90 - static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) 143 + static u32 esdhc_writew_fixup(struct sdhci_host *host, 144 + int spec_reg, u16 value, u32 old_value) 91 145 { 92 - /* 93 - * Enable IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE] 94 - * when SYSCTL[RSTD]) is set for some special operations. 95 - * No any impact other operation. 96 - */ 97 - if (reg == SDHCI_INT_ENABLE) 98 - val |= SDHCI_INT_BLK_GAP; 99 - sdhci_be32bs_writel(host, val, reg); 100 - } 146 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 147 + int shift = (spec_reg & 0x2) * 8; 148 + u32 ret; 101 149 102 - static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) 103 - { 104 - if (reg == SDHCI_BLOCK_SIZE) { 150 + switch (spec_reg) { 151 + case SDHCI_TRANSFER_MODE: 152 + /* 153 + * Postpone this write, we must do it together with a 154 + * command write that is down below. Return old value. 155 + */ 156 + pltfm_host->xfer_mode_shadow = value; 157 + return old_value; 158 + case SDHCI_COMMAND: 159 + ret = (value << 16) | pltfm_host->xfer_mode_shadow; 160 + return ret; 161 + } 162 + 163 + ret = old_value & (~(0xffff << shift)); 164 + ret |= (value << shift); 165 + 166 + if (spec_reg == SDHCI_BLOCK_SIZE) { 105 167 /* 106 168 * Two last DMA bits are reserved, and first one is used for 107 169 * non-standard blksz of 4096 bytes that we don't support 108 170 * yet. So clear the DMA boundary bits. 109 171 */ 110 - val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); 172 + ret &= (~SDHCI_MAKE_BLKSZ(0x7, 0)); 111 173 } 112 - sdhci_be32bs_writew(host, val, reg); 174 + return ret; 113 175 } 114 176 115 - static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) 177 + static u32 esdhc_writeb_fixup(struct sdhci_host *host, 178 + int spec_reg, u8 value, u32 old_value) 116 179 { 180 + u32 ret; 181 + u32 dma_bits; 182 + u8 tmp; 183 + int shift = (spec_reg & 0x3) * 8; 184 + 117 185 /* 118 186 * "DMA select" location is offset 0x28 in SD specification, but on 119 187 * P5020 or P3041, it's located at 0x29. 120 188 */ 121 - if (reg == SDHCI_HOST_CONTROL) { 122 - u32 dma_bits; 123 - 189 + if (spec_reg == SDHCI_HOST_CONTROL) { 124 190 /* 125 191 * If host control register is not standard, exit 126 192 * this function 127 193 */ 128 194 if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL) 129 - return; 195 + return old_value; 130 196 131 197 /* DMA select is 22,23 bits in Protocol Control Register */ 132 - dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5; 133 - clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5, 134 - dma_bits); 135 - val &= ~SDHCI_CTRL_DMA_MASK; 136 - val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK; 198 + dma_bits = (value & SDHCI_CTRL_DMA_MASK) << 5; 199 + ret = (old_value & (~(SDHCI_CTRL_DMA_MASK << 5))) | dma_bits; 200 + tmp = (value & (~SDHCI_CTRL_DMA_MASK)) | 201 + (old_value & SDHCI_CTRL_DMA_MASK); 202 + ret = (ret & (~0xff)) | tmp; 203 + 204 + /* Prevent SDHCI core from writing reserved bits (e.g. HISPD) */ 205 + ret &= ~ESDHC_HOST_CONTROL_RES; 206 + return ret; 137 207 } 138 208 139 - /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ 140 - if (reg == SDHCI_HOST_CONTROL) 141 - val &= ~ESDHC_HOST_CONTROL_RES; 142 - sdhci_be32bs_writeb(host, val, reg); 209 + ret = (old_value & (~(0xff << shift))) | (value << shift); 210 + return ret; 211 + } 212 + 213 + static u32 esdhc_be_readl(struct sdhci_host *host, int reg) 214 + { 215 + u32 ret; 216 + u32 value; 217 + 218 + value = ioread32be(host->ioaddr + reg); 219 + ret = esdhc_readl_fixup(host, reg, value); 220 + 221 + return ret; 222 + } 223 + 224 + static u32 esdhc_le_readl(struct sdhci_host *host, int reg) 225 + { 226 + u32 ret; 227 + u32 value; 228 + 229 + value = ioread32(host->ioaddr + reg); 230 + ret = esdhc_readl_fixup(host, reg, value); 231 + 232 + return ret; 233 + } 234 + 235 + static u16 esdhc_be_readw(struct sdhci_host *host, int reg) 236 + { 237 + u16 ret; 238 + u32 value; 239 + int base = reg & ~0x3; 240 + 241 + value = ioread32be(host->ioaddr + base); 242 + ret = esdhc_readw_fixup(host, reg, value); 243 + return ret; 244 + } 245 + 246 + static u16 esdhc_le_readw(struct sdhci_host *host, int reg) 247 + { 248 + u16 ret; 249 + u32 value; 250 + int base = reg & ~0x3; 251 + 252 + value = ioread32(host->ioaddr + base); 253 + ret = esdhc_readw_fixup(host, reg, value); 254 + return ret; 255 + } 256 + 257 + static u8 esdhc_be_readb(struct sdhci_host *host, int reg) 258 + { 259 + u8 ret; 260 + u32 value; 261 + int base = reg & ~0x3; 262 + 263 + value = ioread32be(host->ioaddr + base); 264 + ret = esdhc_readb_fixup(host, reg, value); 265 + return ret; 266 + } 267 + 268 + static u8 esdhc_le_readb(struct sdhci_host *host, int reg) 269 + { 270 + u8 ret; 271 + u32 value; 272 + int base = reg & ~0x3; 273 + 274 + value = ioread32(host->ioaddr + base); 275 + ret = esdhc_readb_fixup(host, reg, value); 276 + return ret; 277 + } 278 + 279 + static void esdhc_be_writel(struct sdhci_host *host, u32 val, int reg) 280 + { 281 + u32 value; 282 + 283 + value = esdhc_writel_fixup(host, reg, val, 0); 284 + iowrite32be(value, host->ioaddr + reg); 285 + } 286 + 287 + static void esdhc_le_writel(struct sdhci_host *host, u32 val, int reg) 288 + { 289 + u32 value; 290 + 291 + value = esdhc_writel_fixup(host, reg, val, 0); 292 + iowrite32(value, host->ioaddr + reg); 293 + } 294 + 295 + static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg) 296 + { 297 + int base = reg & ~0x3; 298 + u32 value; 299 + u32 ret; 300 + 301 + value = ioread32be(host->ioaddr + base); 302 + ret = esdhc_writew_fixup(host, reg, val, value); 303 + if (reg != SDHCI_TRANSFER_MODE) 304 + iowrite32be(ret, host->ioaddr + base); 305 + } 306 + 307 + static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg) 308 + { 309 + int base = reg & ~0x3; 310 + u32 value; 311 + u32 ret; 312 + 313 + value = ioread32(host->ioaddr + base); 314 + ret = esdhc_writew_fixup(host, reg, val, value); 315 + if (reg != SDHCI_TRANSFER_MODE) 316 + iowrite32(ret, host->ioaddr + base); 317 + } 318 + 319 + static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg) 320 + { 321 + int base = reg & ~0x3; 322 + u32 value; 323 + u32 ret; 324 + 325 + value = ioread32be(host->ioaddr + base); 326 + ret = esdhc_writeb_fixup(host, reg, val, value); 327 + iowrite32be(ret, host->ioaddr + base); 328 + } 329 + 330 + static void esdhc_le_writeb(struct sdhci_host *host, u8 val, int reg) 331 + { 332 + int base = reg & ~0x3; 333 + u32 value; 334 + u32 ret; 335 + 336 + value = ioread32(host->ioaddr + base); 337 + ret = esdhc_writeb_fixup(host, reg, val, value); 338 + iowrite32(ret, host->ioaddr + base); 143 339 } 144 340 145 341 /* ··· 345 149 * For Continue, apply soft reset for data(SYSCTL[RSTD]); 346 150 * and re-issue the entire read transaction from beginning. 347 151 */ 348 - static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) 152 + static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask) 349 153 { 350 - u32 tmp; 154 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 155 + struct sdhci_esdhc *esdhc = pltfm_host->priv; 351 156 bool applicable; 352 157 dma_addr_t dmastart; 353 158 dma_addr_t dmanow; 354 159 355 - tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); 356 - tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; 357 - 358 160 applicable = (intmask & SDHCI_INT_DATA_END) && 359 - (intmask & SDHCI_INT_BLK_GAP) && 360 - (tmp == VENDOR_V_23); 161 + (intmask & SDHCI_INT_BLK_GAP) && 162 + (esdhc->vendor_ver == VENDOR_V_23); 361 163 if (!applicable) 362 164 return; 363 165 ··· 373 179 374 180 static int esdhc_of_enable_dma(struct sdhci_host *host) 375 181 { 376 - setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); 182 + u32 value; 183 + 184 + value = sdhci_readl(host, ESDHC_DMA_SYSCTL); 185 + value |= ESDHC_DMA_SNOOP; 186 + sdhci_writel(host, value, ESDHC_DMA_SYSCTL); 377 187 return 0; 378 188 } 379 189 ··· 397 199 398 200 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) 399 201 { 202 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 203 + struct sdhci_esdhc *esdhc = pltfm_host->priv; 400 204 int pre_div = 1; 401 205 int div = 1; 402 206 u32 temp; ··· 409 209 return; 410 210 411 211 /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */ 412 - temp = esdhc_readw(host, SDHCI_HOST_VERSION); 413 - temp = (temp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; 414 - if (temp < VENDOR_V_23) 212 + if (esdhc->vendor_ver < VENDOR_V_23) 415 213 pre_div = 2; 416 214 417 215 /* Workaround to reduce the clock frequency for p1010 esdhc */ ··· 445 247 mdelay(1); 446 248 } 447 249 448 - static void esdhc_of_platform_init(struct sdhci_host *host) 449 - { 450 - u32 vvn; 451 - 452 - vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); 453 - vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; 454 - if (vvn == VENDOR_V_22) 455 - host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; 456 - 457 - if (vvn > VENDOR_V_22) 458 - host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; 459 - } 460 - 461 250 static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) 462 251 { 463 252 u32 ctrl; 464 253 254 + ctrl = sdhci_readl(host, ESDHC_PROCTL); 255 + ctrl &= (~ESDHC_CTRL_BUSWIDTH_MASK); 465 256 switch (width) { 466 257 case MMC_BUS_WIDTH_8: 467 - ctrl = ESDHC_CTRL_8BITBUS; 258 + ctrl |= ESDHC_CTRL_8BITBUS; 468 259 break; 469 260 470 261 case MMC_BUS_WIDTH_4: 471 - ctrl = ESDHC_CTRL_4BITBUS; 262 + ctrl |= ESDHC_CTRL_4BITBUS; 472 263 break; 473 264 474 265 default: 475 - ctrl = 0; 476 266 break; 477 267 } 478 268 479 - clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL, 480 - ESDHC_CTRL_BUSWIDTH_MASK, ctrl); 269 + sdhci_writel(host, ctrl, ESDHC_PROCTL); 481 270 } 482 271 483 272 static void esdhc_reset(struct sdhci_host *host, u8 mask) ··· 475 290 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 476 291 } 477 292 478 - static const struct sdhci_ops sdhci_esdhc_ops = { 479 - .read_l = esdhc_readl, 480 - .read_w = esdhc_readw, 481 - .read_b = esdhc_readb, 482 - .write_l = esdhc_writel, 483 - .write_w = esdhc_writew, 484 - .write_b = esdhc_writeb, 485 - .set_clock = esdhc_of_set_clock, 486 - .enable_dma = esdhc_of_enable_dma, 487 - .get_max_clock = esdhc_of_get_max_clock, 488 - .get_min_clock = esdhc_of_get_min_clock, 489 - .platform_init = esdhc_of_platform_init, 490 - .adma_workaround = esdhci_of_adma_workaround, 491 - .set_bus_width = esdhc_pltfm_set_bus_width, 492 - .reset = esdhc_reset, 493 - .set_uhs_signaling = sdhci_set_uhs_signaling, 494 - }; 495 - 496 293 #ifdef CONFIG_PM 497 - 498 294 static u32 esdhc_proctl; 499 295 static int esdhc_of_suspend(struct device *dev) 500 296 { 501 297 struct sdhci_host *host = dev_get_drvdata(dev); 502 298 503 - esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL); 299 + esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL); 504 300 505 301 return sdhci_suspend_host(host); 506 302 } ··· 494 328 if (ret == 0) { 495 329 /* Isn't this already done by sdhci_resume_host() ? --rmk */ 496 330 esdhc_of_enable_dma(host); 497 - sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); 331 + sdhci_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); 498 332 } 499 - 500 333 return ret; 501 334 } 502 335 ··· 508 343 #define ESDHC_PMOPS NULL 509 344 #endif 510 345 511 - static const struct sdhci_pltfm_data sdhci_esdhc_pdata = { 512 - /* 513 - * card detection could be handled via GPIO 514 - * eSDHC cannot support End Attribute in NOP ADMA descriptor 515 - */ 346 + static const struct sdhci_ops sdhci_esdhc_be_ops = { 347 + .read_l = esdhc_be_readl, 348 + .read_w = esdhc_be_readw, 349 + .read_b = esdhc_be_readb, 350 + .write_l = esdhc_be_writel, 351 + .write_w = esdhc_be_writew, 352 + .write_b = esdhc_be_writeb, 353 + .set_clock = esdhc_of_set_clock, 354 + .enable_dma = esdhc_of_enable_dma, 355 + .get_max_clock = esdhc_of_get_max_clock, 356 + .get_min_clock = esdhc_of_get_min_clock, 357 + .adma_workaround = esdhc_of_adma_workaround, 358 + .set_bus_width = esdhc_pltfm_set_bus_width, 359 + .reset = esdhc_reset, 360 + .set_uhs_signaling = sdhci_set_uhs_signaling, 361 + }; 362 + 363 + static const struct sdhci_ops sdhci_esdhc_le_ops = { 364 + .read_l = esdhc_le_readl, 365 + .read_w = esdhc_le_readw, 366 + .read_b = esdhc_le_readb, 367 + .write_l = esdhc_le_writel, 368 + .write_w = esdhc_le_writew, 369 + .write_b = esdhc_le_writeb, 370 + .set_clock = esdhc_of_set_clock, 371 + .enable_dma = esdhc_of_enable_dma, 372 + .get_max_clock = esdhc_of_get_max_clock, 373 + .get_min_clock = esdhc_of_get_min_clock, 374 + .adma_workaround = esdhc_of_adma_workaround, 375 + .set_bus_width = esdhc_pltfm_set_bus_width, 376 + .reset = esdhc_reset, 377 + .set_uhs_signaling = sdhci_set_uhs_signaling, 378 + }; 379 + 380 + static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { 516 381 .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION 517 382 | SDHCI_QUIRK_NO_CARD_NO_RESET 518 383 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 519 - .ops = &sdhci_esdhc_ops, 384 + .ops = &sdhci_esdhc_be_ops, 520 385 }; 386 + 387 + static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { 388 + .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION 389 + | SDHCI_QUIRK_NO_CARD_NO_RESET 390 + | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 391 + .ops = &sdhci_esdhc_le_ops, 392 + }; 393 + 394 + static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) 395 + { 396 + struct sdhci_pltfm_host *pltfm_host; 397 + struct sdhci_esdhc *esdhc; 398 + u16 host_ver; 399 + 400 + pltfm_host = sdhci_priv(host); 401 + esdhc = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_esdhc), 402 + GFP_KERNEL); 403 + 404 + host_ver = sdhci_readw(host, SDHCI_HOST_VERSION); 405 + esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >> 406 + SDHCI_VENDOR_VER_SHIFT; 407 + esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK; 408 + 409 + pltfm_host->priv = esdhc; 410 + } 521 411 522 412 static int sdhci_esdhc_probe(struct platform_device *pdev) 523 413 { ··· 580 360 struct device_node *np; 581 361 int ret; 582 362 583 - host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0); 363 + np = pdev->dev.of_node; 364 + 365 + if (of_get_property(np, "little-endian", NULL)) 366 + host = sdhci_pltfm_init(pdev, &sdhci_esdhc_le_pdata, 0); 367 + else 368 + host = sdhci_pltfm_init(pdev, &sdhci_esdhc_be_pdata, 0); 369 + 584 370 if (IS_ERR(host)) 585 371 return PTR_ERR(host); 586 372 373 + esdhc_init(pdev, host); 374 + 587 375 sdhci_get_of_property(pdev); 588 376 589 - np = pdev->dev.of_node; 590 377 if (of_device_is_compatible(np, "fsl,p5040-esdhc") || 591 378 of_device_is_compatible(np, "fsl,p5020-esdhc") || 592 379 of_device_is_compatible(np, "fsl,p4080-esdhc") ||