aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c780
1 files changed, 437 insertions, 343 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index aaed7687cf0..7dc0c85fdb6 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -23,15 +23,18 @@
#include <linux/log2.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_wakeup.h>
#include <linux/suspend.h>
#include <linux/fault-inject.h>
#include <linux/random.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
+#include <linux/mmc/slot-gpio.h>
#include "core.h"
#include "bus.h"
@@ -63,23 +66,6 @@ bool use_spi_crc = 1;
module_param(use_spi_crc, bool, 0);
/*
- * We normally treat cards as removed during suspend if they are not
- * known to be on a non-removable bus, to avoid the risk of writing
- * back data to a different card after resume. Allow this to be
- * overridden if necessary.
- */
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-bool mmc_assume_removable;
-#else
-bool mmc_assume_removable = 1;
-#endif
-EXPORT_SYMBOL(mmc_assume_removable);
-module_param_named(removable, mmc_assume_removable, bool, 0644);
-MODULE_PARM_DESC(
- removable,
- "MMC/SD cards are removable and may be removed during suspend");
-
-/*
* Internal function. Schedule delayed work in the MMC work queue.
*/
static int mmc_schedule_delayed_work(struct delayed_work *work,
@@ -120,8 +106,8 @@ static void mmc_should_fail_request(struct mmc_host *host,
!should_fail(&host->fail_mmc_request, data->blksz * data->blocks))
return;
- data->error = data_errors[random32() % ARRAY_SIZE(data_errors)];
- data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9;
+ data->error = data_errors[prandom_u32() % ARRAY_SIZE(data_errors)];
+ data->bytes_xfered = (prandom_u32() % (data->bytes_xfered >> 9)) << 9;
}
#else /* CONFIG_FAIL_MMC_REQUEST */
@@ -300,7 +286,8 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
}
err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
+ EXT_CSD_BKOPS_START, 1, timeout,
+ use_busy_signal, true, false);
if (err) {
pr_warn("%s: Error %d starting bkops\n",
mmc_hostname(card->host), err);
@@ -319,11 +306,45 @@ out:
}
EXPORT_SYMBOL(mmc_start_bkops);
+/*
+ * mmc_wait_data_done() - done callback for data request
+ * @mrq: done data request
+ *
+ * Wakes up mmc context, passed as a callback to host controller driver
+ */
+static void mmc_wait_data_done(struct mmc_request *mrq)
+{
+ mrq->host->context_info.is_done_rcv = true;
+ wake_up_interruptible(&mrq->host->context_info.wait);
+}
+
static void mmc_wait_done(struct mmc_request *mrq)
{
complete(&mrq->completion);
}
+/*
+ *__mmc_start_data_req() - starts data request
+ * @host: MMC host to start the request
+ * @mrq: data request to start
+ *
+ * Sets the done callback to be called when request is completed by the card.
+ * Starts data mmc request execution
+ */
+static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ mrq->done = mmc_wait_data_done;
+ mrq->host = host;
+ if (mmc_card_removed(host->card)) {
+ mrq->cmd->error = -ENOMEDIUM;
+ mmc_wait_data_done(mrq);
+ return -ENOMEDIUM;
+ }
+ mmc_start_request(host, mrq);
+
+ return 0;
+}
+
static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
{
init_completion(&mrq->completion);
@@ -337,6 +358,63 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
return 0;
}
+/*
+ * mmc_wait_for_data_req_done() - wait for request completed
+ * @host: MMC host to prepare the command.
+ * @mrq: MMC request to wait for
+ *
+ * Blocks MMC context till host controller will ack end of data request
+ * execution or new request notification arrives from the block layer.
+ * Handles command retries.
+ *
+ * Returns enum mmc_blk_status after checking errors.
+ */
+static int mmc_wait_for_data_req_done(struct mmc_host *host,
+ struct mmc_request *mrq,
+ struct mmc_async_req *next_req)
+{
+ struct mmc_command *cmd;
+ struct mmc_context_info *context_info = &host->context_info;
+ int err;
+ unsigned long flags;
+
+ while (1) {
+ wait_event_interruptible(context_info->wait,
+ (context_info->is_done_rcv ||
+ context_info->is_new_req));
+ spin_lock_irqsave(&context_info->lock, flags);
+ context_info->is_waiting_last_req = false;
+ spin_unlock_irqrestore(&context_info->lock, flags);
+ if (context_info->is_done_rcv) {
+ context_info->is_done_rcv = false;
+ context_info->is_new_req = false;
+ cmd = mrq->cmd;
+
+ if (!cmd->error || !cmd->retries ||
+ mmc_card_removed(host->card)) {
+ err = host->areq->err_check(host->card,
+ host->areq);
+ break; /* return err */
+ } else {
+ pr_info("%s: req failed (CMD%u): %d, retrying...\n",
+ mmc_hostname(host),
+ cmd->opcode, cmd->error);
+ cmd->retries--;
+ cmd->error = 0;
+ host->ops->request(host, mrq);
+ continue; /* wait for done/new event again */
+ }
+ } else if (context_info->is_new_req) {
+ context_info->is_new_req = false;
+ if (!next_req) {
+ err = MMC_BLK_NEW_REQUEST;
+ break; /* return err */
+ }
+ }
+ }
+ return err;
+}
+
static void mmc_wait_for_req_done(struct mmc_host *host,
struct mmc_request *mrq)
{
@@ -346,6 +424,24 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
wait_for_completion(&mrq->completion);
cmd = mrq->cmd;
+
+ /*
+ * If host has timed out waiting for the sanitize
+ * to complete, card might be still in programming state
+ * so let's try to bring the card out of programming
+ * state.
+ */
+ if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) {
+ if (!mmc_interrupt_hpi(host->card)) {
+ pr_warning("%s: %s: Interrupted sanitize\n",
+ mmc_hostname(host), __func__);
+ cmd->error = 0;
+ break;
+ } else {
+ pr_err("%s: %s: Failed to interrupt sanitize\n",
+ mmc_hostname(host), __func__);
+ }
+ }
if (!cmd->error || !cmd->retries ||
mmc_card_removed(host->card))
break;
@@ -426,8 +522,16 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
mmc_pre_req(host, areq->mrq, !host->areq);
if (host->areq) {
- mmc_wait_for_req_done(host, host->areq->mrq);
- err = host->areq->err_check(host->card, host->areq);
+ err = mmc_wait_for_data_req_done(host, host->areq->mrq, areq);
+ if (err == MMC_BLK_NEW_REQUEST) {
+ if (error)
+ *error = err;
+ /*
+ * The previous request was not completed,
+ * nothing to return
+ */
+ return NULL;
+ }
/*
* Check BKOPS urgency for each R1 response
*/
@@ -439,14 +543,14 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
}
if (!err && areq)
- start_err = __mmc_start_req(host, areq->mrq);
+ start_err = __mmc_start_data_req(host, areq->mrq);
if (host->areq)
mmc_post_req(host, host->areq->mrq, 0);
/* Cancel a prepared request if it was not started. */
if ((err || start_err) && areq)
- mmc_post_req(host, areq->mrq, -EINVAL);
+ mmc_post_req(host, areq->mrq, -EINVAL);
if (err)
host->areq = NULL;
@@ -696,6 +800,10 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
data->timeout_ns = limit_us * 1000;
data->timeout_clks = 0;
}
+
+ /* assign limit value if invalid */
+ if (timeout_us == 0)
+ data->timeout_ns = limit_us * 1000;
}
/*
@@ -800,31 +908,6 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
EXPORT_SYMBOL(__mmc_claim_host);
/**
- * mmc_try_claim_host - try exclusively to claim a host
- * @host: mmc host to claim
- *
- * Returns %1 if the host is claimed, %0 otherwise.
- */
-int mmc_try_claim_host(struct mmc_host *host)
-{
- int claimed_host = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
- if (!host->claimed || host->claimer == current) {
- host->claimed = 1;
- host->claimer = current;
- host->claim_cnt += 1;
- claimed_host = 1;
- }
- spin_unlock_irqrestore(&host->lock, flags);
- if (host->ops->enable && claimed_host && host->claim_cnt == 1)
- host->ops->enable(host);
- return claimed_host;
-}
-EXPORT_SYMBOL(mmc_try_claim_host);
-
-/**
* mmc_release_host - release a host
* @host: mmc host to release
*
@@ -854,6 +937,29 @@ void mmc_release_host(struct mmc_host *host)
EXPORT_SYMBOL(mmc_release_host);
/*
+ * This is a helper function, which fetches a runtime pm reference for the
+ * card device and also claims the host.
+ */
+void mmc_get_card(struct mmc_card *card)
+{
+ pm_runtime_get_sync(&card->dev);
+ mmc_claim_host(card->host);
+}
+EXPORT_SYMBOL(mmc_get_card);
+
+/*
+ * This is a helper function, which releases the host and drops the runtime
+ * pm reference for the card device.
+ */
+void mmc_put_card(struct mmc_card *card)
+{
+ mmc_release_host(card->host);
+ pm_runtime_mark_last_busy(&card->dev);
+ pm_runtime_put_autosuspend(&card->dev);
+}
+EXPORT_SYMBOL(mmc_put_card);
+
+/*
* Internal function that does the actual ios call to the host driver,
* optionally printing some debug output.
*/
@@ -1056,6 +1162,49 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
+#ifdef CONFIG_OF
+
+/**
+ * mmc_of_parse_voltage - return mask of supported voltages
+ * @np: The device node need to be parsed.
+ * @mask: mask of voltages available for MMC/SD/SDIO
+ *
+ * 1. Return zero on success.
+ * 2. Return negative errno: voltage-range is invalid.
+ */
+int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
+{
+ const u32 *voltage_ranges;
+ int num_ranges, i;
+
+ voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
+ num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
+ if (!voltage_ranges || !num_ranges) {
+ pr_info("%s: voltage-ranges unspecified\n", np->full_name);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < num_ranges; i++) {
+ const int j = i * 2;
+ u32 ocr_mask;
+
+ ocr_mask = mmc_vddrange_to_ocrmask(
+ be32_to_cpu(voltage_ranges[j]),
+ be32_to_cpu(voltage_ranges[j + 1]));
+ if (!ocr_mask) {
+ pr_err("%s: voltage-range #%d is invalid\n",
+ np->full_name, i);
+ return -EINVAL;
+ }
+ *mask |= ocr_mask;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mmc_of_parse_voltage);
+
+#endif /* CONFIG_OF */
+
#ifdef CONFIG_REGULATOR
/**
@@ -1137,7 +1286,7 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
*/
voltage = regulator_get_voltage(supply);
- if (regulator_count_voltages(supply) == 1)
+ if (!regulator_can_change_voltage(supply))
min_uV = max_uV = voltage;
if (voltage < 0)
@@ -1165,31 +1314,38 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
}
EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
+#endif /* CONFIG_REGULATOR */
+
int mmc_regulator_get_supply(struct mmc_host *mmc)
{
struct device *dev = mmc_dev(mmc);
- struct regulator *supply;
int ret;
- supply = devm_regulator_get(dev, "vmmc");
- mmc->supply.vmmc = supply;
- mmc->supply.vqmmc = devm_regulator_get(dev, "vqmmc");
+ mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc");
+ mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
- if (IS_ERR(supply))
- return PTR_ERR(supply);
+ if (IS_ERR(mmc->supply.vmmc)) {
+ if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(dev, "No vmmc regulator found\n");
+ } else {
+ ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
+ if (ret > 0)
+ mmc->ocr_avail = ret;
+ else
+ dev_warn(dev, "Failed getting OCR mask: %d\n", ret);
+ }
- ret = mmc_regulator_get_ocrmask(supply);
- if (ret > 0)
- mmc->ocr_avail = ret;
- else
- dev_warn(mmc_dev(mmc), "Failed getting OCR mask: %d\n", ret);
+ if (IS_ERR(mmc->supply.vqmmc)) {
+ if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(dev, "No vqmmc regulator found\n");
+ }
return 0;
}
EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
-#endif /* CONFIG_REGULATOR */
-
/*
* Mask off any voltages we don't support and select
* the lowest voltage
@@ -1198,31 +1354,60 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
{
int bit;
- ocr &= host->ocr_avail;
+ /*
+ * Sanity check the voltages that the card claims to
+ * support.
+ */
+ if (ocr & 0x7F) {
+ dev_warn(mmc_dev(host),
+ "card claims to support voltages below defined range\n");
+ ocr &= ~0x7F;
+ }
- bit = ffs(ocr);
- if (bit) {
- bit -= 1;
+ ocr &= host->ocr_avail;
+ if (!ocr) {
+ dev_warn(mmc_dev(host), "no support for card's volts\n");
+ return 0;
+ }
+ if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) {
+ bit = ffs(ocr) - 1;
+ ocr &= 3 << bit;
+ mmc_power_cycle(host, ocr);
+ } else {
+ bit = fls(ocr) - 1;
ocr &= 3 << bit;
+ if (bit != host->ios.vdd)
+ dev_warn(mmc_dev(host), "exceeding card's volts\n");
+ }
+
+ return ocr;
+}
+
+int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
+{
+ int err = 0;
+ int old_signal_voltage = host->ios.signal_voltage;
+ host->ios.signal_voltage = signal_voltage;
+ if (host->ops->start_signal_voltage_switch) {
mmc_host_clk_hold(host);
- host->ios.vdd = bit;
- mmc_set_ios(host);
+ err = host->ops->start_signal_voltage_switch(host, &host->ios);
mmc_host_clk_release(host);
- } else {
- pr_warning("%s: host doesn't support card's voltages\n",
- mmc_hostname(host));
- ocr = 0;
}
- return ocr;
+ if (err)
+ host->ios.signal_voltage = old_signal_voltage;
+
+ return err;
+
}
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11)
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
{
struct mmc_command cmd = {0};
int err = 0;
+ u32 clock;
BUG_ON(!host);
@@ -1230,27 +1415,81 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
* Send CMD11 only if the request is to switch the card to
* 1.8V signalling.
*/
- if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) {
- cmd.opcode = SD_SWITCH_VOLTAGE;
- cmd.arg = 0;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+ return __mmc_set_signal_voltage(host, signal_voltage);
- err = mmc_wait_for_cmd(host, &cmd, 0);
- if (err)
- return err;
+ /*
+ * If we cannot switch voltages, return failure so the caller
+ * can continue without UHS mode
+ */
+ if (!host->ops->start_signal_voltage_switch)
+ return -EPERM;
+ if (!host->ops->card_busy)
+ pr_warning("%s: cannot verify signal voltage switch\n",
+ mmc_hostname(host));
+
+ cmd.opcode = SD_SWITCH_VOLTAGE;
+ cmd.arg = 0;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
- return -EIO;
+ err = mmc_wait_for_cmd(host, &cmd, 0);
+ if (err)
+ return err;
+
+ if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+ return -EIO;
+
+ mmc_host_clk_hold(host);
+ /*
+ * The card should drive cmd and dat[0:3] low immediately
+ * after the response of cmd11, but wait 1 ms to be sure
+ */
+ mmc_delay(1);
+ if (host->ops->card_busy && !host->ops->card_busy(host)) {
+ err = -EAGAIN;
+ goto power_cycle;
}
+ /*
+ * During a signal voltage level switch, the clock must be gated
+ * for 5 ms according to the SD spec
+ */
+ clock = host->ios.clock;
+ host->ios.clock = 0;
+ mmc_set_ios(host);
- host->ios.signal_voltage = signal_voltage;
+ if (__mmc_set_signal_voltage(host, signal_voltage)) {
+ /*
+ * Voltages may not have been switched, but we've already
+ * sent CMD11, so a power cycle is required anyway
+ */
+ err = -EAGAIN;
+ goto power_cycle;
+ }
- if (host->ops->start_signal_voltage_switch) {
- mmc_host_clk_hold(host);
- err = host->ops->start_signal_voltage_switch(host, &host->ios);
- mmc_host_clk_release(host);
+ /* Keep clock gated for at least 5 ms */
+ mmc_delay(5);
+ host->ios.clock = clock;
+ mmc_set_ios(host);
+
+ /* Wait for at least 1 ms according to spec */
+ mmc_delay(1);
+
+ /*
+ * Failure to switch is indicated by the card holding
+ * dat[0:3] low
+ */
+ if (host->ops->card_busy && host->ops->card_busy(host))
+ err = -EAGAIN;
+
+power_cycle:
+ if (err) {
+ pr_debug("%s: Signal voltage switch failed, "
+ "power cycling card\n", mmc_hostname(host));
+ mmc_power_cycle(host, ocr);
}
+ mmc_host_clk_release(host);
+
return err;
}
@@ -1287,22 +1526,14 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
* If a host does all the power sequencing itself, ignore the
* initial MMC_POWER_UP stage.
*/
-static void mmc_power_up(struct mmc_host *host)
+void mmc_power_up(struct mmc_host *host, u32 ocr)
{
- int bit;
-
if (host->ios.power_mode == MMC_POWER_ON)
return;
mmc_host_clk_hold(host);
- /* If ocr is set, we use it */
- if (host->ocr)
- bit = ffs(host->ocr) - 1;
- else
- bit = fls(host->ocr_avail) - 1;
-
- host->ios.vdd = bit;
+ host->ios.vdd = fls(ocr) - 1;
if (mmc_host_is_spi(host))
host->ios.chip_select = MMC_CS_HIGH;
else
@@ -1313,8 +1544,13 @@ static void mmc_power_up(struct mmc_host *host)
host->ios.timing = MMC_TIMING_LEGACY;
mmc_set_ios(host);
- /* Set signal voltage to 3.3V */
- mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, false);
+ /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */
+ if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0)
+ dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n");
+ else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180) == 0)
+ dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n");
+ else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120) == 0)
+ dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n");
/*
* This delay should be sufficient to allow the power supply
@@ -1346,13 +1582,6 @@ void mmc_power_off(struct mmc_host *host)
host->ios.clock = 0;
host->ios.vdd = 0;
-
- /*
- * Reset ocr mask to be the highest possible voltage supported for
- * this mmc host. This value will be used at next power up.
- */
- host->ocr = 1 << (fls(host->ocr_avail) - 1);
-
if (!mmc_host_is_spi(host)) {
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.chip_select = MMC_CS_DONTCARE;
@@ -1372,6 +1601,14 @@ void mmc_power_off(struct mmc_host *host)
mmc_host_clk_release(host);
}
+void mmc_power_cycle(struct mmc_host *host, u32 ocr)
+{
+ mmc_power_off(host);
+ /* Wait at least 1 ms according to SD spec */
+ mmc_delay(1);
+ mmc_power_up(host, ocr);
+}
+
/*
* Cleanup when the last reference to the bus operator is dropped.
*/
@@ -1457,6 +1694,28 @@ void mmc_detach_bus(struct mmc_host *host)
mmc_bus_put(host);
}
+static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
+ bool cd_irq)
+{
+#ifdef CONFIG_MMC_DEBUG
+ unsigned long flags;
+ spin_lock_irqsave(&host->lock, flags);
+ WARN_ON(host->removed);
+ spin_unlock_irqrestore(&host->lock, flags);
+#endif
+
+ /*
+ * If the device is configured as wakeup, we prevent a new sleep for
+ * 5 s to give provision for user space to consume the event.
+ */
+ if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) &&
+ device_can_wakeup(mmc_dev(host)))
+ pm_wakeup_event(mmc_dev(host), 5000);
+
+ host->detect_change = 1;
+ mmc_schedule_delayed_work(&host->detect, delay);
+}
+
/**
* mmc_detect_change - process change of state on a MMC socket
* @host: host which changed state.
@@ -1469,16 +1728,8 @@ void mmc_detach_bus(struct mmc_host *host)
*/
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
-#ifdef CONFIG_MMC_DEBUG
- unsigned long flags;
- spin_lock_irqsave(&host->lock, flags);
- WARN_ON(host->removed);
- spin_unlock_irqrestore(&host->lock, flags);
-#endif
- host->detect_change = 1;
- mmc_schedule_delayed_work(&host->detect, delay);
+ _mmc_detect_change(host, delay, true);
}
-
EXPORT_SYMBOL(mmc_detect_change);
void mmc_init_erase(struct mmc_card *card)
@@ -1700,7 +1951,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
cmd.opcode = MMC_ERASE;
cmd.arg = arg;
cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
- cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty);
+ cmd.busy_timeout = mmc_erase_timeout(card, arg, qty);
err = mmc_wait_for_cmd(card->host, &cmd, 0);
if (err) {
pr_err("mmc_erase: erase error %d, status %#x\n",
@@ -1887,7 +2138,7 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card,
y = 0;
for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) {
timeout = mmc_erase_timeout(card, arg, qty + x);
- if (timeout > host->max_discard_to)
+ if (timeout > host->max_busy_timeout)
break;
if (timeout < last_timeout)
break;
@@ -1919,7 +2170,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
struct mmc_host *host = card->host;
unsigned int max_discard, max_trim;
- if (!host->max_discard_to)
+ if (!host->max_busy_timeout)
return UINT_MAX;
/*
@@ -1939,7 +2190,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
max_discard = 0;
}
pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n",
- mmc_hostname(host), max_discard, host->max_discard_to);
+ mmc_hostname(host), max_discard, host->max_busy_timeout);
return max_discard;
}
EXPORT_SYMBOL(mmc_calc_max_discard);
@@ -1948,7 +2199,7 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
{
struct mmc_command cmd = {0};
- if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card))
+ if (mmc_card_blockaddr(card) || mmc_card_ddr52(card))
return 0;
cmd.opcode = MMC_SET_BLOCKLEN;
@@ -1998,9 +2249,6 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check)
{
struct mmc_card *card = host->card;
- if (!host->bus_ops->power_restore)
- return -EOPNOTSUPP;
-
if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
return -EOPNOTSUPP;
@@ -2031,7 +2279,6 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check)
}
}
- host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_DDR);
if (mmc_host_is_spi(host)) {
host->ios.chip_select = MMC_CS_HIGH;
host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
@@ -2068,7 +2315,7 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
pr_info("%s: %s: trying to init card at %u Hz\n",
mmc_hostname(host), __func__, host->f_init);
#endif
- mmc_power_up(host);
+ mmc_power_up(host, host->ocr_avail);
/*
* Some eMMCs (with VCCQ always on) may not be reset after power up, so
@@ -2102,13 +2349,26 @@ int _mmc_detect_card_removed(struct mmc_host *host)
{
int ret;
- if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive)
+ if (host->caps & MMC_CAP_NONREMOVABLE)
return 0;
if (!host->card || mmc_card_removed(host->card))
return 1;
ret = host->bus_ops->alive(host);
+
+ /*
+ * Card detect status and alive check may be out of sync if card is
+ * removed slowly, when card detect switch changes while card/slot
+ * pads are still contacted in hardware (refer to "SD Card Mechanical
+ * Addendum, Appendix C: Card Detection Switch"). So reschedule a
+ * detect work 200ms later for this case.
+ */
+ if (!ret && host->ops->get_cd && !host->ops->get_cd(host)) {
+ mmc_detect_change(host, msecs_to_jiffies(200));
+ pr_debug("%s: card removed too slowly\n", mmc_hostname(host));
+ }
+
if (ret) {
mmc_card_set_removed(host->card);
pr_debug("%s: card remove detected\n", mmc_hostname(host));
@@ -2132,20 +2392,19 @@ int mmc_detect_card_removed(struct mmc_host *host)
* The card will be considered unchanged unless we have been asked to
* detect a change or host requires polling to provide card detection.
*/
- if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) &&
- !(host->caps2 & MMC_CAP2_DETECT_ON_ERR))
+ if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL))
return ret;
host->detect_change = 0;
if (!ret) {
ret = _mmc_detect_card_removed(host);
- if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) {
+ if (ret && (host->caps & MMC_CAP_NEEDS_POLL)) {
/*
* Schedule a detect work as soon as possible to let a
* rescan handle the card removal.
*/
cancel_delayed_work(&host->detect);
- mmc_detect_change(host, 0);
+ _mmc_detect_change(host, 0, false);
}
}
@@ -2159,6 +2418,11 @@ void mmc_rescan(struct work_struct *work)
container_of(work, struct mmc_host, detect.work);
int i;
+ if (host->trigger_card_event && host->ops->card_event) {
+ host->ops->card_event(host);
+ host->trigger_card_event = false;
+ }
+
if (host->rescan_disable)
return;
@@ -2173,7 +2437,7 @@ void mmc_rescan(struct work_struct *work)
* if there is a _removable_ card registered, check whether it is
* still present
*/
- if (host->bus_ops && host->bus_ops->detect && !host->bus_dead
+ if (host->bus_ops && !host->bus_dead
&& !(host->caps & MMC_CAP_NONREMOVABLE))
host->bus_ops->detect(host);
@@ -2198,7 +2462,8 @@ void mmc_rescan(struct work_struct *work)
*/
mmc_bus_put(host);
- if (host->ops->get_cd && host->ops->get_cd(host) == 0) {
+ if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->get_cd &&
+ host->ops->get_cd(host) == 0) {
mmc_claim_host(host);
mmc_power_off(host);
mmc_release_host(host);
@@ -2223,8 +2488,12 @@ void mmc_start_host(struct mmc_host *host)
{
host->f_init = max(freqs[0], host->f_min);
host->rescan_disable = 0;
- mmc_power_up(host);
- mmc_detect_change(host, 0);
+ if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
+ mmc_power_off(host);
+ else
+ mmc_power_up(host, host->ocr_avail);
+ mmc_gpiod_request_cd_irq(host);
+ _mmc_detect_change(host, 0, false);
}
void mmc_stop_host(struct mmc_host *host)
@@ -2235,6 +2504,8 @@ void mmc_stop_host(struct mmc_host *host)
host->removed = 1;
spin_unlock_irqrestore(&host->lock, flags);
#endif
+ if (host->slot.cd_irq >= 0)
+ disable_irq(host->slot.cd_irq);
host->rescan_disable = 1;
cancel_delayed_work_sync(&host->detect);
@@ -2246,9 +2517,7 @@ void mmc_stop_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
/* Calling bus_ops->remove() with a claimed host can deadlock */
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
-
+ host->bus_ops->remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
@@ -2273,7 +2542,7 @@ int mmc_power_save_host(struct mmc_host *host)
mmc_bus_get(host);
- if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) {
+ if (!host->bus_ops || host->bus_dead) {
mmc_bus_put(host);
return -EINVAL;
}
@@ -2299,12 +2568,12 @@ int mmc_power_restore_host(struct mmc_host *host)
mmc_bus_get(host);
- if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) {
+ if (!host->bus_ops || host->bus_dead) {
mmc_bus_put(host);
return -EINVAL;
}
- mmc_power_up(host);
+ mmc_power_up(host, host->card->ocr);
ret = host->bus_ops->power_restore(host);
mmc_bus_put(host);
@@ -2313,63 +2582,13 @@ int mmc_power_restore_host(struct mmc_host *host)
}
EXPORT_SYMBOL(mmc_power_restore_host);
-int mmc_card_awake(struct mmc_host *host)
-{
- int err = -ENOSYS;
-
- if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
- return 0;
-
- mmc_bus_get(host);
-
- if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
- err = host->bus_ops->awake(host);
-
- mmc_bus_put(host);
-
- return err;
-}
-EXPORT_SYMBOL(mmc_card_awake);
-
-int mmc_card_sleep(struct mmc_host *host)
-{
- int err = -ENOSYS;
-
- if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
- return 0;
-
- mmc_bus_get(host);
-
- if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
- err = host->bus_ops->sleep(host);
-
- mmc_bus_put(host);
-
- return err;
-}
-EXPORT_SYMBOL(mmc_card_sleep);
-
-int mmc_card_can_sleep(struct mmc_host *host)
-{
- struct mmc_card *card = host->card;
-
- if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3)
- return 1;
- return 0;
-}
-EXPORT_SYMBOL(mmc_card_can_sleep);
-
/*
* Flush the cache to the non-volatile storage.
*/
int mmc_flush_cache(struct mmc_card *card)
{
- struct mmc_host *host = card->host;
int err = 0;
- if (!(host->caps2 & MMC_CAP2_CACHE_CTRL))
- return err;
-
if (mmc_card_mmc(card) &&
(card->ext_csd.cache_size > 0) &&
(card->ext_csd.cache_ctrl & 1)) {
@@ -2384,143 +2603,8 @@ int mmc_flush_cache(struct mmc_card *card)
}
EXPORT_SYMBOL(mmc_flush_cache);
-/*
- * Turn the cache ON/OFF.
- * Turning the cache OFF shall trigger flushing of the data
- * to the non-volatile storage.
- */
-int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
-{
- struct mmc_card *card = host->card;
- unsigned int timeout;
- int err = 0;
-
- if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
- mmc_card_is_removable(host))
- return err;
-
- mmc_claim_host(host);
- if (card && mmc_card_mmc(card) &&
- (card->ext_csd.cache_size > 0)) {
- enable = !!enable;
-
- if (card->ext_csd.cache_ctrl ^ enable) {
- timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_CACHE_CTRL, enable, timeout);
- if (err)
- pr_err("%s: cache %s error %d\n",
- mmc_hostname(card->host),
- enable ? "on" : "off",
- err);
- else
- card->ext_csd.cache_ctrl = enable;
- }
- }
- mmc_release_host(host);
-
- return err;
-}
-EXPORT_SYMBOL(mmc_cache_ctrl);
-
#ifdef CONFIG_PM
-/**
- * mmc_suspend_host - suspend a host
- * @host: mmc host
- */
-int mmc_suspend_host(struct mmc_host *host)
-{
- int err = 0;
-
- cancel_delayed_work(&host->detect);
- mmc_flush_scheduled_work();
-
- err = mmc_cache_ctrl(host, 0);
- if (err)
- goto out;
-
- mmc_bus_get(host);
- if (host->bus_ops && !host->bus_dead) {
- if (host->bus_ops->suspend) {
- if (mmc_card_doing_bkops(host->card)) {
- err = mmc_stop_bkops(host->card);
- if (err)
- goto out;
- }
- err = host->bus_ops->suspend(host);
- }
-
- if (err == -ENOSYS || !host->bus_ops->resume) {
- /*
- * We simply "remove" the card in this case.
- * It will be redetected on resume. (Calling
- * bus_ops->remove() with a claimed host can
- * deadlock.)
- */
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
- mmc_claim_host(host);
- mmc_detach_bus(host);
- mmc_power_off(host);
- mmc_release_host(host);
- host->pm_flags = 0;
- err = 0;
- }
- }
- mmc_bus_put(host);
-
- if (!err && !mmc_card_keep_power(host))
- mmc_power_off(host);
-
-out:
- return err;
-}
-
-EXPORT_SYMBOL(mmc_suspend_host);
-
-/**
- * mmc_resume_host - resume a previously suspended host
- * @host: mmc host
- */
-int mmc_resume_host(struct mmc_host *host)
-{
- int err = 0;
-
- mmc_bus_get(host);
- if (host->bus_ops && !host->bus_dead) {
- if (!mmc_card_keep_power(host)) {
- mmc_power_up(host);
- mmc_select_voltage(host, host->ocr);
- /*
- * Tell runtime PM core we just powered up the card,
- * since it still believes the card is powered off.
- * Note that currently runtime PM is only enabled
- * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
- */
- if (mmc_card_sdio(host->card) &&
- (host->caps & MMC_CAP_POWER_OFF_CARD)) {
- pm_runtime_disable(&host->card->dev);
- pm_runtime_set_active(&host->card->dev);
- pm_runtime_enable(&host->card->dev);
- }
- }
- BUG_ON(!host->bus_ops->resume);
- err = host->bus_ops->resume(host);
- if (err) {
- pr_warning("%s: error %d during resume "
- "(card was removed?)\n",
- mmc_hostname(host), err);
- err = 0;
- }
- }
- host->pm_flags &= ~MMC_PM_KEEP_POWER;
- mmc_bus_put(host);
-
- return err;
-}
-EXPORT_SYMBOL(mmc_resume_host);
-
/* Do the card removal on suspend if card is assumed removeable
* Do that in pm notifier while userspace isn't yet frozen, so we will be able
to sync the card.
@@ -2536,29 +2620,22 @@ int mmc_pm_notify(struct notifier_block *notify_block,
switch (mode) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
- if (host->card && mmc_card_mmc(host->card) &&
- mmc_card_doing_bkops(host->card)) {
- err = mmc_stop_bkops(host->card);
- if (err) {
- pr_err("%s: didn't stop bkops\n",
- mmc_hostname(host));
- return err;
- }
- mmc_card_clr_doing_bkops(host->card);
- }
-
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 1;
spin_unlock_irqrestore(&host->lock, flags);
cancel_delayed_work_sync(&host->detect);
- if (!host->bus_ops || host->bus_ops->suspend)
+ if (!host->bus_ops)
break;
- /* Calling bus_ops->remove() with a claimed host can deadlock */
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
+ /* Validate prerequisites for suspend */
+ if (host->bus_ops->pre_suspend)
+ err = host->bus_ops->pre_suspend(host);
+ if (!err)
+ break;
+ /* Calling bus_ops->remove() with a claimed host can deadlock */
+ host->bus_ops->remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
@@ -2573,7 +2650,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 0;
spin_unlock_irqrestore(&host->lock, flags);
- mmc_detect_change(host, 0);
+ _mmc_detect_change(host, 0, false);
}
@@ -2581,6 +2658,23 @@ int mmc_pm_notify(struct notifier_block *notify_block,
}
#endif
+/**
+ * mmc_init_context_info() - init synchronization context
+ * @host: mmc host
+ *
+ * Init struct context_info needed to implement asynchronous
+ * request mechanism, used by mmc core, host driver and mmc requests
+ * supplier.
+ */
+void mmc_init_context_info(struct mmc_host *host)
+{
+ spin_lock_init(&host->context_info.lock);
+ host->context_info.is_new_req = false;
+ host->context_info.is_done_rcv = false;
+ host->context_info.is_waiting_last_req = false;
+ init_waitqueue_head(&host->context_info.wait);
+}
+
static int __init mmc_init(void)
{
int ret;