Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[pandora-kernel.git] / drivers / mmc / core / core.c
index 1f453ac..7843efe 100644 (file)
@@ -236,12 +236,10 @@ EXPORT_SYMBOL(mmc_wait_for_req);
  */
 int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
 {
-       struct mmc_request mrq;
+       struct mmc_request mrq = {0};
 
        WARN_ON(!host->claimed);
 
-       memset(&mrq, 0, sizeof(struct mmc_request));
-
        memset(cmd->resp, 0, sizeof(cmd->resp));
        cmd->retries = retries;
 
@@ -719,23 +717,13 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
        mmc_set_ios(host);
 }
 
-/*
- * Change data bus width and DDR mode of a host.
- */
-void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
-                          unsigned int ddr)
-{
-       host->ios.bus_width = width;
-       host->ios.ddr = ddr;
-       mmc_set_ios(host);
-}
-
 /*
  * Change data bus width of a host.
  */
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
 {
-       mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE);
+       host->ios.bus_width = width;
+       mmc_set_ios(host);
 }
 
 /**
@@ -944,6 +932,38 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
        return ocr;
 }
 
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11)
+{
+       struct mmc_command cmd = {0};
+       int err = 0;
+
+       BUG_ON(!host);
+
+       /*
+        * 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;
+
+               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;
+       }
+
+       host->ios.signal_voltage = signal_voltage;
+
+       if (host->ops->start_signal_voltage_switch)
+               err = host->ops->start_signal_voltage_switch(host, &host->ios);
+
+       return err;
+}
+
 /*
  * Select timing parameters for host.
  */
@@ -953,6 +973,15 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
        mmc_set_ios(host);
 }
 
+/*
+ * Select appropriate driver type for host.
+ */
+void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
+{
+       host->ios.drv_type = drv_type;
+       mmc_set_ios(host);
+}
+
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -1187,9 +1216,8 @@ void mmc_init_erase(struct mmc_card *card)
        }
 }
 
-static void mmc_set_mmc_erase_timeout(struct mmc_card *card,
-                                     struct mmc_command *cmd,
-                                     unsigned int arg, unsigned int qty)
+static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
+                                         unsigned int arg, unsigned int qty)
 {
        unsigned int erase_timeout;
 
@@ -1217,7 +1245,7 @@ static void mmc_set_mmc_erase_timeout(struct mmc_card *card,
                 */
                timeout_clks <<= 1;
                timeout_us += (timeout_clks * 1000) /
-                             (card->host->ios.clock / 1000);
+                             (mmc_host_clk_rate(card->host) / 1000);
 
                erase_timeout = timeout_us / 1000;
 
@@ -1246,44 +1274,48 @@ static void mmc_set_mmc_erase_timeout(struct mmc_card *card,
        if (mmc_host_is_spi(card->host) && erase_timeout < 1000)
                erase_timeout = 1000;
 
-       cmd->erase_timeout = erase_timeout;
+       return erase_timeout;
 }
 
-static void mmc_set_sd_erase_timeout(struct mmc_card *card,
-                                    struct mmc_command *cmd, unsigned int arg,
-                                    unsigned int qty)
+static unsigned int mmc_sd_erase_timeout(struct mmc_card *card,
+                                        unsigned int arg,
+                                        unsigned int qty)
 {
+       unsigned int erase_timeout;
+
        if (card->ssr.erase_timeout) {
                /* Erase timeout specified in SD Status Register (SSR) */
-               cmd->erase_timeout = card->ssr.erase_timeout * qty +
-                                    card->ssr.erase_offset;
+               erase_timeout = card->ssr.erase_timeout * qty +
+                               card->ssr.erase_offset;
        } else {
                /*
                 * Erase timeout not specified in SD Status Register (SSR) so
                 * use 250ms per write block.
                 */
-               cmd->erase_timeout = 250 * qty;
+               erase_timeout = 250 * qty;
        }
 
        /* Must not be less than 1 second */
-       if (cmd->erase_timeout < 1000)
-               cmd->erase_timeout = 1000;
+       if (erase_timeout < 1000)
+               erase_timeout = 1000;
+
+       return erase_timeout;
 }
 
-static void mmc_set_erase_timeout(struct mmc_card *card,
-                                 struct mmc_command *cmd, unsigned int arg,
-                                 unsigned int qty)
+static unsigned int mmc_erase_timeout(struct mmc_card *card,
+                                     unsigned int arg,
+                                     unsigned int qty)
 {
        if (mmc_card_sd(card))
-               mmc_set_sd_erase_timeout(card, cmd, arg, qty);
+               return mmc_sd_erase_timeout(card, arg, qty);
        else
-               mmc_set_mmc_erase_timeout(card, cmd, arg, qty);
+               return mmc_mmc_erase_timeout(card, arg, qty);
 }
 
 static int mmc_do_erase(struct mmc_card *card, unsigned int from,
                        unsigned int to, unsigned int arg)
 {
-       struct mmc_command cmd;
+       struct mmc_command cmd = {0};
        unsigned int qty = 0;
        int err;
 
@@ -1317,7 +1349,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
                to <<= 9;
        }
 
-       memset(&cmd, 0, sizeof(struct mmc_command));
        if (mmc_card_sd(card))
                cmd.opcode = SD_ERASE_WR_BLK_START;
        else
@@ -1351,7 +1382,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;
-       mmc_set_erase_timeout(card, &cmd, arg, qty);
+       cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty);
        err = mmc_wait_for_cmd(card->host, &cmd, 0);
        if (err) {
                printk(KERN_ERR "mmc_erase: erase error %d, status %#x\n",
@@ -1487,12 +1518,11 @@ EXPORT_SYMBOL(mmc_erase_group_aligned);
 
 int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
 {
-       struct mmc_command cmd;
+       struct mmc_command cmd = {0};
 
        if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card))
                return 0;
 
-       memset(&cmd, 0, sizeof(struct mmc_command));
        cmd.opcode = MMC_SET_BLOCKLEN;
        cmd.arg = blocklen;
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
@@ -1578,7 +1608,7 @@ void mmc_rescan(struct work_struct *work)
        for (i = 0; i < ARRAY_SIZE(freqs); i++) {
                if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
                        break;
-               if (freqs[i] < host->f_min)
+               if (freqs[i] <= host->f_min)
                        break;
        }
        mmc_release_host(host);
@@ -1746,7 +1776,7 @@ int mmc_suspend_host(struct mmc_host *host)
        }
        mmc_bus_put(host);
 
-       if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
+       if (!err && !mmc_card_keep_power(host))
                mmc_power_off(host);
 
        return err;
@@ -1764,7 +1794,7 @@ int mmc_resume_host(struct mmc_host *host)
 
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
-               if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
+               if (!mmc_card_keep_power(host)) {
                        mmc_power_up(host);
                        mmc_select_voltage(host, host->ocr);
                        /*
@@ -1789,6 +1819,7 @@ int mmc_resume_host(struct mmc_host *host)
                        err = 0;
                }
        }
+       host->pm_flags &= ~MMC_PM_KEEP_POWER;
        mmc_bus_put(host);
 
        return err;