diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index eb92b8107d2c37706a50da220cd411431a4a3883..df1311d93eba58e61d9e637405c173ee67d36127 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -303,6 +303,9 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) else mmc->slots[0].features |= HSMMC_HAS_PBIAS; + if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) + mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET; + switch (c->mmc) { case 1: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index 4f819fc261b721d71ca62220e8ae3d1a69a2491d..2c4629a8d9f2484640492e43dd189819a8a4bff9 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -103,6 +103,7 @@ struct omap_mmc_platform_data { /* we can put the features above into this variable */ #define HSMMC_HAS_PBIAS (1 << 0) +#define HSMMC_HAS_UPDATED_RESET (1 << 1) unsigned features; int switch_pin; /* gpio (card detect) */ diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 53f8fa599cf5fc8d686e75a9eae53d1a9a882d6e..69858e75020381325f5a75b3c26ade9e140b2836 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -982,6 +982,17 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | bit); + /* + * OMAP4 ES2 and greater has an updated reset logic. + * Monitor a 0->1 transition first + */ + if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { + while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit)) + && (i++ < limit)) + cpu_relax(); + } + i = 0; + while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) && (i++ < limit)) cpu_relax();