Loading drivers/scsi/ufs/ufs-msm-phy-qmp-20nm.c +26 −51 Original line number Diff line number Diff line Loading @@ -30,36 +30,27 @@ #define UFS_PHY_NAME "ufs_msm_phy_qmp_20nm" static void ufs_msm_phy_qmp_20nm_phy_calibrate(struct ufs_msm_phy *phy) static int ufs_msm_phy_qmp_20nm_phy_calibrate(struct ufs_msm_phy *ufs_msm_phy) { struct ufs_msm_phy_calibration *tbl; int tbl_size; int i; struct ufs_msm_phy_calibration *tbl_A, *tbl_B; int tbl_size_A, tbl_size_B; int rate = UFS_MSM_LIMIT_HS_RATE; int err; tbl_size = ARRAY_SIZE(phy_cal_table_rate_A); tbl = phy_cal_table_rate_A; tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A); tbl_A = phy_cal_table_rate_A; /* * calibration according phy_cal_table_rate_A happens * regardless of the rate we intend to work with. * Only in case we would like to work in rate B, we need * to override a subset of registers of phy_cal_table_rate_A * table, with phy_cal_table_rate_B table. */ for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, phy->mmio + tbl[i].reg_offset); tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B); tbl_B = phy_cal_table_rate_B; if (UFS_MSM_LIMIT_HS_RATE == PA_HS_MODE_B) { tbl = phy_cal_table_rate_B; tbl_size = ARRAY_SIZE(phy_cal_table_rate_B); err = ufs_msm_phy_calibrate(ufs_msm_phy, tbl_A, tbl_size_A, tbl_B, tbl_size_B, rate); for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, phy->mmio + tbl[i].reg_offset); } if (err) dev_err(ufs_msm_phy->dev, "%s: ufs_msm_phy_calibrate() failed %d\n", __func__, err); /* flush buffered writes */ mb(); return err; } static int ufs_msm_phy_qmp_20nm_init(struct phy *generic_phy) Loading Loading @@ -192,7 +183,6 @@ static int ufs_msm_phy_qmp_20nm_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy *generic_phy; struct ufs_msm_phy_qmp_20nm *phy; struct phy_provider *phy_provider; int err = 0; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); Loading @@ -202,31 +192,16 @@ static int ufs_msm_phy_qmp_20nm_probe(struct platform_device *pdev) goto out; } err = ufs_msm_phy_base_init(pdev, &phy->common_cfg); if (err) { dev_err(dev, "%s: phy base init failed %d\n", __func__, err); goto out; } phy->common_cfg.phy_spec_ops = &phy_20nm_ops; phy->common_cfg.cached_regs = NULL; phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { err = PTR_ERR(phy_provider); dev_err(dev, "%s: failed to register phy %d\n", __func__, err); goto out; } generic_phy = ufs_msm_phy_generic_probe(pdev, &phy->common_cfg, &ufs_msm_phy_qmp_20nm_phy_ops, &phy_20nm_ops); generic_phy = devm_phy_create(dev, &ufs_msm_phy_qmp_20nm_phy_ops, NULL); if (IS_ERR(generic_phy)) { devm_of_phy_provider_unregister(dev, phy_provider); err = PTR_ERR(generic_phy); dev_err(dev, "%s: failed to create phy %d\n", __func__, err); if (!generic_phy) { dev_err(dev, "%s: ufs_msm_phy_generic_probe() failed\n", __func__); err = -EIO; goto out; } phy->common_cfg.dev = dev; phy_set_drvdata(generic_phy, phy); strlcpy(phy->common_cfg.name, UFS_PHY_NAME, Loading drivers/scsi/ufs/ufs-msm-phy-qmp-28nm.c +26 −50 Original line number Diff line number Diff line Loading @@ -97,46 +97,34 @@ out: return err; } static void ufs_msm_phy_qmp_28nm_calibrate(struct ufs_msm_phy *ufs_msm_phy) static int ufs_msm_phy_qmp_28nm_calibrate(struct ufs_msm_phy *ufs_msm_phy) { struct ufs_msm_phy_calibration *tbl; int tbl_size; int i; struct ufs_msm_phy_calibration *tbl_A, *tbl_B; int tbl_size_A, tbl_size_B; int rate = UFS_MSM_LIMIT_HS_RATE; u8 major = ufs_msm_phy->host_ctrl_rev_major; u16 minor = ufs_msm_phy->host_ctrl_rev_minor; u16 step = ufs_msm_phy->host_ctrl_rev_step; int err; if ((major == 0x1) && (minor == 0x001) && (step == 0x0000)) { tbl_size = ARRAY_SIZE(phy_cal_table_ctrl_1_1_0_rate_A); tbl = phy_cal_table_ctrl_1_1_0_rate_A; tbl_size_A = ARRAY_SIZE(phy_cal_table_ctrl_1_1_0_rate_A); tbl_A = phy_cal_table_ctrl_1_1_0_rate_A; } else if ((major == 0x1) && (minor == 0x001) && (step == 0x0001)) { tbl_size = ARRAY_SIZE(phy_cal_table_ctrl_1_1_1_rate_A); tbl = phy_cal_table_ctrl_1_1_1_rate_A; tbl_size_A = ARRAY_SIZE(phy_cal_table_ctrl_1_1_1_rate_A); tbl_A = phy_cal_table_ctrl_1_1_1_rate_A; } /* * calibration according phy_cal_table_ctrl_x_x_x_rate_A * happens regardless of the rate we intend to work with. * Only in case we would like to work in rate B, we need * to override a subset of registers of * phy_cal_table_ctrl_x_x_x_rate_A table, with phy_cal_table_rate_B * table. */ for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, ufs_msm_phy->mmio + tbl[i].reg_offset); if (UFS_MSM_LIMIT_HS_RATE == PA_HS_MODE_B) { tbl = phy_cal_table_rate_B; tbl_size = ARRAY_SIZE(phy_cal_table_rate_B); tbl_B = phy_cal_table_rate_B; tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B); for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, ufs_msm_phy->mmio + tbl[i].reg_offset); } err = ufs_msm_phy_calibrate(ufs_msm_phy, tbl_A, tbl_size_A, tbl_B, tbl_size_B, rate); if (err) dev_err(ufs_msm_phy->dev, "%s: ufs_msm_phy_calibrate() failed %d\n", __func__, err); /* flush buffered writes */ mb(); return err; } static Loading Loading @@ -286,7 +274,7 @@ static int ufs_msm_phy_qmp_28nm_resume(struct phy *generic_phy) return err; } struct phy_ops ufs_msm_phy_ops = { struct phy_ops ufs_msm_phy_qmp_28nm_phy_ops = { .init = ufs_msm_phy_qmp_28nm_init, .exit = ufs_msm_phy_exit, .power_on = ufs_msm_phy_power_on, Loading @@ -312,7 +300,6 @@ static int ufs_msm_phy_qmp_28nm_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int err = 0; struct phy *generic_phy; struct phy_provider *phy_provider; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) { Loading @@ -321,37 +308,26 @@ static int ufs_msm_phy_qmp_28nm_probe(struct platform_device *pdev) goto out; } err = ufs_msm_phy_base_init(pdev, &phy->common_cfg); if (err) { dev_err(dev, "%s: phy base init failed %d\n", __func__, err); goto out; } phy->common_cfg.phy_spec_ops = &phy_28nm_ops; phy->common_cfg.cached_regs = (struct ufs_msm_phy_calibration *)cached_phy_regs; phy->common_cfg.cached_regs_table_size = ARRAY_SIZE(cached_phy_regs); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { err = PTR_ERR(phy_provider); dev_err(dev, "%s: failed to register phy %d\n", __func__, err); goto out; } generic_phy = ufs_msm_phy_generic_probe(pdev, &phy->common_cfg, &ufs_msm_phy_qmp_28nm_phy_ops, &phy_28nm_ops); generic_phy = devm_phy_create(dev, &ufs_msm_phy_ops, NULL); if (IS_ERR(generic_phy)) { err = PTR_ERR(generic_phy); dev_err(dev, "%s: failed to create phy %d\n", __func__, err); if (!generic_phy) { dev_err(dev, "%s: ufs_msm_phy_generic_probe() failed\n", __func__); err = -EIO; goto out; } phy->common_cfg.dev = dev; phy_set_drvdata(generic_phy, phy); strlcpy(phy->common_cfg.name, UFS_PHY_NAME, sizeof(phy->common_cfg.name)); out: return err; } Loading drivers/scsi/ufs/ufs-msm-phy.c +85 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,87 @@ #include "ufs-msm.h" #include "ufs-msm-phy.h" int ufs_msm_phy_calibrate(struct ufs_msm_phy *ufs_msm_phy, struct ufs_msm_phy_calibration *tbl_A, int tbl_size_A, struct ufs_msm_phy_calibration *tbl_B, int tbl_size_B, int rate) { int i; int ret = 0; if (!tbl_A) { dev_err(ufs_msm_phy->dev, "%s: tbl_A is NULL", __func__); ret = EINVAL; goto out; } for (i = 0; i < tbl_size_A; i++) writel_relaxed(tbl_A[i].cfg_value, ufs_msm_phy->mmio + tbl_A[i].reg_offset); /* * In case we would like to work in rate B, we need * to override a registers that were configured in rate A table * with registers of rate B table. * table. */ if (rate == PA_HS_MODE_B) { if (!tbl_B) { dev_err(ufs_msm_phy->dev, "%s: tbl_B is NULL", __func__); ret = EINVAL; goto out; } for (i = 0; i < tbl_size_B; i++) writel_relaxed(tbl_B[i].cfg_value, ufs_msm_phy->mmio + tbl_B[i].reg_offset); } /* flush buffered writes */ mb(); out: return ret; } struct phy *ufs_msm_phy_generic_probe(struct platform_device *pdev, struct ufs_msm_phy *common_cfg, struct phy_ops *ufs_msm_phy_gen_ops, struct ufs_msm_phy_specific_ops *phy_spec_ops) { int err; struct device *dev = &pdev->dev; struct phy *generic_phy = NULL; struct phy_provider *phy_provider; err = ufs_msm_phy_base_init(pdev, common_cfg); if (err) { dev_err(dev, "%s: phy base init failed %d\n", __func__, err); goto out; } phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { err = PTR_ERR(phy_provider); dev_err(dev, "%s: failed to register phy %d\n", __func__, err); goto out; } generic_phy = devm_phy_create(dev, ufs_msm_phy_gen_ops, NULL); if (IS_ERR(generic_phy)) { err = PTR_ERR(generic_phy); dev_err(dev, "%s: failed to create phy %d\n", __func__, err); goto out; } common_cfg->phy_spec_ops = phy_spec_ops; common_cfg->dev = dev; out: return generic_phy; } /* * This assumes the embedded phy structure inside generic_phy is of type * struct ufs_msm_phy. In order to function properly it's crucial Loading Loading @@ -447,8 +528,10 @@ int ufs_msm_phy_calibrate_phy(struct phy *generic_phy) __func__); ret = -ENOTSUPP; } else { ufs_msm_phy->phy_spec_ops-> ret = ufs_msm_phy->phy_spec_ops-> calibrate_phy(ufs_msm_phy); dev_err(ufs_msm_phy->dev, "%s: calibrate_phy() failed %d\n", __func__, ret); } return ret; Loading drivers/scsi/ufs/ufs-msm-phy.h +9 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ struct ufs_msm_phy { * and writes to QSERDES_RX_SIGDET_CNTRL attribute */ struct ufs_msm_phy_specific_ops { void (*calibrate_phy) (struct ufs_msm_phy *phy); int (*calibrate_phy) (struct ufs_msm_phy *phy); void (*start_serdes) (struct ufs_msm_phy *phy); void (*save_configuration)(struct ufs_msm_phy *phy); int (*is_physical_coding_sublayer_ready) (struct ufs_msm_phy *phy); Loading Loading @@ -173,4 +173,12 @@ int ufs_msm_phy_init_vregulators(struct phy *generic_phy, struct ufs_msm_phy *phy_common); int ufs_msm_phy_remove(struct phy *generic_phy, struct ufs_msm_phy *ufs_msm_phy); struct phy *ufs_msm_phy_generic_probe(struct platform_device *pdev, struct ufs_msm_phy *common_cfg, struct phy_ops *ufs_msm_phy_gen_ops, struct ufs_msm_phy_specific_ops *phy_spec_ops); int ufs_msm_phy_calibrate(struct ufs_msm_phy *ufs_msm_phy, struct ufs_msm_phy_calibration *tbl_A, int tbl_size_A, struct ufs_msm_phy_calibration *tbl_B, int tbl_size_B, int rate); #endif Loading
drivers/scsi/ufs/ufs-msm-phy-qmp-20nm.c +26 −51 Original line number Diff line number Diff line Loading @@ -30,36 +30,27 @@ #define UFS_PHY_NAME "ufs_msm_phy_qmp_20nm" static void ufs_msm_phy_qmp_20nm_phy_calibrate(struct ufs_msm_phy *phy) static int ufs_msm_phy_qmp_20nm_phy_calibrate(struct ufs_msm_phy *ufs_msm_phy) { struct ufs_msm_phy_calibration *tbl; int tbl_size; int i; struct ufs_msm_phy_calibration *tbl_A, *tbl_B; int tbl_size_A, tbl_size_B; int rate = UFS_MSM_LIMIT_HS_RATE; int err; tbl_size = ARRAY_SIZE(phy_cal_table_rate_A); tbl = phy_cal_table_rate_A; tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A); tbl_A = phy_cal_table_rate_A; /* * calibration according phy_cal_table_rate_A happens * regardless of the rate we intend to work with. * Only in case we would like to work in rate B, we need * to override a subset of registers of phy_cal_table_rate_A * table, with phy_cal_table_rate_B table. */ for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, phy->mmio + tbl[i].reg_offset); tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B); tbl_B = phy_cal_table_rate_B; if (UFS_MSM_LIMIT_HS_RATE == PA_HS_MODE_B) { tbl = phy_cal_table_rate_B; tbl_size = ARRAY_SIZE(phy_cal_table_rate_B); err = ufs_msm_phy_calibrate(ufs_msm_phy, tbl_A, tbl_size_A, tbl_B, tbl_size_B, rate); for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, phy->mmio + tbl[i].reg_offset); } if (err) dev_err(ufs_msm_phy->dev, "%s: ufs_msm_phy_calibrate() failed %d\n", __func__, err); /* flush buffered writes */ mb(); return err; } static int ufs_msm_phy_qmp_20nm_init(struct phy *generic_phy) Loading Loading @@ -192,7 +183,6 @@ static int ufs_msm_phy_qmp_20nm_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy *generic_phy; struct ufs_msm_phy_qmp_20nm *phy; struct phy_provider *phy_provider; int err = 0; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); Loading @@ -202,31 +192,16 @@ static int ufs_msm_phy_qmp_20nm_probe(struct platform_device *pdev) goto out; } err = ufs_msm_phy_base_init(pdev, &phy->common_cfg); if (err) { dev_err(dev, "%s: phy base init failed %d\n", __func__, err); goto out; } phy->common_cfg.phy_spec_ops = &phy_20nm_ops; phy->common_cfg.cached_regs = NULL; phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { err = PTR_ERR(phy_provider); dev_err(dev, "%s: failed to register phy %d\n", __func__, err); goto out; } generic_phy = ufs_msm_phy_generic_probe(pdev, &phy->common_cfg, &ufs_msm_phy_qmp_20nm_phy_ops, &phy_20nm_ops); generic_phy = devm_phy_create(dev, &ufs_msm_phy_qmp_20nm_phy_ops, NULL); if (IS_ERR(generic_phy)) { devm_of_phy_provider_unregister(dev, phy_provider); err = PTR_ERR(generic_phy); dev_err(dev, "%s: failed to create phy %d\n", __func__, err); if (!generic_phy) { dev_err(dev, "%s: ufs_msm_phy_generic_probe() failed\n", __func__); err = -EIO; goto out; } phy->common_cfg.dev = dev; phy_set_drvdata(generic_phy, phy); strlcpy(phy->common_cfg.name, UFS_PHY_NAME, Loading
drivers/scsi/ufs/ufs-msm-phy-qmp-28nm.c +26 −50 Original line number Diff line number Diff line Loading @@ -97,46 +97,34 @@ out: return err; } static void ufs_msm_phy_qmp_28nm_calibrate(struct ufs_msm_phy *ufs_msm_phy) static int ufs_msm_phy_qmp_28nm_calibrate(struct ufs_msm_phy *ufs_msm_phy) { struct ufs_msm_phy_calibration *tbl; int tbl_size; int i; struct ufs_msm_phy_calibration *tbl_A, *tbl_B; int tbl_size_A, tbl_size_B; int rate = UFS_MSM_LIMIT_HS_RATE; u8 major = ufs_msm_phy->host_ctrl_rev_major; u16 minor = ufs_msm_phy->host_ctrl_rev_minor; u16 step = ufs_msm_phy->host_ctrl_rev_step; int err; if ((major == 0x1) && (minor == 0x001) && (step == 0x0000)) { tbl_size = ARRAY_SIZE(phy_cal_table_ctrl_1_1_0_rate_A); tbl = phy_cal_table_ctrl_1_1_0_rate_A; tbl_size_A = ARRAY_SIZE(phy_cal_table_ctrl_1_1_0_rate_A); tbl_A = phy_cal_table_ctrl_1_1_0_rate_A; } else if ((major == 0x1) && (minor == 0x001) && (step == 0x0001)) { tbl_size = ARRAY_SIZE(phy_cal_table_ctrl_1_1_1_rate_A); tbl = phy_cal_table_ctrl_1_1_1_rate_A; tbl_size_A = ARRAY_SIZE(phy_cal_table_ctrl_1_1_1_rate_A); tbl_A = phy_cal_table_ctrl_1_1_1_rate_A; } /* * calibration according phy_cal_table_ctrl_x_x_x_rate_A * happens regardless of the rate we intend to work with. * Only in case we would like to work in rate B, we need * to override a subset of registers of * phy_cal_table_ctrl_x_x_x_rate_A table, with phy_cal_table_rate_B * table. */ for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, ufs_msm_phy->mmio + tbl[i].reg_offset); if (UFS_MSM_LIMIT_HS_RATE == PA_HS_MODE_B) { tbl = phy_cal_table_rate_B; tbl_size = ARRAY_SIZE(phy_cal_table_rate_B); tbl_B = phy_cal_table_rate_B; tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B); for (i = 0; i < tbl_size; i++) writel_relaxed(tbl[i].cfg_value, ufs_msm_phy->mmio + tbl[i].reg_offset); } err = ufs_msm_phy_calibrate(ufs_msm_phy, tbl_A, tbl_size_A, tbl_B, tbl_size_B, rate); if (err) dev_err(ufs_msm_phy->dev, "%s: ufs_msm_phy_calibrate() failed %d\n", __func__, err); /* flush buffered writes */ mb(); return err; } static Loading Loading @@ -286,7 +274,7 @@ static int ufs_msm_phy_qmp_28nm_resume(struct phy *generic_phy) return err; } struct phy_ops ufs_msm_phy_ops = { struct phy_ops ufs_msm_phy_qmp_28nm_phy_ops = { .init = ufs_msm_phy_qmp_28nm_init, .exit = ufs_msm_phy_exit, .power_on = ufs_msm_phy_power_on, Loading @@ -312,7 +300,6 @@ static int ufs_msm_phy_qmp_28nm_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int err = 0; struct phy *generic_phy; struct phy_provider *phy_provider; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) { Loading @@ -321,37 +308,26 @@ static int ufs_msm_phy_qmp_28nm_probe(struct platform_device *pdev) goto out; } err = ufs_msm_phy_base_init(pdev, &phy->common_cfg); if (err) { dev_err(dev, "%s: phy base init failed %d\n", __func__, err); goto out; } phy->common_cfg.phy_spec_ops = &phy_28nm_ops; phy->common_cfg.cached_regs = (struct ufs_msm_phy_calibration *)cached_phy_regs; phy->common_cfg.cached_regs_table_size = ARRAY_SIZE(cached_phy_regs); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { err = PTR_ERR(phy_provider); dev_err(dev, "%s: failed to register phy %d\n", __func__, err); goto out; } generic_phy = ufs_msm_phy_generic_probe(pdev, &phy->common_cfg, &ufs_msm_phy_qmp_28nm_phy_ops, &phy_28nm_ops); generic_phy = devm_phy_create(dev, &ufs_msm_phy_ops, NULL); if (IS_ERR(generic_phy)) { err = PTR_ERR(generic_phy); dev_err(dev, "%s: failed to create phy %d\n", __func__, err); if (!generic_phy) { dev_err(dev, "%s: ufs_msm_phy_generic_probe() failed\n", __func__); err = -EIO; goto out; } phy->common_cfg.dev = dev; phy_set_drvdata(generic_phy, phy); strlcpy(phy->common_cfg.name, UFS_PHY_NAME, sizeof(phy->common_cfg.name)); out: return err; } Loading
drivers/scsi/ufs/ufs-msm-phy.c +85 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,87 @@ #include "ufs-msm.h" #include "ufs-msm-phy.h" int ufs_msm_phy_calibrate(struct ufs_msm_phy *ufs_msm_phy, struct ufs_msm_phy_calibration *tbl_A, int tbl_size_A, struct ufs_msm_phy_calibration *tbl_B, int tbl_size_B, int rate) { int i; int ret = 0; if (!tbl_A) { dev_err(ufs_msm_phy->dev, "%s: tbl_A is NULL", __func__); ret = EINVAL; goto out; } for (i = 0; i < tbl_size_A; i++) writel_relaxed(tbl_A[i].cfg_value, ufs_msm_phy->mmio + tbl_A[i].reg_offset); /* * In case we would like to work in rate B, we need * to override a registers that were configured in rate A table * with registers of rate B table. * table. */ if (rate == PA_HS_MODE_B) { if (!tbl_B) { dev_err(ufs_msm_phy->dev, "%s: tbl_B is NULL", __func__); ret = EINVAL; goto out; } for (i = 0; i < tbl_size_B; i++) writel_relaxed(tbl_B[i].cfg_value, ufs_msm_phy->mmio + tbl_B[i].reg_offset); } /* flush buffered writes */ mb(); out: return ret; } struct phy *ufs_msm_phy_generic_probe(struct platform_device *pdev, struct ufs_msm_phy *common_cfg, struct phy_ops *ufs_msm_phy_gen_ops, struct ufs_msm_phy_specific_ops *phy_spec_ops) { int err; struct device *dev = &pdev->dev; struct phy *generic_phy = NULL; struct phy_provider *phy_provider; err = ufs_msm_phy_base_init(pdev, common_cfg); if (err) { dev_err(dev, "%s: phy base init failed %d\n", __func__, err); goto out; } phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { err = PTR_ERR(phy_provider); dev_err(dev, "%s: failed to register phy %d\n", __func__, err); goto out; } generic_phy = devm_phy_create(dev, ufs_msm_phy_gen_ops, NULL); if (IS_ERR(generic_phy)) { err = PTR_ERR(generic_phy); dev_err(dev, "%s: failed to create phy %d\n", __func__, err); goto out; } common_cfg->phy_spec_ops = phy_spec_ops; common_cfg->dev = dev; out: return generic_phy; } /* * This assumes the embedded phy structure inside generic_phy is of type * struct ufs_msm_phy. In order to function properly it's crucial Loading Loading @@ -447,8 +528,10 @@ int ufs_msm_phy_calibrate_phy(struct phy *generic_phy) __func__); ret = -ENOTSUPP; } else { ufs_msm_phy->phy_spec_ops-> ret = ufs_msm_phy->phy_spec_ops-> calibrate_phy(ufs_msm_phy); dev_err(ufs_msm_phy->dev, "%s: calibrate_phy() failed %d\n", __func__, ret); } return ret; Loading
drivers/scsi/ufs/ufs-msm-phy.h +9 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ struct ufs_msm_phy { * and writes to QSERDES_RX_SIGDET_CNTRL attribute */ struct ufs_msm_phy_specific_ops { void (*calibrate_phy) (struct ufs_msm_phy *phy); int (*calibrate_phy) (struct ufs_msm_phy *phy); void (*start_serdes) (struct ufs_msm_phy *phy); void (*save_configuration)(struct ufs_msm_phy *phy); int (*is_physical_coding_sublayer_ready) (struct ufs_msm_phy *phy); Loading Loading @@ -173,4 +173,12 @@ int ufs_msm_phy_init_vregulators(struct phy *generic_phy, struct ufs_msm_phy *phy_common); int ufs_msm_phy_remove(struct phy *generic_phy, struct ufs_msm_phy *ufs_msm_phy); struct phy *ufs_msm_phy_generic_probe(struct platform_device *pdev, struct ufs_msm_phy *common_cfg, struct phy_ops *ufs_msm_phy_gen_ops, struct ufs_msm_phy_specific_ops *phy_spec_ops); int ufs_msm_phy_calibrate(struct ufs_msm_phy *ufs_msm_phy, struct ufs_msm_phy_calibration *tbl_A, int tbl_size_A, struct ufs_msm_phy_calibration *tbl_B, int tbl_size_B, int rate); #endif