]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/mmc/core/core.c
Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / mmc / core / core.c
index a3eb20bdcd97bf32d7a56d741b1bde5097d65767..5ae89e48fd85b575cf743363b3a298b49872b7db 100644 (file)
@@ -187,8 +187,6 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 
                if (mrq->done)
                        mrq->done(mrq);
-
-               mmc_host_clk_release(host);
        }
 }
 
@@ -206,6 +204,23 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
                return;
        }
 
+       /*
+        * For sdio rw commands we must wait for card busy otherwise some
+        * sdio devices won't work properly.
+        */
+       if (mmc_is_io_op(mrq->cmd->opcode) && host->ops->card_busy) {
+               int tries = 500; /* Wait aprox 500ms at maximum */
+
+               while (host->ops->card_busy(host) && --tries)
+                       mmc_delay(1);
+
+               if (tries == 0) {
+                       mrq->cmd->error = -EBUSY;
+                       mmc_request_done(host, mrq);
+                       return;
+               }
+       }
+
        host->ops->request(host, mrq);
 }
 
@@ -275,7 +290,6 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
                        mrq->stop->mrq = mrq;
                }
        }
-       mmc_host_clk_hold(host);
        led_trigger_event(host->led, LED_FULL);
        __mmc_start_request(host, mrq);
 
@@ -525,11 +539,8 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
 static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
                 bool is_first_req)
 {
-       if (host->ops->pre_req) {
-               mmc_host_clk_hold(host);
+       if (host->ops->pre_req)
                host->ops->pre_req(host, mrq, is_first_req);
-               mmc_host_clk_release(host);
-       }
 }
 
 /**
@@ -544,11 +555,8 @@ static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
 static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
                         int err)
 {
-       if (host->ops->post_req) {
-               mmc_host_clk_hold(host);
+       if (host->ops->post_req)
                host->ops->post_req(host, mrq, err);
-               mmc_host_clk_release(host);
-       }
 }
 
 /**
@@ -833,9 +841,9 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
                unsigned int timeout_us, limit_us;
 
                timeout_us = data->timeout_ns / 1000;
-               if (mmc_host_clk_rate(card->host))
+               if (card->host->ios.clock)
                        timeout_us += data->timeout_clks * 1000 /
-                               (mmc_host_clk_rate(card->host) / 1000);
+                               (card->host->ios.clock / 1000);
 
                if (data->flags & MMC_DATA_WRITE)
                        /*
@@ -1033,8 +1041,6 @@ static inline void mmc_set_ios(struct mmc_host *host)
                 ios->power_mode, ios->chip_select, ios->vdd,
                 ios->bus_width, ios->timing);
 
-       if (ios->clock > 0)
-               mmc_set_ungated(host);
        host->ops->set_ios(host, ios);
 }
 
@@ -1043,17 +1049,15 @@ static inline void mmc_set_ios(struct mmc_host *host)
  */
 void mmc_set_chip_select(struct mmc_host *host, int mode)
 {
-       mmc_host_clk_hold(host);
        host->ios.chip_select = mode;
        mmc_set_ios(host);
-       mmc_host_clk_release(host);
 }
 
 /*
  * Sets the host clock to the highest possible frequency that
  * is below "hz".
  */
-static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
+void mmc_set_clock(struct mmc_host *host, unsigned int hz)
 {
        WARN_ON(hz && hz < host->f_min);
 
@@ -1064,68 +1068,6 @@ static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
        mmc_set_ios(host);
 }
 
-void mmc_set_clock(struct mmc_host *host, unsigned int hz)
-{
-       mmc_host_clk_hold(host);
-       __mmc_set_clock(host, hz);
-       mmc_host_clk_release(host);
-}
-
-#ifdef CONFIG_MMC_CLKGATE
-/*
- * This gates the clock by setting it to 0 Hz.
- */
-void mmc_gate_clock(struct mmc_host *host)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&host->clk_lock, flags);
-       host->clk_old = host->ios.clock;
-       host->ios.clock = 0;
-       host->clk_gated = true;
-       spin_unlock_irqrestore(&host->clk_lock, flags);
-       mmc_set_ios(host);
-}
-
-/*
- * This restores the clock from gating by using the cached
- * clock value.
- */
-void mmc_ungate_clock(struct mmc_host *host)
-{
-       /*
-        * We should previously have gated the clock, so the clock shall
-        * be 0 here! The clock may however be 0 during initialization,
-        * when some request operations are performed before setting
-        * the frequency. When ungate is requested in that situation
-        * we just ignore the call.
-        */
-       if (host->clk_old) {
-               BUG_ON(host->ios.clock);
-               /* This call will also set host->clk_gated to false */
-               __mmc_set_clock(host, host->clk_old);
-       }
-}
-
-void mmc_set_ungated(struct mmc_host *host)
-{
-       unsigned long flags;
-
-       /*
-        * We've been given a new frequency while the clock is gated,
-        * so make sure we regard this as ungating it.
-        */
-       spin_lock_irqsave(&host->clk_lock, flags);
-       host->clk_gated = false;
-       spin_unlock_irqrestore(&host->clk_lock, flags);
-}
-
-#else
-void mmc_set_ungated(struct mmc_host *host)
-{
-}
-#endif
-
 int mmc_execute_tuning(struct mmc_card *card)
 {
        struct mmc_host *host = card->host;
@@ -1140,9 +1082,7 @@ int mmc_execute_tuning(struct mmc_card *card)
        else
                opcode = MMC_SEND_TUNING_BLOCK;
 
-       mmc_host_clk_hold(host);
        err = host->ops->execute_tuning(host, opcode);
-       mmc_host_clk_release(host);
 
        if (err)
                pr_err("%s: tuning execution failed\n", mmc_hostname(host));
@@ -1157,10 +1097,8 @@ int mmc_execute_tuning(struct mmc_card *card)
  */
 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
 {
-       mmc_host_clk_hold(host);
        host->ios.bus_mode = mode;
        mmc_set_ios(host);
-       mmc_host_clk_release(host);
 }
 
 /*
@@ -1168,10 +1106,8 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
  */
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
 {
-       mmc_host_clk_hold(host);
        host->ios.bus_width = width;
        mmc_set_ios(host);
-       mmc_host_clk_release(host);
 }
 
 /*
@@ -1340,6 +1276,40 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host,
 
 #ifdef CONFIG_REGULATOR
 
+/**
+ * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage
+ * @vdd_bit:   OCR bit number
+ * @min_uV:    minimum voltage value (mV)
+ * @max_uV:    maximum voltage value (mV)
+ *
+ * This function returns the voltage range according to the provided OCR
+ * bit number. If conversion is not possible a negative errno value returned.
+ */
+static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV)
+{
+       int             tmp;
+
+       if (!vdd_bit)
+               return -EINVAL;
+
+       /*
+        * REVISIT mmc_vddrange_to_ocrmask() may have set some
+        * bits this regulator doesn't quite support ... don't
+        * be too picky, most cards and regulators are OK with
+        * a 0.1V range goof (it's a small error percentage).
+        */
+       tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+       if (tmp == 0) {
+               *min_uV = 1650 * 1000;
+               *max_uV = 1950 * 1000;
+       } else {
+               *min_uV = 1900 * 1000 + tmp * 100 * 1000;
+               *max_uV = *min_uV + 100 * 1000;
+       }
+
+       return 0;
+}
+
 /**
  * mmc_regulator_get_ocrmask - return mask of supported voltages
  * @supply: regulator to use
@@ -1403,22 +1373,7 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
        int                     min_uV, max_uV;
 
        if (vdd_bit) {
-               int             tmp;
-
-               /*
-                * REVISIT mmc_vddrange_to_ocrmask() may have set some
-                * bits this regulator doesn't quite support ... don't
-                * be too picky, most cards and regulators are OK with
-                * a 0.1V range goof (it's a small error percentage).
-                */
-               tmp = vdd_bit - ilog2(MMC_VDD_165_195);
-               if (tmp == 0) {
-                       min_uV = 1650 * 1000;
-                       max_uV = 1950 * 1000;
-               } else {
-                       min_uV = 1900 * 1000 + tmp * 100 * 1000;
-                       max_uV = min_uV + 100 * 1000;
-               }
+               mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV);
 
                result = regulator_set_voltage(supply, min_uV, max_uV);
                if (result == 0 && !mmc->regulator_enabled) {
@@ -1439,6 +1394,84 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
 }
 EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
 
+static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator,
+                                                 int min_uV, int target_uV,
+                                                 int max_uV)
+{
+       /*
+        * Check if supported first to avoid errors since we may try several
+        * signal levels during power up and don't want to show errors.
+        */
+       if (!regulator_is_supported_voltage(regulator, min_uV, max_uV))
+               return -EINVAL;
+
+       return regulator_set_voltage_triplet(regulator, min_uV, target_uV,
+                                            max_uV);
+}
+
+/**
+ * mmc_regulator_set_vqmmc - Set VQMMC as per the ios
+ *
+ * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible.
+ * That will match the behavior of old boards where VQMMC and VMMC were supplied
+ * by the same supply.  The Bus Operating conditions for 3.3V signaling in the
+ * SD card spec also define VQMMC in terms of VMMC.
+ * If this is not possible we'll try the full 2.7-3.6V of the spec.
+ *
+ * For 1.2V and 1.8V signaling we'll try to get as close as possible to the
+ * requested voltage.  This is definitely a good idea for UHS where there's a
+ * separate regulator on the card that's trying to make 1.8V and it's best if
+ * we match.
+ *
+ * This function is expected to be used by a controller's
+ * start_signal_voltage_switch() function.
+ */
+int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct device *dev = mmc_dev(mmc);
+       int ret, volt, min_uV, max_uV;
+
+       /* If no vqmmc supply then we can't change the voltage */
+       if (IS_ERR(mmc->supply.vqmmc))
+               return -EINVAL;
+
+       switch (ios->signal_voltage) {
+       case MMC_SIGNAL_VOLTAGE_120:
+               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               1100000, 1200000, 1300000);
+       case MMC_SIGNAL_VOLTAGE_180:
+               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               1700000, 1800000, 1950000);
+       case MMC_SIGNAL_VOLTAGE_330:
+               ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV);
+               if (ret < 0)
+                       return ret;
+
+               dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n",
+                       __func__, volt, max_uV);
+
+               min_uV = max(volt - 300000, 2700000);
+               max_uV = min(max_uV + 200000, 3600000);
+
+               /*
+                * Due to a limitation in the current implementation of
+                * regulator_set_voltage_triplet() which is taking the lowest
+                * voltage possible if below the target, search for a suitable
+                * voltage in two steps and try to stay close to vmmc
+                * with a 0.3V tolerance at first.
+                */
+               if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               min_uV, volt, max_uV))
+                       return 0;
+
+               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               2700000, volt, 3600000);
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc);
+
 #endif /* CONFIG_REGULATOR */
 
 int mmc_regulator_get_supply(struct mmc_host *mmc)
@@ -1515,11 +1548,8 @@ int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
        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);
+       if (host->ops->start_signal_voltage_switch)
                err = host->ops->start_signal_voltage_switch(host, &host->ios);
-               mmc_host_clk_release(host);
-       }
 
        if (err)
                host->ios.signal_voltage = old_signal_voltage;
@@ -1553,20 +1583,17 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
                pr_warn("%s: cannot verify signal voltage switch\n",
                        mmc_hostname(host));
 
-       mmc_host_clk_hold(host);
-
        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)
-               goto err_command;
+               return err;
+
+       if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+               return -EIO;
 
-       if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) {
-               err = -EIO;
-               goto err_command;
-       }
        /*
         * The card should drive cmd and dat[0:3] low immediately
         * after the response of cmd11, but wait 1 ms to be sure
@@ -1615,9 +1642,6 @@ power_cycle:
                mmc_power_cycle(host, ocr);
        }
 
-err_command:
-       mmc_host_clk_release(host);
-
        return err;
 }
 
@@ -1626,10 +1650,8 @@ err_command:
  */
 void mmc_set_timing(struct mmc_host *host, unsigned int timing)
 {
-       mmc_host_clk_hold(host);
        host->ios.timing = timing;
        mmc_set_ios(host);
-       mmc_host_clk_release(host);
 }
 
 /*
@@ -1637,10 +1659,8 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
  */
 void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
 {
-       mmc_host_clk_hold(host);
        host->ios.drv_type = drv_type;
        mmc_set_ios(host);
-       mmc_host_clk_release(host);
 }
 
 int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
@@ -1648,7 +1668,6 @@ int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
 {
        struct mmc_host *host = card->host;
        int host_drv_type = SD_DRIVER_TYPE_B;
-       int drive_strength;
 
        *drv_type = 0;
 
@@ -1671,14 +1690,10 @@ int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
         * information and let the hardware specific code
         * return what is possible given the options
         */
-       mmc_host_clk_hold(host);
-       drive_strength = host->ops->select_drive_strength(card, max_dtr,
-                                                         host_drv_type,
-                                                         card_drv_type,
-                                                         drv_type);
-       mmc_host_clk_release(host);
-
-       return drive_strength;
+       return host->ops->select_drive_strength(card, max_dtr,
+                                               host_drv_type,
+                                               card_drv_type,
+                                               drv_type);
 }
 
 /*
@@ -1697,8 +1712,6 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
        if (host->ios.power_mode == MMC_POWER_ON)
                return;
 
-       mmc_host_clk_hold(host);
-
        mmc_pwrseq_pre_power_on(host);
 
        host->ios.vdd = fls(ocr) - 1;
@@ -1732,8 +1745,6 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
         * time required to reach a stable voltage.
         */
        mmc_delay(10);
-
-       mmc_host_clk_release(host);
 }
 
 void mmc_power_off(struct mmc_host *host)
@@ -1741,8 +1752,6 @@ void mmc_power_off(struct mmc_host *host)
        if (host->ios.power_mode == MMC_POWER_OFF)
                return;
 
-       mmc_host_clk_hold(host);
-
        mmc_pwrseq_power_off(host);
 
        host->ios.clock = 0;
@@ -1758,8 +1767,6 @@ void mmc_power_off(struct mmc_host *host)
         * can be successfully turned on again.
         */
        mmc_delay(1);
-
-       mmc_host_clk_release(host);
 }
 
 void mmc_power_cycle(struct mmc_host *host, u32 ocr)
@@ -1975,7 +1982,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
                 */
                timeout_clks <<= 1;
                timeout_us += (timeout_clks * 1000) /
-                             (mmc_host_clk_rate(card->host) / 1000);
+                             (card->host->ios.clock / 1000);
 
                erase_timeout = timeout_us / 1000;
 
@@ -2423,9 +2430,7 @@ static void mmc_hw_reset_for_init(struct mmc_host *host)
 {
        if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
                return;
-       mmc_host_clk_hold(host);
        host->ops->hw_reset(host);
-       mmc_host_clk_release(host);
 }
 
 int mmc_hw_reset(struct mmc_host *host)
@@ -2633,10 +2638,14 @@ void mmc_start_host(struct mmc_host *host)
        host->f_init = max(freqs[0], host->f_min);
        host->rescan_disable = 0;
        host->ios.power_mode = MMC_POWER_UNDEFINED;
+
+       mmc_claim_host(host);
        if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
                mmc_power_off(host);
        else
                mmc_power_up(host, host->ocr_avail);
+       mmc_release_host(host);
+
        mmc_gpiod_request_cd_irq(host);
        _mmc_detect_change(host, 0, false);
 }
@@ -2674,7 +2683,9 @@ void mmc_stop_host(struct mmc_host *host)
 
        BUG_ON(host->card);
 
+       mmc_claim_host(host);
        mmc_power_off(host);
+       mmc_release_host(host);
 }
 
 int mmc_power_save_host(struct mmc_host *host)