These patches cleanup the ufs phy driver to an extent.
Subsequent patches will target to clean the phy_init() of
these qcom-ufs phy drivers in order to get rid of a number of
exported APIs that phy drivers expose for ufs-qcom hcd driver
to use.
These patches are based on linux-phy next branch, and have been
tested with on db820c hardware with integration branch -
'integration-linux-qcomlt' of qualcomm linaro lt tree [1].
Changes from v1:
1) Added a patch to the series to remove following unnecessary
function declarations by moving the code:
- __ufs_qcom_phy_init_vreg(),
- ufs_qcom_phy_init_vreg(),
- ufs_qcom_phy_base_init()
2) Cleaned up following functions further for patch [2]:
- ufs_qcom_phy_enable(/disable)_ref_clk()
- ufs_qcom_phy_enable(/disable)_iface_clk()
3) Added patch to add phy_exit() call to ufs-qcom exit path.
4) Added a patch to remove ufs_qcom_phy_exit() from 'phy-qcom-ufs'
driver, since this api just powers off the phy.
[1] https://git.linaro.org/landing-teams/working/qualcomm/kernel.git
[2] ufs-qcom: phy/hcd: Refactoring phy clock handling
Vivek Gautam (9):
phy: qcom-ufs: Remove unnecessary BUG_ON
phy: qcom-ufs: Use devm sibling of kstrdup for regulator names
phy: qcom-ufs-qmp-xx: Discard remove callback for drivers.
phy: qcom-ufs: Cleanup clock and regulator initialization
phy: qcom-ufs: Remove unnecessary function declarations
phy: qcom-ufs-qmp-xx: Move clock and regulator init out of phy init
ufs-qcom: phy/hcd: Refactoring phy clock handling
scsi/ufs: qcom: Add phy_exit call in hcd exit path
phy: qcom-ufs: Remove common layer phy exit callback
Yaniv Gardi (1):
phy: qcom-ufs: remove failure when rx/tx_iface_clk are absence
drivers/phy/phy-qcom-ufs-i.h | 7 +-
drivers/phy/phy-qcom-ufs-qmp-14nm.c | 71 ++++-----
drivers/phy/phy-qcom-ufs-qmp-20nm.c | 65 ++++-----
drivers/phy/phy-qcom-ufs.c | 278 ++++++++++++++++--------------------
drivers/scsi/ufs/ufs-qcom.c | 16 +--
include/linux/phy/phy-qcom-ufs.h | 18 ---
6 files changed, 182 insertions(+), 273 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
This helps us in avoiding any requirement for kfree() operation
to be called exclusively over the allocated string pointer.
Signed-off-by: Vivek Gautam <[email protected]>
Reviewed-by: Subhash Jadavani <[email protected]>
---
No change since v1.
drivers/phy/phy-qcom-ufs.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index 805c91d..f639a7c 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -262,7 +262,7 @@ static int __ufs_qcom_phy_init_vreg(struct phy *phy,
char prop_name[MAX_PROP_NAME];
- vreg->name = kstrdup(name, GFP_KERNEL);
+ vreg->name = devm_kstrdup(dev, name, GFP_KERNEL);
if (!vreg->name) {
err = -ENOMEM;
goto out;
@@ -650,9 +650,6 @@ int ufs_qcom_phy_remove(struct phy *generic_phy,
{
phy_power_off(generic_phy);
- kfree(ufs_qcom_phy->vdda_pll.name);
- kfree(ufs_qcom_phy->vdda_phy.name);
-
return 0;
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_remove);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
BUG_ON() are not preferred in the driver, plus the variable
on which BUG_ON is asserted is already checked in the code
before passing.
Signed-off-by: Vivek Gautam <[email protected]>
Reviewed-by: Subhash Jadavani <[email protected]>
---
No change since v1.
drivers/phy/phy-qcom-ufs.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index 183ec04..805c91d 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -335,8 +335,6 @@ int ufs_qcom_phy_cfg_vreg(struct phy *phy,
struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
struct device *dev = ufs_qcom_phy->dev;
- BUG_ON(!vreg);
-
if (regulator_count_voltages(reg) > 0) {
min_uV = on ? vreg->min_uV : 0;
ret = regulator_set_voltage(reg, min_uV, vreg->max_uV);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
From: Yaniv Gardi <[email protected]>
Since in future UFS Phy's the tx_iface_clk and rx_iface_clk
are no longer exist, we should not fail when their initialization
fail, but rather just report with debug message.
Signed-off-by: Yaniv Gardi <[email protected]>
Signed-off-by: Vivek Gautam <[email protected]>
---
No change since v1.
drivers/phy/phy-qcom-ufs.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index 107cb57..183ec04 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -186,16 +186,27 @@ ufs_qcom_phy_init_clks(struct phy *generic_phy,
struct ufs_qcom_phy *phy_common)
{
int err;
+ struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
err = ufs_qcom_phy_clk_get(generic_phy, "tx_iface_clk",
&phy_common->tx_iface_clk);
+ /*
+ * tx_iface_clk does not exist in newer version of ufs-phy HW,
+ * so don't return error if it is not found
+ */
if (err)
- goto out;
+ dev_dbg(phy->dev, "%s: failed to get tx_iface_clk\n",
+ __func__);
err = ufs_qcom_phy_clk_get(generic_phy, "rx_iface_clk",
&phy_common->rx_iface_clk);
+ /*
+ * rx_iface_clk does not exist in newer version of ufs-phy HW,
+ * so don't return error if it is not found
+ */
if (err)
- goto out;
+ dev_dbg(phy->dev, "%s: failed to get rx_iface_clk\n",
+ __func__);
err = ufs_qcom_phy_clk_get(generic_phy, "ref_clk_src",
&phy_common->ref_clk_src);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Move the functions' definitions to remove unnecessary
declarations.
Signed-off-by: Vivek Gautam <[email protected]>
---
New patch added in v2 series.
drivers/phy/phy-qcom-ufs.c | 133 +++++++++++++++++++++------------------------
1 file changed, 63 insertions(+), 70 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index 3a87e88..144b11f 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -22,13 +22,6 @@
#define VDDP_REF_CLK_MIN_UV 1200000
#define VDDP_REF_CLK_MAX_UV 1200000
-static int __ufs_qcom_phy_init_vreg(struct device *, struct ufs_qcom_phy_vreg *,
- const char *, bool);
-static int ufs_qcom_phy_init_vreg(struct device *, struct ufs_qcom_phy_vreg *,
- const char *);
-static int ufs_qcom_phy_base_init(struct platform_device *pdev,
- struct ufs_qcom_phy *phy_common);
-
int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
struct ufs_qcom_phy_calibration *tbl_A,
int tbl_size_A,
@@ -75,45 +68,6 @@ out:
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate);
-struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
- struct ufs_qcom_phy *common_cfg,
- const struct phy_ops *ufs_qcom_phy_gen_ops,
- struct ufs_qcom_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_qcom_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, NULL, ufs_qcom_phy_gen_ops);
- if (IS_ERR(generic_phy)) {
- err = PTR_ERR(generic_phy);
- dev_err(dev, "%s: failed to create phy %d\n", __func__, err);
- generic_phy = NULL;
- goto out;
- }
-
- common_cfg->phy_spec_ops = phy_spec_ops;
- common_cfg->dev = dev;
-
-out:
- return generic_phy;
-}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe);
-
/*
* This assumes the embedded phy structure inside generic_phy is of type
* struct ufs_qcom_phy. In order to function properly it's crucial
@@ -154,6 +108,45 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev,
return 0;
}
+struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
+ struct ufs_qcom_phy *common_cfg,
+ const struct phy_ops *ufs_qcom_phy_gen_ops,
+ struct ufs_qcom_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_qcom_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, NULL, ufs_qcom_phy_gen_ops);
+ if (IS_ERR(generic_phy)) {
+ err = PTR_ERR(generic_phy);
+ dev_err(dev, "%s: failed to create phy %d\n", __func__, err);
+ generic_phy = NULL;
+ goto out;
+ }
+
+ common_cfg->phy_spec_ops = phy_spec_ops;
+ common_cfg->dev = dev;
+
+out:
+ return generic_phy;
+}
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe);
+
static int __ufs_qcom_phy_clk_get(struct device *dev,
const char *name, struct clk **clk_out, bool err_print)
{
@@ -224,30 +217,6 @@ out:
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_clks);
-int
-ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common)
-{
- int err;
-
- err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_pll,
- "vdda-pll");
- if (err)
- goto out;
-
- err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_phy,
- "vdda-phy");
-
- if (err)
- goto out;
-
- /* vddp-ref-clk-* properties are optional */
- __ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
- "vddp-ref-clk", true);
-out:
- return err;
-}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators);
-
static int __ufs_qcom_phy_init_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional)
{
@@ -316,6 +285,30 @@ static int ufs_qcom_phy_init_vreg(struct device *dev,
return __ufs_qcom_phy_init_vreg(dev, vreg, name, false);
}
+int
+ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common)
+{
+ int err;
+
+ err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_pll,
+ "vdda-pll");
+ if (err)
+ goto out;
+
+ err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_phy,
+ "vdda-phy");
+
+ if (err)
+ goto out;
+
+ /* vddp-ref-clk-* properties are optional */
+ __ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
+ "vddp-ref-clk", true);
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators);
+
static
int ufs_qcom_phy_cfg_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg, bool on)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Add phy clock enable code to phy_power_on/off callbacks, and
remove explicit calls to enable these phy clocks from the
ufs-qcom hcd driver.
Signed-off-by: Vivek Gautam <[email protected]>
---
Changes since v1:
- staticized ufs_qcom_phy_enable(/disable)_ref_clk(),
- staticized ufs_qcom_phy_enable(/disable)_iface_clk()
- removed function declaration and export symbol for these APIs.
drivers/phy/phy-qcom-ufs.c | 36 ++++++++++++++++++------------------
drivers/scsi/ufs/ufs-qcom.c | 15 ---------------
include/linux/phy/phy-qcom-ufs.h | 18 ------------------
3 files changed, 18 insertions(+), 51 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index 144b11f..a425cc2 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -373,10 +373,9 @@ out:
return ret;
}
-int ufs_qcom_phy_enable_ref_clk(struct phy *generic_phy)
+static int ufs_qcom_phy_enable_ref_clk(struct ufs_qcom_phy *phy)
{
int ret = 0;
- struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
if (phy->is_ref_clk_enabled)
goto out;
@@ -423,7 +422,6 @@ out_disable_src:
out:
return ret;
}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_ref_clk);
static
int ufs_qcom_phy_disable_vreg(struct device *dev,
@@ -448,10 +446,8 @@ out:
return ret;
}
-void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
+static void ufs_qcom_phy_disable_ref_clk(struct ufs_qcom_phy *phy)
{
- struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
-
if (phy->is_ref_clk_enabled) {
clk_disable_unprepare(phy->ref_clk);
/*
@@ -464,7 +460,6 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
phy->is_ref_clk_enabled = false;
}
}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_ref_clk);
#define UFS_REF_CLK_EN (1 << 5)
@@ -517,9 +512,8 @@ void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_dev_ref_clk);
/* Turn ON M-PHY RMMI interface clocks */
-int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
+static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy)
{
- struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
int ret = 0;
if (phy->is_iface_clk_enabled)
@@ -543,20 +537,16 @@ int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
out:
return ret;
}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_iface_clk);
/* Turn OFF M-PHY RMMI interface clocks */
-void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
+void ufs_qcom_phy_disable_iface_clk(struct ufs_qcom_phy *phy)
{
- struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
-
if (phy->is_iface_clk_enabled) {
clk_disable_unprepare(phy->tx_iface_clk);
clk_disable_unprepare(phy->rx_iface_clk);
phy->is_iface_clk_enabled = false;
}
}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_iface_clk);
int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
{
@@ -674,13 +664,20 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
goto out_disable_phy;
}
- err = ufs_qcom_phy_enable_ref_clk(generic_phy);
+ err = ufs_qcom_phy_enable_iface_clk(phy_common);
if (err) {
- dev_err(dev, "%s enable phy ref clock failed, err=%d\n",
+ dev_err(dev, "%s enable phy iface clock failed, err=%d\n",
__func__, err);
goto out_disable_pll;
}
+ err = ufs_qcom_phy_enable_ref_clk(phy_common);
+ if (err) {
+ dev_err(dev, "%s enable phy ref clock failed, err=%d\n",
+ __func__, err);
+ goto out_disable_iface_clk;
+ }
+
/* enable device PHY ref_clk pad rail */
if (phy_common->vddp_ref_clk.reg) {
err = ufs_qcom_phy_enable_vreg(dev,
@@ -696,7 +693,9 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
goto out;
out_disable_ref_clk:
- ufs_qcom_phy_disable_ref_clk(generic_phy);
+ ufs_qcom_phy_disable_ref_clk(phy_common);
+out_disable_iface_clk:
+ ufs_qcom_phy_disable_iface_clk(phy_common);
out_disable_pll:
ufs_qcom_phy_disable_vreg(dev, &phy_common->vdda_pll);
out_disable_phy:
@@ -715,7 +714,8 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
if (phy_common->vddp_ref_clk.reg)
ufs_qcom_phy_disable_vreg(phy_common->dev,
&phy_common->vddp_ref_clk);
- ufs_qcom_phy_disable_ref_clk(generic_phy);
+ ufs_qcom_phy_disable_ref_clk(phy_common);
+ ufs_qcom_phy_disable_iface_clk(phy_common);
ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_pll);
ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_phy);
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 3aedf73..6e4ce5f 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1112,17 +1112,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
return 0;
if (on) {
- err = ufs_qcom_phy_enable_iface_clk(host->generic_phy);
- if (err)
- goto out;
-
- err = ufs_qcom_phy_enable_ref_clk(host->generic_phy);
- if (err) {
- dev_err(hba->dev, "%s enable phy ref clock failed, err=%d\n",
- __func__, err);
- ufs_qcom_phy_disable_iface_clk(host->generic_phy);
- goto out;
- }
/* enable the device ref clock for HS mode*/
if (ufshcd_is_hs_mode(&hba->pwr_info))
ufs_qcom_dev_ref_clk_ctrl(host, true);
@@ -1131,9 +1120,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
ufs_qcom_update_bus_bw_vote(host);
} else {
-
- /* M-PHY RMMI interface clocks can be turned off */
- ufs_qcom_phy_disable_iface_clk(host->generic_phy);
if (!ufs_qcom_is_link_active(hba))
/* disable device ref_clk */
ufs_qcom_dev_ref_clk_ctrl(host, false);
@@ -1146,7 +1132,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
dev_err(hba->dev, "%s: set bus vote failed %d\n",
__func__, err);
-out:
return err;
}
diff --git a/include/linux/phy/phy-qcom-ufs.h b/include/linux/phy/phy-qcom-ufs.h
index 9d18e9f..35c070e 100644
--- a/include/linux/phy/phy-qcom-ufs.h
+++ b/include/linux/phy/phy-qcom-ufs.h
@@ -18,22 +18,6 @@
#include "phy.h"
/**
- * ufs_qcom_phy_enable_ref_clk() - Enable the phy
- * ref clock.
- * @phy: reference to a generic phy
- *
- * returns 0 for success, and non-zero for error.
- */
-int ufs_qcom_phy_enable_ref_clk(struct phy *phy);
-
-/**
- * ufs_qcom_phy_disable_ref_clk() - Disable the phy
- * ref clock.
- * @phy: reference to a generic phy.
- */
-void ufs_qcom_phy_disable_ref_clk(struct phy *phy);
-
-/**
* ufs_qcom_phy_enable_dev_ref_clk() - Enable the device
* ref clock.
* @phy: reference to a generic phy.
@@ -47,8 +31,6 @@ void ufs_qcom_phy_enable_dev_ref_clk(struct phy *phy);
*/
void ufs_qcom_phy_disable_dev_ref_clk(struct phy *phy);
-int ufs_qcom_phy_enable_iface_clk(struct phy *phy);
-void ufs_qcom_phy_disable_iface_clk(struct phy *phy);
int ufs_qcom_phy_start_serdes(struct phy *phy);
int ufs_qcom_phy_set_tx_lane_enable(struct phy *phy, u32 tx_lanes);
int ufs_qcom_phy_calibrate_phy(struct phy *phy, bool is_rate_B);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
The phy init is meant to do phy initialization rather than
just getting the clock and regulator. Move these clock and
regulator get to probe(), to make room for actual phy
initialization sequence.
Signed-off-by: Vivek Gautam <[email protected]>
Reviewed-by: Subhash Jadavani <[email protected]>
---
No change since v1.
drivers/phy/phy-qcom-ufs-qmp-14nm.c | 52 ++++++++++++++++++-------------------
drivers/phy/phy-qcom-ufs-qmp-20nm.c | 46 +++++++++++++++-----------------
2 files changed, 46 insertions(+), 52 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
index 55fecbb..a60cf34 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
@@ -44,30 +44,7 @@ void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common)
static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
{
- struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy);
- struct ufs_qcom_phy *phy_common = &phy->common_cfg;
- int err;
-
- err = ufs_qcom_phy_init_clks(phy_common);
- if (err) {
- dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n",
- __func__, err);
- goto out;
- }
-
- err = ufs_qcom_phy_init_vregulators(phy_common);
- if (err) {
- dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n",
- __func__, err);
- goto out;
- }
- phy_common->vdda_phy.max_uV = UFS_PHY_VDDA_PHY_UV;
- phy_common->vdda_phy.min_uV = UFS_PHY_VDDA_PHY_UV;
-
- ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common);
-
-out:
- return err;
+ return 0;
}
static
@@ -136,6 +113,7 @@ static int ufs_qcom_phy_qmp_14nm_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct phy *generic_phy;
struct ufs_qcom_phy_qmp_14nm *phy;
+ struct ufs_qcom_phy *phy_common;
int err = 0;
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
@@ -143,8 +121,9 @@ static int ufs_qcom_phy_qmp_14nm_probe(struct platform_device *pdev)
err = -ENOMEM;
goto out;
}
+ phy_common = &phy->common_cfg;
- generic_phy = ufs_qcom_phy_generic_probe(pdev, &phy->common_cfg,
+ generic_phy = ufs_qcom_phy_generic_probe(pdev, phy_common,
&ufs_qcom_phy_qmp_14nm_phy_ops, &phy_14nm_ops);
if (!generic_phy) {
@@ -154,10 +133,29 @@ static int ufs_qcom_phy_qmp_14nm_probe(struct platform_device *pdev)
goto out;
}
+ err = ufs_qcom_phy_init_clks(phy_common);
+ if (err) {
+ dev_err(phy_common->dev,
+ "%s: ufs_qcom_phy_init_clks() failed %d\n",
+ __func__, err);
+ goto out;
+ }
+
+ err = ufs_qcom_phy_init_vregulators(phy_common);
+ if (err) {
+ dev_err(phy_common->dev,
+ "%s: ufs_qcom_phy_init_vregulators() failed %d\n",
+ __func__, err);
+ goto out;
+ }
+ phy_common->vdda_phy.max_uV = UFS_PHY_VDDA_PHY_UV;
+ phy_common->vdda_phy.min_uV = UFS_PHY_VDDA_PHY_UV;
+
+ ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common);
+
phy_set_drvdata(generic_phy, phy);
- strlcpy(phy->common_cfg.name, UFS_PHY_NAME,
- sizeof(phy->common_cfg.name));
+ strlcpy(phy_common->name, UFS_PHY_NAME, sizeof(phy_common->name));
out:
return err;
diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
index 9a2f53d..dfc5175 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
@@ -63,28 +63,7 @@ void ufs_qcom_phy_qmp_20nm_advertise_quirks(struct ufs_qcom_phy *phy_common)
static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy)
{
- struct ufs_qcom_phy_qmp_20nm *phy = phy_get_drvdata(generic_phy);
- struct ufs_qcom_phy *phy_common = &phy->common_cfg;
- int err = 0;
-
- err = ufs_qcom_phy_init_clks(phy_common);
- if (err) {
- dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n",
- __func__, err);
- goto out;
- }
-
- err = ufs_qcom_phy_init_vregulators(phy_common);
- if (err) {
- dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n",
- __func__, err);
- goto out;
- }
-
- ufs_qcom_phy_qmp_20nm_advertise_quirks(phy_common);
-
-out:
- return err;
+ return 0;
}
static
@@ -192,6 +171,7 @@ static int ufs_qcom_phy_qmp_20nm_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct phy *generic_phy;
struct ufs_qcom_phy_qmp_20nm *phy;
+ struct ufs_qcom_phy *phy_common;
int err = 0;
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
@@ -199,8 +179,9 @@ static int ufs_qcom_phy_qmp_20nm_probe(struct platform_device *pdev)
err = -ENOMEM;
goto out;
}
+ phy_common = &phy->common_cfg;
- generic_phy = ufs_qcom_phy_generic_probe(pdev, &phy->common_cfg,
+ generic_phy = ufs_qcom_phy_generic_probe(pdev, phy_common,
&ufs_qcom_phy_qmp_20nm_phy_ops, &phy_20nm_ops);
if (!generic_phy) {
@@ -210,10 +191,25 @@ static int ufs_qcom_phy_qmp_20nm_probe(struct platform_device *pdev)
goto out;
}
+ err = ufs_qcom_phy_init_clks(phy_common);
+ if (err) {
+ dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n",
+ __func__, err);
+ goto out;
+ }
+
+ err = ufs_qcom_phy_init_vregulators(phy_common);
+ if (err) {
+ dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n",
+ __func__, err);
+ goto out;
+ }
+
+ ufs_qcom_phy_qmp_20nm_advertise_quirks(phy_common);
+
phy_set_drvdata(generic_phy, phy);
- strlcpy(phy->common_cfg.name, UFS_PHY_NAME,
- sizeof(phy->common_cfg.name));
+ strlcpy(phy_common->name, UFS_PHY_NAME, sizeof(phy_common->name));
out:
return err;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
The common layer phy exit callback ufs_qcom_phy_exit()
calls phy_power_off() that has no meaning when phy_power_off()
callback is already registered with the phy provider and
the consumer makes use of the same.
Instead, add a no-op specific phy_exit() callback for now
to add the exit sequence at a later point.
Signed-off-by: Vivek Gautam <[email protected]>
---
New patch added in v2 series.
drivers/phy/phy-qcom-ufs-i.h | 1 -
drivers/phy/phy-qcom-ufs-qmp-14nm.c | 7 ++++++-
drivers/phy/phy-qcom-ufs-qmp-20nm.c | 7 ++++++-
drivers/phy/phy-qcom-ufs.c | 17 ++++++-----------
4 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs-i.h b/drivers/phy/phy-qcom-ufs-i.h
index 69e836d..d505d98 100644
--- a/drivers/phy/phy-qcom-ufs-i.h
+++ b/drivers/phy/phy-qcom-ufs-i.h
@@ -141,7 +141,6 @@ struct ufs_qcom_phy_specific_ops {
struct ufs_qcom_phy *get_ufs_qcom_phy(struct phy *generic_phy);
int ufs_qcom_phy_power_on(struct phy *generic_phy);
int ufs_qcom_phy_power_off(struct phy *generic_phy);
-int ufs_qcom_phy_exit(struct phy *generic_phy);
int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common);
int ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common);
int ufs_qcom_phy_remove(struct phy *generic_phy,
diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
index a60cf34..061604f 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
@@ -47,6 +47,11 @@ static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
return 0;
}
+static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy)
+{
+ return 0;
+}
+
static
void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy, bool val)
{
@@ -94,7 +99,7 @@ static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy *phy_common)
static const struct phy_ops ufs_qcom_phy_qmp_14nm_phy_ops = {
.init = ufs_qcom_phy_qmp_14nm_init,
- .exit = ufs_qcom_phy_exit,
+ .exit = ufs_qcom_phy_qmp_14nm_exit,
.power_on = ufs_qcom_phy_power_on,
.power_off = ufs_qcom_phy_power_off,
.owner = THIS_MODULE,
diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
index dfc5175..1a26a64 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
@@ -66,6 +66,11 @@ static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy)
return 0;
}
+static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy)
+{
+ return 0;
+}
+
static
void ufs_qcom_phy_qmp_20nm_power_control(struct ufs_qcom_phy *phy, bool val)
{
@@ -152,7 +157,7 @@ static int ufs_qcom_phy_qmp_20nm_is_pcs_ready(struct ufs_qcom_phy *phy_common)
static const struct phy_ops ufs_qcom_phy_qmp_20nm_phy_ops = {
.init = ufs_qcom_phy_qmp_20nm_init,
- .exit = ufs_qcom_phy_exit,
+ .exit = ufs_qcom_phy_qmp_20nm_exit,
.power_on = ufs_qcom_phy_power_on,
.power_off = ufs_qcom_phy_power_off,
.owner = THIS_MODULE,
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index a425cc2..494f90f 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -615,17 +615,6 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
-int ufs_qcom_phy_exit(struct phy *generic_phy)
-{
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
-
- if (ufs_qcom_phy->is_powered_on)
- phy_power_off(generic_phy);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_exit);
-
int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy)
{
struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
@@ -647,6 +636,9 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
struct device *dev = phy_common->dev;
int err;
+ if (phy_common->is_powered_on)
+ return 0;
+
err = ufs_qcom_phy_enable_vreg(dev, &phy_common->vdda_phy);
if (err) {
dev_err(dev, "%s enable vdda_phy failed, err=%d\n",
@@ -709,6 +701,9 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
{
struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
+ if (!phy_common->is_powered_on)
+ return 0;
+
phy_common->phy_spec_ops->power_control(phy_common, false);
if (phy_common->vddp_ref_clk.reg)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Do a phy_exit() over the ufs phy in the ufs qcom exit path
to de-initialize the phy.
Signed-off-by: Vivek Gautam <[email protected]>
---
New patch added in v2 series.
drivers/scsi/ufs/ufs-qcom.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 6e4ce5f..dfd2af8 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1272,6 +1272,7 @@ static void ufs_qcom_exit(struct ufs_hba *hba)
ufs_qcom_disable_lane_clks(host);
phy_power_off(host->generic_phy);
+ phy_exit(host->generic_phy);
}
static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Different menthods pass around generic phy pointer to
extract device pointer. Instead, pass the device pointer
directly between function calls.
Signed-off-by: Vivek Gautam <[email protected]>
Reviewed-by: Subhash Jadavani <[email protected]>
---
No change since v1.
drivers/phy/phy-qcom-ufs-i.h | 6 +--
drivers/phy/phy-qcom-ufs-qmp-14nm.c | 4 +-
drivers/phy/phy-qcom-ufs-qmp-20nm.c | 4 +-
drivers/phy/phy-qcom-ufs.c | 79 ++++++++++++++++---------------------
4 files changed, 39 insertions(+), 54 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs-i.h b/drivers/phy/phy-qcom-ufs-i.h
index 2bd5ce4..69e836d 100644
--- a/drivers/phy/phy-qcom-ufs-i.h
+++ b/drivers/phy/phy-qcom-ufs-i.h
@@ -142,10 +142,8 @@ struct ufs_qcom_phy *get_ufs_qcom_phy(struct phy *generic_phy);
int ufs_qcom_phy_power_on(struct phy *generic_phy);
int ufs_qcom_phy_power_off(struct phy *generic_phy);
int ufs_qcom_phy_exit(struct phy *generic_phy);
-int ufs_qcom_phy_init_clks(struct phy *generic_phy,
- struct ufs_qcom_phy *phy_common);
-int ufs_qcom_phy_init_vregulators(struct phy *generic_phy,
- struct ufs_qcom_phy *phy_common);
+int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common);
+int ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common);
int ufs_qcom_phy_remove(struct phy *generic_phy,
struct ufs_qcom_phy *ufs_qcom_phy);
struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
index a305016..55fecbb 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
@@ -48,14 +48,14 @@ static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
struct ufs_qcom_phy *phy_common = &phy->common_cfg;
int err;
- err = ufs_qcom_phy_init_clks(generic_phy, phy_common);
+ err = ufs_qcom_phy_init_clks(phy_common);
if (err) {
dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n",
__func__, err);
goto out;
}
- err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common);
+ err = ufs_qcom_phy_init_vregulators(phy_common);
if (err) {
dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n",
__func__, err);
diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
index 2db1fbb..9a2f53d 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
@@ -67,14 +67,14 @@ static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy)
struct ufs_qcom_phy *phy_common = &phy->common_cfg;
int err = 0;
- err = ufs_qcom_phy_init_clks(generic_phy, phy_common);
+ err = ufs_qcom_phy_init_clks(phy_common);
if (err) {
dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed %d\n",
__func__, err);
goto out;
}
- err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common);
+ err = ufs_qcom_phy_init_vregulators(phy_common);
if (err) {
dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() failed %d\n",
__func__, err);
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index b8f9286..3a87e88 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -22,9 +22,9 @@
#define VDDP_REF_CLK_MIN_UV 1200000
#define VDDP_REF_CLK_MAX_UV 1200000
-static int __ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *,
+static int __ufs_qcom_phy_init_vreg(struct device *, struct ufs_qcom_phy_vreg *,
const char *, bool);
-static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *,
+static int ufs_qcom_phy_init_vreg(struct device *, struct ufs_qcom_phy_vreg *,
const char *);
static int ufs_qcom_phy_base_init(struct platform_device *pdev,
struct ufs_qcom_phy *phy_common);
@@ -154,13 +154,11 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev,
return 0;
}
-static int __ufs_qcom_phy_clk_get(struct phy *phy,
+static int __ufs_qcom_phy_clk_get(struct device *dev,
const char *name, struct clk **clk_out, bool err_print)
{
struct clk *clk;
int err = 0;
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
- struct device *dev = ufs_qcom_phy->dev;
clk = devm_clk_get(dev, name);
if (IS_ERR(clk)) {
@@ -175,40 +173,38 @@ static int __ufs_qcom_phy_clk_get(struct phy *phy,
}
static
-int ufs_qcom_phy_clk_get(struct phy *phy,
+int ufs_qcom_phy_clk_get(struct device *dev,
const char *name, struct clk **clk_out)
{
- return __ufs_qcom_phy_clk_get(phy, name, clk_out, true);
+ return __ufs_qcom_phy_clk_get(dev, name, clk_out, true);
}
int
-ufs_qcom_phy_init_clks(struct phy *generic_phy,
- struct ufs_qcom_phy *phy_common)
+ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common)
{
int err;
- struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
- err = ufs_qcom_phy_clk_get(generic_phy, "tx_iface_clk",
+ err = ufs_qcom_phy_clk_get(phy_common->dev, "tx_iface_clk",
&phy_common->tx_iface_clk);
/*
* tx_iface_clk does not exist in newer version of ufs-phy HW,
* so don't return error if it is not found
*/
if (err)
- dev_dbg(phy->dev, "%s: failed to get tx_iface_clk\n",
+ dev_dbg(phy_common->dev, "%s: failed to get tx_iface_clk\n",
__func__);
- err = ufs_qcom_phy_clk_get(generic_phy, "rx_iface_clk",
+ err = ufs_qcom_phy_clk_get(phy_common->dev, "rx_iface_clk",
&phy_common->rx_iface_clk);
/*
* rx_iface_clk does not exist in newer version of ufs-phy HW,
* so don't return error if it is not found
*/
if (err)
- dev_dbg(phy->dev, "%s: failed to get rx_iface_clk\n",
+ dev_dbg(phy_common->dev, "%s: failed to get rx_iface_clk\n",
__func__);
- err = ufs_qcom_phy_clk_get(generic_phy, "ref_clk_src",
+ err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk_src",
&phy_common->ref_clk_src);
if (err)
goto out;
@@ -217,10 +213,10 @@ ufs_qcom_phy_init_clks(struct phy *generic_phy,
* "ref_clk_parent" is optional hence don't abort init if it's not
* found.
*/
- __ufs_qcom_phy_clk_get(generic_phy, "ref_clk_parent",
+ __ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk_parent",
&phy_common->ref_clk_parent, false);
- err = ufs_qcom_phy_clk_get(generic_phy, "ref_clk",
+ err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk",
&phy_common->ref_clk);
out:
@@ -229,36 +225,33 @@ out:
EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_clks);
int
-ufs_qcom_phy_init_vregulators(struct phy *generic_phy,
- struct ufs_qcom_phy *phy_common)
+ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common)
{
int err;
- err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_pll,
+ err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_pll,
"vdda-pll");
if (err)
goto out;
- err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_phy,
+ err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_phy,
"vdda-phy");
if (err)
goto out;
/* vddp-ref-clk-* properties are optional */
- __ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vddp_ref_clk,
+ __ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
"vddp-ref-clk", true);
out:
return err;
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators);
-static int __ufs_qcom_phy_init_vreg(struct phy *phy,
+static int __ufs_qcom_phy_init_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional)
{
int err = 0;
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
- struct device *dev = ufs_qcom_phy->dev;
char prop_name[MAX_PROP_NAME];
@@ -317,14 +310,14 @@ out:
return err;
}
-static int ufs_qcom_phy_init_vreg(struct phy *phy,
+static int ufs_qcom_phy_init_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg, const char *name)
{
- return __ufs_qcom_phy_init_vreg(phy, vreg, name, false);
+ return __ufs_qcom_phy_init_vreg(dev, vreg, name, false);
}
static
-int ufs_qcom_phy_cfg_vreg(struct phy *phy,
+int ufs_qcom_phy_cfg_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg, bool on)
{
int ret = 0;
@@ -332,8 +325,6 @@ int ufs_qcom_phy_cfg_vreg(struct phy *phy,
const char *name = vreg->name;
int min_uV;
int uA_load;
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
- struct device *dev = ufs_qcom_phy->dev;
if (regulator_count_voltages(reg) > 0) {
min_uV = on ? vreg->min_uV : 0;
@@ -362,17 +353,15 @@ out:
}
static
-int ufs_qcom_phy_enable_vreg(struct phy *phy,
+int ufs_qcom_phy_enable_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg)
{
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
- struct device *dev = ufs_qcom_phy->dev;
int ret = 0;
if (!vreg || vreg->enabled)
goto out;
- ret = ufs_qcom_phy_cfg_vreg(phy, vreg, true);
+ ret = ufs_qcom_phy_cfg_vreg(dev, vreg, true);
if (ret) {
dev_err(dev, "%s: ufs_qcom_phy_cfg_vreg() failed, err=%d\n",
__func__, ret);
@@ -444,11 +433,9 @@ out:
EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_ref_clk);
static
-int ufs_qcom_phy_disable_vreg(struct phy *phy,
+int ufs_qcom_phy_disable_vreg(struct device *dev,
struct ufs_qcom_phy_vreg *vreg)
{
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
- struct device *dev = ufs_qcom_phy->dev;
int ret = 0;
if (!vreg || !vreg->enabled || vreg->is_always_on)
@@ -458,7 +445,7 @@ int ufs_qcom_phy_disable_vreg(struct phy *phy,
if (!ret) {
/* ignore errors on applying disable config */
- ufs_qcom_phy_cfg_vreg(phy, vreg, false);
+ ufs_qcom_phy_cfg_vreg(dev, vreg, false);
vreg->enabled = false;
} else {
dev_err(dev, "%s: %s disable failed, err=%d\n",
@@ -677,7 +664,7 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
struct device *dev = phy_common->dev;
int err;
- err = ufs_qcom_phy_enable_vreg(generic_phy, &phy_common->vdda_phy);
+ err = ufs_qcom_phy_enable_vreg(dev, &phy_common->vdda_phy);
if (err) {
dev_err(dev, "%s enable vdda_phy failed, err=%d\n",
__func__, err);
@@ -687,7 +674,7 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
phy_common->phy_spec_ops->power_control(phy_common, true);
/* vdda_pll also enables ref clock LDOs so enable it first */
- err = ufs_qcom_phy_enable_vreg(generic_phy, &phy_common->vdda_pll);
+ err = ufs_qcom_phy_enable_vreg(dev, &phy_common->vdda_pll);
if (err) {
dev_err(dev, "%s enable vdda_pll failed, err=%d\n",
__func__, err);
@@ -703,7 +690,7 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
/* enable device PHY ref_clk pad rail */
if (phy_common->vddp_ref_clk.reg) {
- err = ufs_qcom_phy_enable_vreg(generic_phy,
+ err = ufs_qcom_phy_enable_vreg(dev,
&phy_common->vddp_ref_clk);
if (err) {
dev_err(dev, "%s enable vddp_ref_clk failed, err=%d\n",
@@ -718,9 +705,9 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
out_disable_ref_clk:
ufs_qcom_phy_disable_ref_clk(generic_phy);
out_disable_pll:
- ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll);
+ ufs_qcom_phy_disable_vreg(dev, &phy_common->vdda_pll);
out_disable_phy:
- ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_phy);
+ ufs_qcom_phy_disable_vreg(dev, &phy_common->vdda_phy);
out:
return err;
}
@@ -733,12 +720,12 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
phy_common->phy_spec_ops->power_control(phy_common, false);
if (phy_common->vddp_ref_clk.reg)
- ufs_qcom_phy_disable_vreg(generic_phy,
+ ufs_qcom_phy_disable_vreg(phy_common->dev,
&phy_common->vddp_ref_clk);
ufs_qcom_phy_disable_ref_clk(generic_phy);
- ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll);
- ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_phy);
+ ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_pll);
+ ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_phy);
phy_common->is_powered_on = false;
return 0;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
remove() callback does a phy_exit() only and nothing else now.
The phy_exit() over the generic phy is called from the phy
consumer, and phy provider driver should not explicitly need to
call any phy_exit().
So discard the remove callback for qcom-ufs phy platform drivers.
Signed-off-by: Vivek Gautam <[email protected]>
Reviewed-by: Subhash Jadavani <[email protected]>
---
No change since v1.
drivers/phy/phy-qcom-ufs-qmp-14nm.c | 16 ----------------
drivers/phy/phy-qcom-ufs-qmp-20nm.c | 16 ----------------
drivers/phy/phy-qcom-ufs.c | 9 ---------
3 files changed, 41 deletions(-)
diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
index 6ee5149..a305016 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
@@ -163,21 +163,6 @@ out:
return err;
}
-static int ufs_qcom_phy_qmp_14nm_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct phy *generic_phy = to_phy(dev);
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
- int err = 0;
-
- err = ufs_qcom_phy_remove(generic_phy, ufs_qcom_phy);
- if (err)
- dev_err(dev, "%s: ufs_qcom_phy_remove failed = %d\n",
- __func__, err);
-
- return err;
-}
-
static const struct of_device_id ufs_qcom_phy_qmp_14nm_of_match[] = {
{.compatible = "qcom,ufs-phy-qmp-14nm"},
{},
@@ -186,7 +171,6 @@ MODULE_DEVICE_TABLE(of, ufs_qcom_phy_qmp_14nm_of_match);
static struct platform_driver ufs_qcom_phy_qmp_14nm_driver = {
.probe = ufs_qcom_phy_qmp_14nm_probe,
- .remove = ufs_qcom_phy_qmp_14nm_remove,
.driver = {
.of_match_table = ufs_qcom_phy_qmp_14nm_of_match,
.name = "ufs_qcom_phy_qmp_14nm",
diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
index 770087a..2db1fbb 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
@@ -219,21 +219,6 @@ out:
return err;
}
-static int ufs_qcom_phy_qmp_20nm_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct phy *generic_phy = to_phy(dev);
- struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
- int err = 0;
-
- err = ufs_qcom_phy_remove(generic_phy, ufs_qcom_phy);
- if (err)
- dev_err(dev, "%s: ufs_qcom_phy_remove failed = %d\n",
- __func__, err);
-
- return err;
-}
-
static const struct of_device_id ufs_qcom_phy_qmp_20nm_of_match[] = {
{.compatible = "qcom,ufs-phy-qmp-20nm"},
{},
@@ -242,7 +227,6 @@ MODULE_DEVICE_TABLE(of, ufs_qcom_phy_qmp_20nm_of_match);
static struct platform_driver ufs_qcom_phy_qmp_20nm_driver = {
.probe = ufs_qcom_phy_qmp_20nm_probe,
- .remove = ufs_qcom_phy_qmp_20nm_remove,
.driver = {
.of_match_table = ufs_qcom_phy_qmp_20nm_of_match,
.name = "ufs_qcom_phy_qmp_20nm",
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index f639a7c..b8f9286 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -645,15 +645,6 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
}
EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
-int ufs_qcom_phy_remove(struct phy *generic_phy,
- struct ufs_qcom_phy *ufs_qcom_phy)
-{
- phy_power_off(generic_phy);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ufs_qcom_phy_remove);
-
int ufs_qcom_phy_exit(struct phy *generic_phy)
{
struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-10-18 07:28, Vivek Gautam wrote:
> From: Yaniv Gardi <[email protected]>
>
> Since in future UFS Phy's the tx_iface_clk and rx_iface_clk
> are no longer exist, we should not fail when their initialization
> fail, but rather just report with debug message.
You may also want to update the device tree binding (documentation) to
update these as optional properties.
>
> Signed-off-by: Yaniv Gardi <[email protected]>
> Signed-off-by: Vivek Gautam <[email protected]>
> ---
>
> No change since v1.
>
> drivers/phy/phy-qcom-ufs.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
> index 107cb57..183ec04 100644
> --- a/drivers/phy/phy-qcom-ufs.c
> +++ b/drivers/phy/phy-qcom-ufs.c
> @@ -186,16 +186,27 @@ ufs_qcom_phy_init_clks(struct phy *generic_phy,
> struct ufs_qcom_phy *phy_common)
> {
> int err;
> + struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
>
> err = ufs_qcom_phy_clk_get(generic_phy, "tx_iface_clk",
> &phy_common->tx_iface_clk);
> + /*
> + * tx_iface_clk does not exist in newer version of ufs-phy HW,
> + * so don't return error if it is not found
> + */
> if (err)
> - goto out;
> + dev_dbg(phy->dev, "%s: failed to get tx_iface_clk\n",
> + __func__);
>
> err = ufs_qcom_phy_clk_get(generic_phy, "rx_iface_clk",
> &phy_common->rx_iface_clk);
> + /*
> + * rx_iface_clk does not exist in newer version of ufs-phy HW,
> + * so don't return error if it is not found
> + */
> if (err)
> - goto out;
> + dev_dbg(phy->dev, "%s: failed to get rx_iface_clk\n",
> + __func__);
>
> err = ufs_qcom_phy_clk_get(generic_phy, "ref_clk_src",
> &phy_common->ref_clk_src);
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-10-18 07:28, Vivek Gautam wrote:
> Move the functions' definitions to remove unnecessary
> declarations.
>
> Signed-off-by: Vivek Gautam <[email protected]>
> ---
>
> New patch added in v2 series.
>
> drivers/phy/phy-qcom-ufs.c | 133
> +++++++++++++++++++++------------------------
> 1 file changed, 63 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
> index 3a87e88..144b11f 100644
> --- a/drivers/phy/phy-qcom-ufs.c
> +++ b/drivers/phy/phy-qcom-ufs.c
> @@ -22,13 +22,6 @@
> #define VDDP_REF_CLK_MIN_UV 1200000
> #define VDDP_REF_CLK_MAX_UV 1200000
>
> -static int __ufs_qcom_phy_init_vreg(struct device *, struct
> ufs_qcom_phy_vreg *,
> - const char *, bool);
> -static int ufs_qcom_phy_init_vreg(struct device *, struct
> ufs_qcom_phy_vreg *,
> - const char *);
> -static int ufs_qcom_phy_base_init(struct platform_device *pdev,
> - struct ufs_qcom_phy *phy_common);
> -
> int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
> struct ufs_qcom_phy_calibration *tbl_A,
> int tbl_size_A,
> @@ -75,45 +68,6 @@ out:
> }
> EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate);
>
> -struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
> - struct ufs_qcom_phy *common_cfg,
> - const struct phy_ops *ufs_qcom_phy_gen_ops,
> - struct ufs_qcom_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_qcom_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, NULL, ufs_qcom_phy_gen_ops);
> - if (IS_ERR(generic_phy)) {
> - err = PTR_ERR(generic_phy);
> - dev_err(dev, "%s: failed to create phy %d\n", __func__, err);
> - generic_phy = NULL;
> - goto out;
> - }
> -
> - common_cfg->phy_spec_ops = phy_spec_ops;
> - common_cfg->dev = dev;
> -
> -out:
> - return generic_phy;
> -}
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe);
> -
> /*
> * This assumes the embedded phy structure inside generic_phy is of
> type
> * struct ufs_qcom_phy. In order to function properly it's crucial
> @@ -154,6 +108,45 @@ int ufs_qcom_phy_base_init(struct platform_device
> *pdev,
> return 0;
> }
>
> +struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
> + struct ufs_qcom_phy *common_cfg,
> + const struct phy_ops *ufs_qcom_phy_gen_ops,
> + struct ufs_qcom_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_qcom_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, NULL, ufs_qcom_phy_gen_ops);
> + if (IS_ERR(generic_phy)) {
> + err = PTR_ERR(generic_phy);
> + dev_err(dev, "%s: failed to create phy %d\n", __func__, err);
> + generic_phy = NULL;
> + goto out;
> + }
> +
> + common_cfg->phy_spec_ops = phy_spec_ops;
> + common_cfg->dev = dev;
> +
> +out:
> + return generic_phy;
> +}
> +EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe);
> +
> static int __ufs_qcom_phy_clk_get(struct device *dev,
> const char *name, struct clk **clk_out, bool err_print)
> {
> @@ -224,30 +217,6 @@ out:
> }
> EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_clks);
>
> -int
> -ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common)
> -{
> - int err;
> -
> - err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_pll,
> - "vdda-pll");
> - if (err)
> - goto out;
> -
> - err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_phy,
> - "vdda-phy");
> -
> - if (err)
> - goto out;
> -
> - /* vddp-ref-clk-* properties are optional */
> - __ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
> - "vddp-ref-clk", true);
> -out:
> - return err;
> -}
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators);
> -
> static int __ufs_qcom_phy_init_vreg(struct device *dev,
> struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional)
> {
> @@ -316,6 +285,30 @@ static int ufs_qcom_phy_init_vreg(struct device
> *dev,
> return __ufs_qcom_phy_init_vreg(dev, vreg, name, false);
> }
>
> +int
> +ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common)
> +{
> + int err;
> +
> + err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_pll,
> + "vdda-pll");
> + if (err)
> + goto out;
> +
> + err = ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vdda_phy,
> + "vdda-phy");
> +
> + if (err)
> + goto out;
> +
> + /* vddp-ref-clk-* properties are optional */
> + __ufs_qcom_phy_init_vreg(phy_common->dev, &phy_common->vddp_ref_clk,
> + "vddp-ref-clk", true);
> +out:
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators);
> +
> static
> int ufs_qcom_phy_cfg_vreg(struct device *dev,
> struct ufs_qcom_phy_vreg *vreg, bool on)
LGTM.
Reviewed-by: Subhash Jadavani <[email protected]>
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-10-18 07:28, Vivek Gautam wrote:
> Add phy clock enable code to phy_power_on/off callbacks, and
> remove explicit calls to enable these phy clocks from the
> ufs-qcom hcd driver.
>
> Signed-off-by: Vivek Gautam <[email protected]>
> ---
>
> Changes since v1:
> - staticized ufs_qcom_phy_enable(/disable)_ref_clk(),
> - staticized ufs_qcom_phy_enable(/disable)_iface_clk()
> - removed function declaration and export symbol for these APIs.
>
> drivers/phy/phy-qcom-ufs.c | 36
> ++++++++++++++++++------------------
> drivers/scsi/ufs/ufs-qcom.c | 15 ---------------
> include/linux/phy/phy-qcom-ufs.h | 18 ------------------
> 3 files changed, 18 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
> index 144b11f..a425cc2 100644
> --- a/drivers/phy/phy-qcom-ufs.c
> +++ b/drivers/phy/phy-qcom-ufs.c
> @@ -373,10 +373,9 @@ out:
> return ret;
> }
>
> -int ufs_qcom_phy_enable_ref_clk(struct phy *generic_phy)
> +static int ufs_qcom_phy_enable_ref_clk(struct ufs_qcom_phy *phy)
> {
> int ret = 0;
> - struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
>
> if (phy->is_ref_clk_enabled)
> goto out;
> @@ -423,7 +422,6 @@ out_disable_src:
> out:
> return ret;
> }
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_ref_clk);
>
> static
> int ufs_qcom_phy_disable_vreg(struct device *dev,
> @@ -448,10 +446,8 @@ out:
> return ret;
> }
>
> -void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
> +static void ufs_qcom_phy_disable_ref_clk(struct ufs_qcom_phy *phy)
> {
> - struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
> -
> if (phy->is_ref_clk_enabled) {
> clk_disable_unprepare(phy->ref_clk);
> /*
> @@ -464,7 +460,6 @@ void ufs_qcom_phy_disable_ref_clk(struct phy
> *generic_phy)
> phy->is_ref_clk_enabled = false;
> }
> }
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_ref_clk);
>
> #define UFS_REF_CLK_EN (1 << 5)
>
> @@ -517,9 +512,8 @@ void ufs_qcom_phy_disable_dev_ref_clk(struct phy
> *generic_phy)
> EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_dev_ref_clk);
>
> /* Turn ON M-PHY RMMI interface clocks */
> -int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
> +static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy)
> {
> - struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
> int ret = 0;
>
> if (phy->is_iface_clk_enabled)
> @@ -543,20 +537,16 @@ int ufs_qcom_phy_enable_iface_clk(struct phy
> *generic_phy)
> out:
> return ret;
> }
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_iface_clk);
>
> /* Turn OFF M-PHY RMMI interface clocks */
> -void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
> +void ufs_qcom_phy_disable_iface_clk(struct ufs_qcom_phy *phy)
> {
> - struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
> -
> if (phy->is_iface_clk_enabled) {
> clk_disable_unprepare(phy->tx_iface_clk);
> clk_disable_unprepare(phy->rx_iface_clk);
> phy->is_iface_clk_enabled = false;
> }
> }
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_iface_clk);
>
> int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
> {
> @@ -674,13 +664,20 @@ int ufs_qcom_phy_power_on(struct phy
> *generic_phy)
> goto out_disable_phy;
> }
>
> - err = ufs_qcom_phy_enable_ref_clk(generic_phy);
> + err = ufs_qcom_phy_enable_iface_clk(phy_common);
> if (err) {
> - dev_err(dev, "%s enable phy ref clock failed, err=%d\n",
> + dev_err(dev, "%s enable phy iface clock failed, err=%d\n",
> __func__, err);
> goto out_disable_pll;
> }
>
> + err = ufs_qcom_phy_enable_ref_clk(phy_common);
> + if (err) {
> + dev_err(dev, "%s enable phy ref clock failed, err=%d\n",
> + __func__, err);
> + goto out_disable_iface_clk;
> + }
> +
> /* enable device PHY ref_clk pad rail */
> if (phy_common->vddp_ref_clk.reg) {
> err = ufs_qcom_phy_enable_vreg(dev,
> @@ -696,7 +693,9 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
> goto out;
>
> out_disable_ref_clk:
> - ufs_qcom_phy_disable_ref_clk(generic_phy);
> + ufs_qcom_phy_disable_ref_clk(phy_common);
> +out_disable_iface_clk:
> + ufs_qcom_phy_disable_iface_clk(phy_common);
> out_disable_pll:
> ufs_qcom_phy_disable_vreg(dev, &phy_common->vdda_pll);
> out_disable_phy:
> @@ -715,7 +714,8 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
> if (phy_common->vddp_ref_clk.reg)
> ufs_qcom_phy_disable_vreg(phy_common->dev,
> &phy_common->vddp_ref_clk);
> - ufs_qcom_phy_disable_ref_clk(generic_phy);
> + ufs_qcom_phy_disable_ref_clk(phy_common);
> + ufs_qcom_phy_disable_iface_clk(phy_common);
>
> ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_pll);
> ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_phy);
> diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
> index 3aedf73..6e4ce5f 100644
> --- a/drivers/scsi/ufs/ufs-qcom.c
> +++ b/drivers/scsi/ufs/ufs-qcom.c
> @@ -1112,17 +1112,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba
> *hba, bool on)
> return 0;
>
> if (on) {
> - err = ufs_qcom_phy_enable_iface_clk(host->generic_phy);
> - if (err)
> - goto out;
> -
> - err = ufs_qcom_phy_enable_ref_clk(host->generic_phy);
> - if (err) {
> - dev_err(hba->dev, "%s enable phy ref clock failed, err=%d\n",
> - __func__, err);
> - ufs_qcom_phy_disable_iface_clk(host->generic_phy);
> - goto out;
> - }
Now that you are moving these ref clk enable/disable to phy_power_on/off
and these phy_power_on/off are called only in runtime suspend/resume (3
seconds after last UFS access).
Goal is to disable the phy reference clock during aggressive gating
(10ms from last UFS access) so shouldn't we call the phy_power_on/off
from these setup_clocks() function as well?
> /* enable the device ref clock for HS mode*/
> if (ufshcd_is_hs_mode(&hba->pwr_info))
> ufs_qcom_dev_ref_clk_ctrl(host, true);
> @@ -1131,9 +1120,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba
> *hba, bool on)
> ufs_qcom_update_bus_bw_vote(host);
>
> } else {
> -
> - /* M-PHY RMMI interface clocks can be turned off */
> - ufs_qcom_phy_disable_iface_clk(host->generic_phy);
> if (!ufs_qcom_is_link_active(hba))
> /* disable device ref_clk */
> ufs_qcom_dev_ref_clk_ctrl(host, false);
> @@ -1146,7 +1132,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba
> *hba, bool on)
> dev_err(hba->dev, "%s: set bus vote failed %d\n",
> __func__, err);
>
> -out:
> return err;
> }
>
> diff --git a/include/linux/phy/phy-qcom-ufs.h
> b/include/linux/phy/phy-qcom-ufs.h
> index 9d18e9f..35c070e 100644
> --- a/include/linux/phy/phy-qcom-ufs.h
> +++ b/include/linux/phy/phy-qcom-ufs.h
> @@ -18,22 +18,6 @@
> #include "phy.h"
>
> /**
> - * ufs_qcom_phy_enable_ref_clk() - Enable the phy
> - * ref clock.
> - * @phy: reference to a generic phy
> - *
> - * returns 0 for success, and non-zero for error.
> - */
> -int ufs_qcom_phy_enable_ref_clk(struct phy *phy);
> -
> -/**
> - * ufs_qcom_phy_disable_ref_clk() - Disable the phy
> - * ref clock.
> - * @phy: reference to a generic phy.
> - */
> -void ufs_qcom_phy_disable_ref_clk(struct phy *phy);
> -
> -/**
> * ufs_qcom_phy_enable_dev_ref_clk() - Enable the device
> * ref clock.
> * @phy: reference to a generic phy.
> @@ -47,8 +31,6 @@ void ufs_qcom_phy_enable_dev_ref_clk(struct phy
> *phy);
> */
> void ufs_qcom_phy_disable_dev_ref_clk(struct phy *phy);
>
> -int ufs_qcom_phy_enable_iface_clk(struct phy *phy);
> -void ufs_qcom_phy_disable_iface_clk(struct phy *phy);
> int ufs_qcom_phy_start_serdes(struct phy *phy);
> int ufs_qcom_phy_set_tx_lane_enable(struct phy *phy, u32 tx_lanes);
> int ufs_qcom_phy_calibrate_phy(struct phy *phy, bool is_rate_B);
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-10-18 07:28, Vivek Gautam wrote:
> Do a phy_exit() over the ufs phy in the ufs qcom exit path
> to de-initialize the phy.
>
> Signed-off-by: Vivek Gautam <[email protected]>
> ---
>
> New patch added in v2 series.
>
> drivers/scsi/ufs/ufs-qcom.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
> index 6e4ce5f..dfd2af8 100644
> --- a/drivers/scsi/ufs/ufs-qcom.c
> +++ b/drivers/scsi/ufs/ufs-qcom.c
> @@ -1272,6 +1272,7 @@ static void ufs_qcom_exit(struct ufs_hba *hba)
>
> ufs_qcom_disable_lane_clks(host);
> phy_power_off(host->generic_phy);
> + phy_exit(host->generic_phy);
> }
>
> static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba
> *hba,
LGTM.
Reviewed-by: Subhash Jadavani <[email protected]>
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On 10/18/2016 07:28 AM, Vivek Gautam wrote:
> From: Yaniv Gardi <[email protected]>
>
> Since in future UFS Phy's the tx_iface_clk and rx_iface_clk
> are no longer exist, we should not fail when their initialization
> fail, but rather just report with debug message.
>
> Signed-off-by: Yaniv Gardi <[email protected]>
> Signed-off-by: Vivek Gautam <[email protected]>
> ---
Shouldn't we have a different compatible string on future UFS phys so
that we know which number of clks and what clks are required? That's how
we typically handle clk configurations changing. Making them optional
should really only be needed when they're really optional, i.e. things
will work fine if they're there or not.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-10-18 07:28, Vivek Gautam wrote:
> The common layer phy exit callback ufs_qcom_phy_exit()
> calls phy_power_off() that has no meaning when phy_power_off()
> callback is already registered with the phy provider and
> the consumer makes use of the same.
> Instead, add a no-op specific phy_exit() callback for now
> to add the exit sequence at a later point.
>
> Signed-off-by: Vivek Gautam <[email protected]>
> ---
>
> New patch added in v2 series.
>
> drivers/phy/phy-qcom-ufs-i.h | 1 -
> drivers/phy/phy-qcom-ufs-qmp-14nm.c | 7 ++++++-
> drivers/phy/phy-qcom-ufs-qmp-20nm.c | 7 ++++++-
> drivers/phy/phy-qcom-ufs.c | 17 ++++++-----------
> 4 files changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/phy/phy-qcom-ufs-i.h
> b/drivers/phy/phy-qcom-ufs-i.h
> index 69e836d..d505d98 100644
> --- a/drivers/phy/phy-qcom-ufs-i.h
> +++ b/drivers/phy/phy-qcom-ufs-i.h
> @@ -141,7 +141,6 @@ struct ufs_qcom_phy_specific_ops {
> struct ufs_qcom_phy *get_ufs_qcom_phy(struct phy *generic_phy);
> int ufs_qcom_phy_power_on(struct phy *generic_phy);
> int ufs_qcom_phy_power_off(struct phy *generic_phy);
> -int ufs_qcom_phy_exit(struct phy *generic_phy);
> int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common);
> int ufs_qcom_phy_init_vregulators(struct ufs_qcom_phy *phy_common);
> int ufs_qcom_phy_remove(struct phy *generic_phy,
> diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> index a60cf34..061604f 100644
> --- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> +++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> @@ -47,6 +47,11 @@ static int ufs_qcom_phy_qmp_14nm_init(struct phy
> *generic_phy)
> return 0;
> }
>
> +static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy)
> +{
> + return 0;
> +}
> +
> static
> void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy,
> bool val)
> {
> @@ -94,7 +99,7 @@ static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct
> ufs_qcom_phy *phy_common)
>
> static const struct phy_ops ufs_qcom_phy_qmp_14nm_phy_ops = {
> .init = ufs_qcom_phy_qmp_14nm_init,
> - .exit = ufs_qcom_phy_exit,
> + .exit = ufs_qcom_phy_qmp_14nm_exit,
> .power_on = ufs_qcom_phy_power_on,
> .power_off = ufs_qcom_phy_power_off,
> .owner = THIS_MODULE,
> diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> index dfc5175..1a26a64 100644
> --- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> +++ b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> @@ -66,6 +66,11 @@ static int ufs_qcom_phy_qmp_20nm_init(struct phy
> *generic_phy)
> return 0;
> }
>
> +static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy)
> +{
> + return 0;
> +}
> +
> static
> void ufs_qcom_phy_qmp_20nm_power_control(struct ufs_qcom_phy *phy,
> bool val)
> {
> @@ -152,7 +157,7 @@ static int
> ufs_qcom_phy_qmp_20nm_is_pcs_ready(struct ufs_qcom_phy *phy_common)
>
> static const struct phy_ops ufs_qcom_phy_qmp_20nm_phy_ops = {
> .init = ufs_qcom_phy_qmp_20nm_init,
> - .exit = ufs_qcom_phy_exit,
> + .exit = ufs_qcom_phy_qmp_20nm_exit,
> .power_on = ufs_qcom_phy_power_on,
> .power_off = ufs_qcom_phy_power_off,
> .owner = THIS_MODULE,
> diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
> index a425cc2..494f90f 100644
> --- a/drivers/phy/phy-qcom-ufs.c
> +++ b/drivers/phy/phy-qcom-ufs.c
> @@ -615,17 +615,6 @@ int ufs_qcom_phy_calibrate_phy(struct phy
> *generic_phy, bool is_rate_B)
> }
> EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
>
> -int ufs_qcom_phy_exit(struct phy *generic_phy)
> -{
> - struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
> -
> - if (ufs_qcom_phy->is_powered_on)
> - phy_power_off(generic_phy);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_exit);
> -
> int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy)
> {
> struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
> @@ -647,6 +636,9 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy)
> struct device *dev = phy_common->dev;
> int err;
>
> + if (phy_common->is_powered_on)
> + return 0;
> +
> err = ufs_qcom_phy_enable_vreg(dev, &phy_common->vdda_phy);
> if (err) {
> dev_err(dev, "%s enable vdda_phy failed, err=%d\n",
> @@ -709,6 +701,9 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
> {
> struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
>
> + if (!phy_common->is_powered_on)
> + return 0;
> +
> phy_common->phy_spec_ops->power_control(phy_common, false);
>
> if (phy_common->vddp_ref_clk.reg)
LGTM , Reviewed-by: Subhash Jadavani <[email protected]>
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
Hi,
On Wed, Oct 19, 2016 at 2:48 AM, Stephen Boyd <[email protected]> wrote:
> On 10/18/2016 07:28 AM, Vivek Gautam wrote:
>> From: Yaniv Gardi <[email protected]>
>>
>> Since in future UFS Phy's the tx_iface_clk and rx_iface_clk
>> are no longer exist, we should not fail when their initialization
>> fail, but rather just report with debug message.
>>
>> Signed-off-by: Yaniv Gardi <[email protected]>
>> Signed-off-by: Vivek Gautam <[email protected]>
>> ---
>
> Shouldn't we have a different compatible string on future UFS phys so
> that we know which number of clks and what clks are required? That's how
> we typically handle clk configurations changing. Making them optional
> should really only be needed when they're really optional, i.e. things
> will work fine if they're there or not.
Correct. It makes sense to have different compatible strings for different
versions.
I will gather more information about previous versions that required
this clock, and update as suggested.
Regards
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
Hi,
On Wed, Oct 19, 2016 at 1:43 AM, Subhash Jadavani
<[email protected]> wrote:
> On 2016-10-18 07:28, Vivek Gautam wrote:
>>
>> Add phy clock enable code to phy_power_on/off callbacks, and
>> remove explicit calls to enable these phy clocks from the
>> ufs-qcom hcd driver.
>>
>> Signed-off-by: Vivek Gautam <[email protected]>
>> ---
>>
>> Changes since v1:
>> - staticized ufs_qcom_phy_enable(/disable)_ref_clk(),
>> - staticized ufs_qcom_phy_enable(/disable)_iface_clk()
>> - removed function declaration and export symbol for these APIs.
[snip]
>> --- a/drivers/scsi/ufs/ufs-qcom.c
>> +++ b/drivers/scsi/ufs/ufs-qcom.c
>> @@ -1112,17 +1112,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba
>> *hba, bool on)
>> return 0;
>>
>> if (on) {
>> - err = ufs_qcom_phy_enable_iface_clk(host->generic_phy);
>> - if (err)
>> - goto out;
>> -
>> - err = ufs_qcom_phy_enable_ref_clk(host->generic_phy);
>> - if (err) {
>> - dev_err(hba->dev, "%s enable phy ref clock failed,
>> err=%d\n",
>> - __func__, err);
>> - ufs_qcom_phy_disable_iface_clk(host->generic_phy);
>> - goto out;
>> - }
>
>
> Now that you are moving these ref clk enable/disable to phy_power_on/off and
> these phy_power_on/off are called only in runtime suspend/resume (3 seconds
> after last UFS access).
> Goal is to disable the phy reference clock during aggressive gating (10ms
> from last UFS access) so shouldn't we call the phy_power_on/off from these
> setup_clocks() function as well?
>
So setup_clocks() is called for aggressive clock gating as well ?
If that's the case then yes, we may need to call. But we should try to
understand here. The phy_power_off turns off all the clocks - reflclk,
and other interface clocks. Do we want all of them to be turned off ?
phy_power_off will also turn off the PHY. Do we want all this for aggressive
clock gating ?
[snip]
Regards
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-10-19 10:45, Vivek Gautam wrote:
> Hi,
>
>
> On Wed, Oct 19, 2016 at 1:43 AM, Subhash Jadavani
> <[email protected]> wrote:
>> On 2016-10-18 07:28, Vivek Gautam wrote:
>>>
>>> Add phy clock enable code to phy_power_on/off callbacks, and
>>> remove explicit calls to enable these phy clocks from the
>>> ufs-qcom hcd driver.
>>>
>>> Signed-off-by: Vivek Gautam <[email protected]>
>>> ---
>>>
>>> Changes since v1:
>>> - staticized ufs_qcom_phy_enable(/disable)_ref_clk(),
>>> - staticized ufs_qcom_phy_enable(/disable)_iface_clk()
>>> - removed function declaration and export symbol for these APIs.
>
> [snip]
>
>>> --- a/drivers/scsi/ufs/ufs-qcom.c
>>> +++ b/drivers/scsi/ufs/ufs-qcom.c
>>> @@ -1112,17 +1112,6 @@ static int ufs_qcom_setup_clocks(struct
>>> ufs_hba
>>> *hba, bool on)
>>> return 0;
>>>
>>> if (on) {
>>> - err =
>>> ufs_qcom_phy_enable_iface_clk(host->generic_phy);
>>> - if (err)
>>> - goto out;
>>> -
>>> - err = ufs_qcom_phy_enable_ref_clk(host->generic_phy);
>>> - if (err) {
>>> - dev_err(hba->dev, "%s enable phy ref clock
>>> failed,
>>> err=%d\n",
>>> - __func__, err);
>>> -
>>> ufs_qcom_phy_disable_iface_clk(host->generic_phy);
>>> - goto out;
>>> - }
>>
>>
>> Now that you are moving these ref clk enable/disable to
>> phy_power_on/off and
>> these phy_power_on/off are called only in runtime suspend/resume (3
>> seconds
>> after last UFS access).
>> Goal is to disable the phy reference clock during aggressive gating
>> (10ms
>> from last UFS access) so shouldn't we call the phy_power_on/off from
>> these
>> setup_clocks() function as well?
>>
>
> So setup_clocks() is called for aggressive clock gating as well ?
> If that's the case then yes, we may need to call. But we should try to
> understand here. The phy_power_off turns off all the clocks - reflclk,
> and other interface clocks. Do we want all of them to be turned off ?
Yes, we want to turn off the ref clock (& other clocks) during
aggressive gating.
>
> phy_power_off will also turn off the PHY. Do we want all this for
> aggressive
> clock gating ?
Yes, PHY rails can be powered off both during the aggressive clk gating
and runtime suspend. But as the regulator on/off latencies could be
higher (especially for the shared rail), we were turning them off doing
it in runtime suspend only (via phy_power_off()).
Now that phy_power_on/off is managing both clocks and regulators, and we
will really want to turn off the ref clocks during clock gating, there
is no option but to call phy_power_on/off during aggressive gating.
>
>
> [snip]
>
>
> Regards
> Vivek
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On Thu, Oct 20, 2016 at 12:48 AM, Subhash Jadavani
<[email protected]> wrote:
> On 2016-10-19 10:45, Vivek Gautam wrote:
>>
>> Hi,
>>
>>
>> On Wed, Oct 19, 2016 at 1:43 AM, Subhash Jadavani
>> <[email protected]> wrote:
>>>
>>> On 2016-10-18 07:28, Vivek Gautam wrote:
>>>>
>>>>
>>>> Add phy clock enable code to phy_power_on/off callbacks, and
>>>> remove explicit calls to enable these phy clocks from the
>>>> ufs-qcom hcd driver.
>>>>
>>>> Signed-off-by: Vivek Gautam <[email protected]>
>>>> ---
>>>>
>>>> Changes since v1:
>>>> - staticized ufs_qcom_phy_enable(/disable)_ref_clk(),
>>>> - staticized ufs_qcom_phy_enable(/disable)_iface_clk()
>>>> - removed function declaration and export symbol for these APIs.
>>
>>
>> [snip]
>>
>>>> --- a/drivers/scsi/ufs/ufs-qcom.c
>>>> +++ b/drivers/scsi/ufs/ufs-qcom.c
>>>> @@ -1112,17 +1112,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba
>>>> *hba, bool on)
>>>> return 0;
>>>>
>>>> if (on) {
>>>> - err = ufs_qcom_phy_enable_iface_clk(host->generic_phy);
>>>> - if (err)
>>>> - goto out;
>>>> -
>>>> - err = ufs_qcom_phy_enable_ref_clk(host->generic_phy);
>>>> - if (err) {
>>>> - dev_err(hba->dev, "%s enable phy ref clock
>>>> failed,
>>>> err=%d\n",
>>>> - __func__, err);
>>>> -
>>>> ufs_qcom_phy_disable_iface_clk(host->generic_phy);
>>>> - goto out;
>>>> - }
>>>
>>>
>>>
>>> Now that you are moving these ref clk enable/disable to phy_power_on/off
>>> and
>>> these phy_power_on/off are called only in runtime suspend/resume (3
>>> seconds
>>> after last UFS access).
>>> Goal is to disable the phy reference clock during aggressive gating (10ms
>>> from last UFS access) so shouldn't we call the phy_power_on/off from
>>> these
>>> setup_clocks() function as well?
>>>
>>
>> So setup_clocks() is called for aggressive clock gating as well ?
>> If that's the case then yes, we may need to call. But we should try to
>> understand here. The phy_power_off turns off all the clocks - reflclk,
>> and other interface clocks. Do we want all of them to be turned off ?
>
>
> Yes, we want to turn off the ref clock (& other clocks) during aggressive
> gating.
Ok.
>
>>
>> phy_power_off will also turn off the PHY. Do we want all this for
>> aggressive
>> clock gating ?
>
>
> Yes, PHY rails can be powered off both during the aggressive clk gating and
> runtime suspend. But as the regulator on/off latencies could be higher
> (especially for the shared rail), we were turning them off doing it in
> runtime suspend only (via phy_power_off()).
> Now that phy_power_on/off is managing both clocks and regulators, and we
> will really want to turn off the ref clocks during clock gating, there is no
> option but to call phy_power_on/off during aggressive gating.
Alright then, i will update the change to add phy_power_off/on()
during aggressive clock gating.
Thanks
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
>>>>> "Vivek" == Vivek Gautam <[email protected]> writes:
Vivek,
Vivek> These patches cleanup the ufs phy driver to an extent.
Vivek> Subsequent patches will target to clean the phy_init() of these
Vivek> qcom-ufs phy drivers in order to get rid of a number of exported
Vivek> APIs that phy drivers expose for ufs-qcom hcd driver to use.
Please submit a v3 which addresses the review comments and adds the
relevant Reviewed-by: tags.
Thanks!
--
Martin K. Petersen Oracle Linux Engineering
Hi Martin,
On Tue, Oct 25, 2016 at 6:10 AM, Martin K. Petersen
<[email protected]> wrote:
>>>>>> "Vivek" == Vivek Gautam <[email protected]> writes:
>
> Vivek,
>
> Vivek> These patches cleanup the ufs phy driver to an extent.
> Vivek> Subsequent patches will target to clean the phy_init() of these
> Vivek> qcom-ufs phy drivers in order to get rid of a number of exported
> Vivek> APIs that phy drivers expose for ufs-qcom hcd driver to use.
>
> Please submit a v3 which addresses the review comments and adds the
> relevant Reviewed-by: tags.
>
> Thanks!
Sure, i will send the v3 in couple of days.
Thanks
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On Tuesday 18 October 2016 07:58 PM, Vivek Gautam wrote:
> remove() callback does a phy_exit() only and nothing else now.
remove callback calls a phy_power_off() ;-)
-Kishon
> The phy_exit() over the generic phy is called from the phy
> consumer, and phy provider driver should not explicitly need to
> call any phy_exit().
> So discard the remove callback for qcom-ufs phy platform drivers.
>
> Signed-off-by: Vivek Gautam <[email protected]>
> Reviewed-by: Subhash Jadavani <[email protected]>
> ---
>
> No change since v1.
>
> drivers/phy/phy-qcom-ufs-qmp-14nm.c | 16 ----------------
> drivers/phy/phy-qcom-ufs-qmp-20nm.c | 16 ----------------
> drivers/phy/phy-qcom-ufs.c | 9 ---------
> 3 files changed, 41 deletions(-)
>
> diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> index 6ee5149..a305016 100644
> --- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> +++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> @@ -163,21 +163,6 @@ out:
> return err;
> }
>
> -static int ufs_qcom_phy_qmp_14nm_remove(struct platform_device *pdev)
> -{
> - struct device *dev = &pdev->dev;
> - struct phy *generic_phy = to_phy(dev);
> - struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
> - int err = 0;
> -
> - err = ufs_qcom_phy_remove(generic_phy, ufs_qcom_phy);
> - if (err)
> - dev_err(dev, "%s: ufs_qcom_phy_remove failed = %d\n",
> - __func__, err);
> -
> - return err;
> -}
> -
> static const struct of_device_id ufs_qcom_phy_qmp_14nm_of_match[] = {
> {.compatible = "qcom,ufs-phy-qmp-14nm"},
> {},
> @@ -186,7 +171,6 @@ MODULE_DEVICE_TABLE(of, ufs_qcom_phy_qmp_14nm_of_match);
>
> static struct platform_driver ufs_qcom_phy_qmp_14nm_driver = {
> .probe = ufs_qcom_phy_qmp_14nm_probe,
> - .remove = ufs_qcom_phy_qmp_14nm_remove,
> .driver = {
> .of_match_table = ufs_qcom_phy_qmp_14nm_of_match,
> .name = "ufs_qcom_phy_qmp_14nm",
> diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> index 770087a..2db1fbb 100644
> --- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> +++ b/drivers/phy/phy-qcom-ufs-qmp-20nm.c
> @@ -219,21 +219,6 @@ out:
> return err;
> }
>
> -static int ufs_qcom_phy_qmp_20nm_remove(struct platform_device *pdev)
> -{
> - struct device *dev = &pdev->dev;
> - struct phy *generic_phy = to_phy(dev);
> - struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
> - int err = 0;
> -
> - err = ufs_qcom_phy_remove(generic_phy, ufs_qcom_phy);
> - if (err)
> - dev_err(dev, "%s: ufs_qcom_phy_remove failed = %d\n",
> - __func__, err);
> -
> - return err;
> -}
> -
> static const struct of_device_id ufs_qcom_phy_qmp_20nm_of_match[] = {
> {.compatible = "qcom,ufs-phy-qmp-20nm"},
> {},
> @@ -242,7 +227,6 @@ MODULE_DEVICE_TABLE(of, ufs_qcom_phy_qmp_20nm_of_match);
>
> static struct platform_driver ufs_qcom_phy_qmp_20nm_driver = {
> .probe = ufs_qcom_phy_qmp_20nm_probe,
> - .remove = ufs_qcom_phy_qmp_20nm_remove,
> .driver = {
> .of_match_table = ufs_qcom_phy_qmp_20nm_of_match,
> .name = "ufs_qcom_phy_qmp_20nm",
> diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
> index f639a7c..b8f9286 100644
> --- a/drivers/phy/phy-qcom-ufs.c
> +++ b/drivers/phy/phy-qcom-ufs.c
> @@ -645,15 +645,6 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
> }
> EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
>
> -int ufs_qcom_phy_remove(struct phy *generic_phy,
> - struct ufs_qcom_phy *ufs_qcom_phy)
> -{
> - phy_power_off(generic_phy);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL_GPL(ufs_qcom_phy_remove);
> -
> int ufs_qcom_phy_exit(struct phy *generic_phy)
> {
> struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
>
Hi,
On Thu, Oct 27, 2016 at 1:50 AM, Kishon Vijay Abraham I <[email protected]> wrote:
>
>
> On Tuesday 18 October 2016 07:58 PM, Vivek Gautam wrote:
>> remove() callback does a phy_exit() only and nothing else now.
>
> remove callback calls a phy_power_off() ;-)
Yea, correct. My bad. :)
Will correct.
[snip]
Thanks
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
Hi,
On Wed, Oct 19, 2016 at 10:50 PM, Vivek Gautam
<[email protected]> wrote:
> Hi,
>
>
> On Wed, Oct 19, 2016 at 2:48 AM, Stephen Boyd <[email protected]> wrote:
>> On 10/18/2016 07:28 AM, Vivek Gautam wrote:
>>> From: Yaniv Gardi <[email protected]>
>>>
>>> Since in future UFS Phy's the tx_iface_clk and rx_iface_clk
>>> are no longer exist, we should not fail when their initialization
>>> fail, but rather just report with debug message.
>>>
>>> Signed-off-by: Yaniv Gardi <[email protected]>
>>> Signed-off-by: Vivek Gautam <[email protected]>
>>> ---
>>
>> Shouldn't we have a different compatible string on future UFS phys so
>> that we know which number of clks and what clks are required? That's how
>> we typically handle clk configurations changing. Making them optional
>> should really only be needed when they're really optional, i.e. things
>> will work fine if they're there or not.
>
> Correct. It makes sense to have different compatible strings for different
> versions.
> I will gather more information about previous versions that required
> this clock, and update as suggested.
The tx/rx_face clocks are not available on some of the recent chips,
such as msm8996. Older chips with this 14nm ufs phy had handles
for tx/rx_iface clocks.
So, i will add new compatible string for msm8996 -
"qcom,msm8996-ufs-phy-qmp-14nm"
This can be used with chips further on that are going to use the same ufs phy.
Regards
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project