Loading drivers/scsi/ufs/ufs-msm.c +73 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/platform_device.h> #include <linux/msm-bus.h> #include <soc/qcom/scm.h> #include "ufshcd.h" #include "unipro.h" Loading @@ -32,6 +33,7 @@ static int ufs_msm_get_speed_mode(struct ufs_pa_layer_attr *p, char *result); static int ufs_msm_get_bus_vote(struct ufs_msm_host *host, const char *speed_mode); static int ufs_msm_set_bus_vote(struct ufs_msm_host *host, int vote); static int ufs_msm_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg); static int ufs_msm_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes) { Loading Loading @@ -1060,6 +1062,9 @@ static int ufs_msm_init(struct ufs_hba *hba) hba->priv = (void *)host; /* restore the secure configuration */ ufs_msm_update_sec_cfg(hba, true); err = ufs_msm_bus_register(host); if (err) goto out_host_free; Loading Loading @@ -1115,6 +1120,73 @@ void ufs_msm_clk_scale_notify(struct ufs_hba *hba) dev_req_params->hs_rate); ufs_msm_update_bus_bw_vote(host); } /* * This function should be called to restore the security configuration of UFS * register space after coming out of UFS host core power collapse. * * @hba: host controller instance * @restore_sec_cfg: Set "true" if secure configuration needs to be restored * and set "false" when secure configuration is lost. */ static int ufs_msm_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg) { int ret = 0, scm_ret = 0; struct ufs_msm_host *host = hba->priv; /* scm command buffer structrue */ struct msm_scm_cmd_buf { unsigned int device_id; unsigned int spare; } cbuf; #define RESTORE_SEC_CFG_CMD 0x2 #define UFS_TZ_DEV_ID 19 if (!host || !hba->vreg_info.vdd_hba || !(host->sec_cfg_updated ^ restore_sec_cfg)) { return 0; } else if (!restore_sec_cfg) { /* * Clear the flag so next time when this function is called * with restore_sec_cfg set to true, we can restore the secure * configuration. */ host->sec_cfg_updated = false; goto out; } else if (hba->clk_gating.state != CLKS_ON) { /* * Clocks should be ON to restore the host controller secure * configuration. */ goto out; } /* * If we are here, Host controller clocks are running, Host controller * power collapse feature is supported and Host controller has just came * out of power collapse. */ cbuf.device_id = UFS_TZ_DEV_ID; ret = scm_call(SCM_SVC_MP, RESTORE_SEC_CFG_CMD, &cbuf, sizeof(cbuf), &scm_ret, sizeof(scm_ret)); if (ret || scm_ret) { dev_err(hba->dev, "%s: failed, ret %d scm_ret %d\n", __func__, ret, scm_ret); if (!ret) ret = scm_ret; } else { host->sec_cfg_updated = true; } out: dev_dbg(hba->dev, "%s: ip: restore_sec_cfg %d, op: restore_sec_cfg %d, ret %d scm_ret %d\n", __func__, restore_sec_cfg, host->sec_cfg_updated, ret, scm_ret); return ret; } /** * struct ufs_hba_msm_vops - UFS MSM specific variant operations * Loading @@ -1132,5 +1204,6 @@ const struct ufs_hba_variant_ops ufs_hba_msm_vops = { .pwr_change_notify = ufs_msm_pwr_change_notify, .suspend = ufs_msm_suspend, .resume = ufs_msm_resume, .update_sec_cfg = ufs_msm_update_sec_cfg, }; EXPORT_SYMBOL(ufs_hba_msm_vops); drivers/scsi/ufs/ufs-msm.h +1 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ struct ufs_msm_host { struct clk *rx_l1_sync_clk; struct clk *tx_l1_sync_clk; bool is_lane_clks_enabled; bool sec_cfg_updated; }; #define ufs_msm_is_link_off(hba) ufshcd_is_link_off(hba) Loading drivers/scsi/ufs/ufshcd.c +12 −4 Original line number Diff line number Diff line Loading @@ -5252,12 +5252,17 @@ out: static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on) { int ret = 0; struct ufs_vreg_info *info = &hba->vreg_info; if (info) return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); else return 0; if (info->vdd_hba) { ret = ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); if (!ret && hba->vops->update_sec_cfg) hba->vops->update_sec_cfg(hba, on); } return ret; } static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) Loading Loading @@ -5356,6 +5361,9 @@ out: ufschd_clk_gating_state_to_string( hba->clk_gating.state)); spin_unlock_irqrestore(hba->host->host_lock, flags); /* restore the secure configuration as clocks are enabled */ if (hba->vops->update_sec_cfg) hba->vops->update_sec_cfg(hba, true); } return ret; } Loading drivers/scsi/ufs/ufshcd.h +2 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ struct ufs_pwr_mode_info { * to be set. * @suspend: called during host controller PM callback * @resume: called during host controller PM callback * @update_sec_cfg: called to restore host controller secure configuration */ struct ufs_hba_variant_ops { const char *name; Loading @@ -329,6 +330,7 @@ struct ufs_hba_variant_ops { struct ufs_pa_layer_attr *); int (*suspend)(struct ufs_hba *, enum ufs_pm_op); int (*resume)(struct ufs_hba *, enum ufs_pm_op); int (*update_sec_cfg)(struct ufs_hba *hba, bool restore_sec_cfg); }; /* clock gating state */ Loading Loading
drivers/scsi/ufs/ufs-msm.c +73 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/platform_device.h> #include <linux/msm-bus.h> #include <soc/qcom/scm.h> #include "ufshcd.h" #include "unipro.h" Loading @@ -32,6 +33,7 @@ static int ufs_msm_get_speed_mode(struct ufs_pa_layer_attr *p, char *result); static int ufs_msm_get_bus_vote(struct ufs_msm_host *host, const char *speed_mode); static int ufs_msm_set_bus_vote(struct ufs_msm_host *host, int vote); static int ufs_msm_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg); static int ufs_msm_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes) { Loading Loading @@ -1060,6 +1062,9 @@ static int ufs_msm_init(struct ufs_hba *hba) hba->priv = (void *)host; /* restore the secure configuration */ ufs_msm_update_sec_cfg(hba, true); err = ufs_msm_bus_register(host); if (err) goto out_host_free; Loading Loading @@ -1115,6 +1120,73 @@ void ufs_msm_clk_scale_notify(struct ufs_hba *hba) dev_req_params->hs_rate); ufs_msm_update_bus_bw_vote(host); } /* * This function should be called to restore the security configuration of UFS * register space after coming out of UFS host core power collapse. * * @hba: host controller instance * @restore_sec_cfg: Set "true" if secure configuration needs to be restored * and set "false" when secure configuration is lost. */ static int ufs_msm_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg) { int ret = 0, scm_ret = 0; struct ufs_msm_host *host = hba->priv; /* scm command buffer structrue */ struct msm_scm_cmd_buf { unsigned int device_id; unsigned int spare; } cbuf; #define RESTORE_SEC_CFG_CMD 0x2 #define UFS_TZ_DEV_ID 19 if (!host || !hba->vreg_info.vdd_hba || !(host->sec_cfg_updated ^ restore_sec_cfg)) { return 0; } else if (!restore_sec_cfg) { /* * Clear the flag so next time when this function is called * with restore_sec_cfg set to true, we can restore the secure * configuration. */ host->sec_cfg_updated = false; goto out; } else if (hba->clk_gating.state != CLKS_ON) { /* * Clocks should be ON to restore the host controller secure * configuration. */ goto out; } /* * If we are here, Host controller clocks are running, Host controller * power collapse feature is supported and Host controller has just came * out of power collapse. */ cbuf.device_id = UFS_TZ_DEV_ID; ret = scm_call(SCM_SVC_MP, RESTORE_SEC_CFG_CMD, &cbuf, sizeof(cbuf), &scm_ret, sizeof(scm_ret)); if (ret || scm_ret) { dev_err(hba->dev, "%s: failed, ret %d scm_ret %d\n", __func__, ret, scm_ret); if (!ret) ret = scm_ret; } else { host->sec_cfg_updated = true; } out: dev_dbg(hba->dev, "%s: ip: restore_sec_cfg %d, op: restore_sec_cfg %d, ret %d scm_ret %d\n", __func__, restore_sec_cfg, host->sec_cfg_updated, ret, scm_ret); return ret; } /** * struct ufs_hba_msm_vops - UFS MSM specific variant operations * Loading @@ -1132,5 +1204,6 @@ const struct ufs_hba_variant_ops ufs_hba_msm_vops = { .pwr_change_notify = ufs_msm_pwr_change_notify, .suspend = ufs_msm_suspend, .resume = ufs_msm_resume, .update_sec_cfg = ufs_msm_update_sec_cfg, }; EXPORT_SYMBOL(ufs_hba_msm_vops);
drivers/scsi/ufs/ufs-msm.h +1 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ struct ufs_msm_host { struct clk *rx_l1_sync_clk; struct clk *tx_l1_sync_clk; bool is_lane_clks_enabled; bool sec_cfg_updated; }; #define ufs_msm_is_link_off(hba) ufshcd_is_link_off(hba) Loading
drivers/scsi/ufs/ufshcd.c +12 −4 Original line number Diff line number Diff line Loading @@ -5252,12 +5252,17 @@ out: static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on) { int ret = 0; struct ufs_vreg_info *info = &hba->vreg_info; if (info) return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); else return 0; if (info->vdd_hba) { ret = ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); if (!ret && hba->vops->update_sec_cfg) hba->vops->update_sec_cfg(hba, on); } return ret; } static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) Loading Loading @@ -5356,6 +5361,9 @@ out: ufschd_clk_gating_state_to_string( hba->clk_gating.state)); spin_unlock_irqrestore(hba->host->host_lock, flags); /* restore the secure configuration as clocks are enabled */ if (hba->vops->update_sec_cfg) hba->vops->update_sec_cfg(hba, true); } return ret; } Loading
drivers/scsi/ufs/ufshcd.h +2 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ struct ufs_pwr_mode_info { * to be set. * @suspend: called during host controller PM callback * @resume: called during host controller PM callback * @update_sec_cfg: called to restore host controller secure configuration */ struct ufs_hba_variant_ops { const char *name; Loading @@ -329,6 +330,7 @@ struct ufs_hba_variant_ops { struct ufs_pa_layer_attr *); int (*suspend)(struct ufs_hba *, enum ufs_pm_op); int (*resume)(struct ufs_hba *, enum ufs_pm_op); int (*update_sec_cfg)(struct ufs_hba *hba, bool restore_sec_cfg); }; /* clock gating state */ Loading