ufs: ufs-qcom: Defer ufs probe if phy drvdata is not initialized

During ufs probe, the phy drvdata is read to get
the phy version information. But in some rare cases,
the ufs driver tries to read it before the phy parameters
are fully initialized, which causes kernel panic.

So, defer the ufs probe if phy drvdata is not fully
initialized.

Call trace:
  ufs_qcom_phy_save_controller_version+0x4/0x18 [phy_qcom_ufs]
  ufshcd_variant_hba_init+0x40/0x98
  ufshcd_init+0x388/0xc64
  ufshcd_pltfrm_init+0x324/0x42c
  ufs_qcom_probe+0x108/0x248 [ufs_qcom]
  platform_probe+0xc0/0xec
  really_probe+0x190/0x384
  __driver_probe_device+0xa0/0x12c
  driver_probe_device+0x44/0x210
  __driver_attach+0x108/0x1d4
  bus_for_each_dev+0x98/0xe8
  driver_attach+0x24/0x34
  bus_add_driver+0x10c/0x1fc
  driver_register+0x78/0x118
  __platform_driver_register+0x24/0x34
  init_module+0x20/0xfe4 [ufs_qcom]
  do_one_initcall+0xdc/0x314
  do_init_module+0x48/0x1dc
  load_module+0x1348/0x152c
  __arm64_sys_finit_module+0xc0/0x110
  invoke_syscall+0x58/0x11c
  el0_svc_common+0xb4/0xf4
  do_el0_svc+0x2c/0xb0
  el0_svc+0x2c/0xa4
  el0t_64_sync_handler+0x68/0xb4
  el0t_64_sync+0x1a4/0x1a8
---[ end trace 0000000000000000 ]---.

Change-Id: Ia5783cdfed68d54a38340ca2234b6273c43b2b06
Signed-off-by: Ram Kumar Dwivedi <quic_rdwivedi@quicinc.com>
This commit is contained in:
Ram Kumar Dwivedi 2023-09-08 05:30:41 -07:00
parent 2f482f795f
commit b0b23bcbfd
3 changed files with 11 additions and 3 deletions

View File

@ -708,14 +708,18 @@ void ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
}
EXPORT_SYMBOL(ufs_qcom_phy_set_tx_lane_enable);
void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
int ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
u8 major, u16 minor, u16 step)
{
struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
if (!ufs_qcom_phy)
return -EPROBE_DEFER;
ufs_qcom_phy->host_ctrl_rev_major = major;
ufs_qcom_phy->host_ctrl_rev_minor = minor;
ufs_qcom_phy->host_ctrl_rev_step = step;
return 0;
}
EXPORT_SYMBOL(ufs_qcom_phy_save_controller_version);

View File

@ -3793,9 +3793,13 @@ static int ufs_qcom_init(struct ufs_hba *hba)
&host->vdd_hba_reg_nb);
/* update phy revision information before calling phy_init() */
ufs_qcom_phy_save_controller_version(host->generic_phy,
host->hw_ver.major, host->hw_ver.minor, host->hw_ver.step);
if (err == -EPROBE_DEFER) {
pr_err("%s: phy device probe is not completed yet\n",
__func__);
goto out_variant_clear;
}
err = ufs_qcom_parse_reg_info(host, "qcom,vddp-ref-clk",
&host->vddp_ref_clk);

View File

@ -16,7 +16,7 @@ void ufs_qcom_phy_dbg_register_dump(struct phy *generic_phy);
void ufs_qcom_phy_dbg_register_save(struct phy *generic_phy);
void ufs_qcom_phy_set_src_clk_h8_enter(struct phy *generic_phy);
void ufs_qcom_phy_set_src_clk_h8_exit(struct phy *generic_phy);
void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
int ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
u8 major, u16 minor, u16 step);
#endif /* PHY_QCOM_UFS_H_ */