diff options
author | Maya Erez <merez@codeaurora.org> | 2014-12-12 20:45:08 +0200 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 10:58:24 -0700 |
commit | 1fd1c6a6970c8d44a0e29463e9a8d378ec9bea84 (patch) | |
tree | fb02e68b8152bde82347a624b90955a7bd02eadc /drivers | |
parent | 8a03efed539ba899f8a6d54b901800609e4613ab (diff) |
scsi: ufs: perform ice_init as part of UFS initialization
ice_init may need UFS clocks to be enabled in order to allow
enabling ICE as part of its initialization. To allow that,
ice_init should be done as part of UFS initialization sequence.
In such a case ice_reset is no longer needed to be called as part of
UFS initialization and should be moved to host reset scenarios.
Change-Id: Iaa851083a9f73045c7ca02d69dd65b3a00b85bff
Signed-off-by: Maya Erez <merez@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/ufs/ufs-qcom-ice.c | 7 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufs-qcom.c | 40 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 15 |
3 files changed, 45 insertions, 17 deletions
diff --git a/drivers/scsi/ufs/ufs-qcom-ice.c b/drivers/scsi/ufs/ufs-qcom-ice.c index 2ade16d5ef1f..09ccd7cf145a 100644 --- a/drivers/scsi/ufs/ufs-qcom-ice.c +++ b/drivers/scsi/ufs/ufs-qcom-ice.c @@ -362,6 +362,13 @@ int ufs_qcom_ice_reset(struct ufs_qcom_host *qcom_host) err = -ETIMEDOUT; } + if (qcom_host->ice.state != UFS_QCOM_ICE_STATE_ACTIVE) { + dev_err(qcom_host->hba->dev, + "%s: error. ice.state (%d) is not in active state\n", + __func__, qcom_host->ice.state); + err = -EINVAL; + } + out: return err; } diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index cb7a32f6ce9f..9cbbc51793f2 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -323,18 +323,20 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba, bool status) * is initialized. */ err = ufs_qcom_enable_lane_clks(host); + if (!err && host->ice.pdev) { + err = ufs_qcom_ice_init(host); + if (err) { + dev_err(hba->dev, "%s: ICE init failed (%d)\n", + __func__, err); + err = -EINVAL; + } + } + break; case POST_CHANGE: /* check if UFS PHY moved from DISABLED to HIBERN8 */ err = ufs_qcom_check_hibern8(hba); ufs_qcom_enable_hw_clk_gating(hba); - if (!err) { - err = ufs_qcom_ice_reset(host); - if (err) - dev_err(hba->dev, - "%s: ufs_qcom_ice_reset() failed %d\n", - __func__, err); - } break; default: @@ -590,6 +592,20 @@ out: return err; } +static +int ufs_qcom_crytpo_engine_reset(struct ufs_hba *hba) +{ + struct ufs_qcom_host *host = hba->priv; + int err = 0; + + if (!host->ice.pdev) + goto out; + + err = ufs_qcom_ice_reset(host); +out: + return err; +} + static int ufs_qcom_crypto_engine_eh(struct ufs_hba *hba) { struct ufs_qcom_host *host = hba->priv; @@ -1185,15 +1201,6 @@ static int ufs_qcom_init(struct ufs_hba *hba) hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND; hba->caps |= UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE; ufs_qcom_setup_clocks(hba, true); - if (host->ice.pdev) { - err = ufs_qcom_ice_init(host); - if (err) { - dev_err(dev, "%s: ICE driver initialization failed (%d)\n", - __func__, err); - device_remove_file(dev, &host->bus_vote.max_bus_bw); - goto out_disable_phy; - } - } if (hba->dev->id < MAX_UFS_QCOM_HOSTS) ufs_qcom_hosts[hba->dev->id] = host; @@ -1362,6 +1369,7 @@ const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { .update_sec_cfg = ufs_qcom_update_sec_cfg, .dbg_register_dump = ufs_qcom_dump_dbg_regs, .crypto_engine_cfg = ufs_qcom_crytpo_engine_cfg, + .crypto_engine_reset = ufs_qcom_crytpo_engine_reset, .crypto_engine_eh = ufs_qcom_crypto_engine_eh, .crypto_engine_get_err = ufs_qcom_crypto_engine_get_err, .crypto_engine_reset_err = ufs_qcom_crypto_engine_reset_err, diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a12e85a3855d..ccf1718e01c7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5826,8 +5826,21 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) /* Establish the link again and restore the device */ err = ufshcd_probe_hba(hba); - if (!err && (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)) + if (!err && (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)) { err = -EIO; + goto out; + } + + if (hba->vops->crypto_engine_reset) { + err = hba->vops->crypto_engine_reset(hba); + if (err) { + dev_err(hba->dev, + "%s: failed to reset crypto engine %d\n", + __func__, err); + goto out; + } + } + out: if (err) dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err); |