diff options
-rw-r--r-- | drivers/mmc/mmc-uclass.c | 14 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 15 | ||||
-rw-r--r-- | include/mmc.h | 13 |
3 files changed, 42 insertions, 0 deletions
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 37c3843902..c7a832ca90 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -122,6 +122,20 @@ int mmc_set_enhanced_strobe(struct mmc *mmc) } #endif +int dm_mmc_host_power_cycle(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->host_power_cycle) + return ops->host_power_cycle(dev); + return 0; +} + +int mmc_host_power_cycle(struct mmc *mmc) +{ + return dm_mmc_host_power_cycle(mmc->dev); +} + int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) { int val; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c2c85ba144..f683b52ead 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1546,6 +1546,16 @@ static int mmc_set_ios(struct mmc *mmc) return ret; } + +static int mmc_host_power_cycle(struct mmc *mmc) +{ + int ret = 0; + + if (mmc->cfg->ops->host_power_cycle) + ret = mmc->cfg->ops->host_power_cycle(mmc); + + return ret; +} #endif int mmc_set_clock(struct mmc *mmc, uint clock, bool disable) @@ -2715,6 +2725,11 @@ static int mmc_power_cycle(struct mmc *mmc) ret = mmc_power_off(mmc); if (ret) return ret; + + ret = mmc_host_power_cycle(mmc); + if (ret) + return ret; + /* * SD spec recommends at least 1ms of delay. Let's wait for 2ms * to be on the safer side. diff --git a/include/mmc.h b/include/mmc.h index 8c29c8d4ab..1a9efe4c38 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -466,6 +466,16 @@ struct dm_mmc_ops { /* set_enhanced_strobe() - set HS400 enhanced strobe */ int (*set_enhanced_strobe)(struct udevice *dev); #endif + + /** + * host_power_cycle - host specific tasks in power cycle sequence + * Called between mmc_power_off() and + * mmc_power_on() + * + * @dev: Device to check + * @return 0 if not present, 1 if present, -ve on error + */ + int (*host_power_cycle)(struct udevice *dev); }; #define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) @@ -477,6 +487,7 @@ int dm_mmc_get_cd(struct udevice *dev); int dm_mmc_get_wp(struct udevice *dev); int dm_mmc_execute_tuning(struct udevice *dev, uint opcode); int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us); +int dm_mmc_host_power_cycle(struct udevice *dev); /* Transition functions for compatibility */ int mmc_set_ios(struct mmc *mmc); @@ -485,6 +496,7 @@ int mmc_getwp(struct mmc *mmc); int mmc_execute_tuning(struct mmc *mmc, uint opcode); int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us); int mmc_set_enhanced_strobe(struct mmc *mmc); +int mmc_host_power_cycle(struct mmc *mmc); #else struct mmc_ops { @@ -494,6 +506,7 @@ struct mmc_ops { int (*init)(struct mmc *mmc); int (*getcd)(struct mmc *mmc); int (*getwp)(struct mmc *mmc); + int (*host_power_cycle)(struct mmc *mmc); }; #endif |