aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/core/core.c24
-rw-r--r--drivers/mmc/core/core.h1
-rw-r--r--include/linux/mmc/core.h1
3 files changed, 26 insertions, 0 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 3e17c62eea86..7a79dc1599e5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2451,6 +2451,30 @@ int mmc_hw_reset(struct mmc_host *host)
}
EXPORT_SYMBOL(mmc_hw_reset);
+int mmc_sw_reset(struct mmc_host *host)
+{
+ int ret;
+
+ if (!host->card)
+ return -EINVAL;
+
+ mmc_bus_get(host);
+ if (!host->bus_ops || host->bus_dead || !host->bus_ops->sw_reset) {
+ mmc_bus_put(host);
+ return -EOPNOTSUPP;
+ }
+
+ ret = host->bus_ops->sw_reset(host);
+ mmc_bus_put(host);
+
+ if (ret)
+ pr_warn("%s: tried to SW reset card, got error %d\n",
+ mmc_hostname(host), ret);
+
+ return ret;
+}
+EXPORT_SYMBOL(mmc_sw_reset);
+
static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
{
host->f_init = freq;
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 367ed1127be2..a141ec0e1ccc 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -33,6 +33,7 @@ struct mmc_bus_ops {
int (*alive)(struct mmc_host *);
int (*shutdown)(struct mmc_host *);
int (*hw_reset)(struct mmc_host *);
+ int (*sw_reset)(struct mmc_host *);
};
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 927519385482..134a6483347a 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -177,6 +177,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd,
int retries);
int mmc_hw_reset(struct mmc_host *host);
+int mmc_sw_reset(struct mmc_host *host);
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card);
#endif /* LINUX_MMC_CORE_H */