OSDN Git Service

Merge android-4.4.185 (14e1196) into msm-4.4
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / scsi / ufs / ufshcd.c
index 707da4a..433e93f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This code is based on drivers/scsi/ufs/ufshcd.c
  * Copyright (C) 2011-2013 Samsung India Software Operations
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  *
  * Authors:
  *     Santosh Yaraganavi <santosh.sy@samsung.com>
@@ -2380,7 +2380,8 @@ int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
        memcpy(&query_res->upiu_res, &lrbp->ucd_rsp_ptr->qr, QUERY_OSF_SIZE);
 
        /* Get the descriptor */
-       if (lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) {
+       if (hba->dev_cmd.query.descriptor &&
+           lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) {
                u8 *descp = (u8 *)lrbp->ucd_rsp_ptr +
                                GENERAL_UPIU_REQUEST_SIZE;
                u16 resp_len;
@@ -5611,7 +5612,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
                                        lrbp, cmd->request);
                        }
 
-                       clear_bit_unlock(index, &hba->lrb_in_use);
                        req = cmd->request;
                        if (req) {
                                /* Update IO svc time latency histogram */
@@ -7163,19 +7163,19 @@ static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba,
                goto out;
        }
 
-       if (hba->vreg_info.vcc)
+       if (hba->vreg_info.vcc && hba->vreg_info.vcc->max_uA)
                icc_level = ufshcd_get_max_icc_level(
                                hba->vreg_info.vcc->max_uA,
                                POWER_DESC_MAX_ACTV_ICC_LVLS - 1,
                                &desc_buf[PWR_DESC_ACTIVE_LVLS_VCC_0]);
 
-       if (hba->vreg_info.vccq)
+       if (hba->vreg_info.vccq && hba->vreg_info.vccq->max_uA)
                icc_level = ufshcd_get_max_icc_level(
                                hba->vreg_info.vccq->max_uA,
                                icc_level,
                                &desc_buf[PWR_DESC_ACTIVE_LVLS_VCCQ_0]);
 
-       if (hba->vreg_info.vccq2)
+       if (hba->vreg_info.vccq2 && hba->vreg_info.vccq2->max_uA)
                icc_level = ufshcd_get_max_icc_level(
                                hba->vreg_info.vccq2->max_uA,
                                icc_level,
@@ -7951,6 +7951,15 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
        if (!vreg)
                return 0;
 
+       /*
+        * "set_load" operation shall be required on those regulators
+        * which specifically configured current limitation. Otherwise
+        * zero max_uA may cause unexpected behavior when regulator is
+        * enabled or set as high power mode.
+        */
+       if (!vreg->max_uA)
+               return 0;
+
        ret = regulator_set_load(vreg->reg, ua);
        if (ret < 0) {
                dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n",
@@ -8002,12 +8011,15 @@ static int ufshcd_config_vreg(struct device *dev,
                if (ret)
                        goto out;
 
-               min_uV = on ? vreg->min_uV : 0;
-               ret = regulator_set_voltage(reg, min_uV, vreg->max_uV);
-               if (ret) {
-                       dev_err(dev, "%s: %s set voltage failed, err=%d\n",
+               if (vreg->min_uV && vreg->max_uV) {
+                       min_uV = on ? vreg->min_uV : 0;
+                       ret = regulator_set_voltage(reg, min_uV, vreg->max_uV);
+                       if (ret) {
+                               dev_err(dev,
+                                       "%s: %s set voltage failed, err=%d\n",
                                        __func__, name, ret);
-                       goto out;
+                               goto out;
+                       }
                }
        }
 out: