Hi,
On Thu, Oct 11, 2018 at 5:33 AM Can Guo <cang@xxxxxxxxxxxxxx> wrote:
static int ufs_qcom_host_clk_get(struct device *dev,
- const char *name, struct clk **clk_out)
+ const char *name, struct clk **clk_out, bool optional)
{
struct clk *clk;
int err = 0;
clk = devm_clk_get(dev, name);
- if (IS_ERR(clk)) {
+ if (clk == ERR_PTR(-EPROBE_DEFER)) {
+ err = -EPROBE_DEFER;
+ dev_warn(dev, "required clock %s hasn't probed yet, err %d\n",
+ name, err);
+ } else if (IS_ERR(clk)) {
+ if (optional)
+ return 0;
Change this function to:
static int ufs_qcom_host_clk_get(struct device *dev,
const char *name, struct clk **clk_out, bool optional)
{
struct clk *clk;
int err;
clk = devm_clk_get(dev, name);
if (!IS_ERR(clk)) {
*clk_out = clk;
return 0;
}
err = PTR_ERR(clk);
if (optional && err == -ENOENT) {
*clk_out = NULL;
return 0;
}
if (err != -EPROBE_DEFER)
dev_err(dev, "failed to get %s err %d",
name, err);
return err;
}
Specifically:
* Typically it just spams the log to print something when you see an
-EPROBE_DEFER.
* If a clock is optional you should only consider things a success
only if "-ENOENT" was returned. All other errors should be considered
fatal.
* If a clock is optional it's slightly cleaner to set *clk_out to
NULL. I know you're initting global data that happened to already be
NULL by default, but it still feels nice for the abstraction of the
function to do this.
* Please don't pass __func__ to your error messages.
err = PTR_ERR(clk);
dev_err(dev, "%s: failed to get %s err %d",
__func__, name, err);
@@ -113,10 +119,10 @@ static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host)
if (!host->is_lane_clks_enabled)
return;
- if (host->hba->lanes_per_direction > 1)
+ if (host->tx_l1_sync_clk)
Remove this "if". Always call clk_disable_unprepare() which will be a
no-op if "host->tx_l1_sync_clk" is NULL. clk_disable_unprepare() is a
no-op for NULL clocks by design specifically to make code like this
cleaner.
clk_disable_unprepare(host->tx_l1_sync_clk);
clk_disable_unprepare(host->tx_l0_sync_clk);
- if (host->hba->lanes_per_direction > 1)
+ if (host->rx_l1_sync_clk)
Remove this "if". Always call clk_disable_unprepare() which will be a
no-op if "host->rx_l1_sync_clk" is NULL. clk_disable_unprepare() is a
no-op for NULL clocks by design specifically to make code like this
cleaner.
clk_disable_unprepare(host->rx_l1_sync_clk);
clk_disable_unprepare(host->rx_l0_sync_clk);
@@ -141,12 +147,14 @@ static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host)
if (err)
goto disable_rx_l0;
- if (host->hba->lanes_per_direction > 1) {
+ if (host->rx_l1_sync_clk) {
Remove this "if". Always call ufs_qcom_host_clk_enable(). The
clk_prepare_enable() inside ufs_qcom_host_clk_enable() will be a no-op
if "host->rx_l1_sync_clk" is NULL and will return 0 (no error).
err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
host->rx_l1_sync_clk);
if (err)
goto disable_tx_l0;
+ }
+ if (host->tx_l1_sync_clk) {
Remove this "if". Always call ufs_qcom_host_clk_enable(). The
clk_prepare_enable() inside ufs_qcom_host_clk_enable() will be a no-op
if "host->tx_l1_sync_clk" is NULL and will return 0 (no error).
-Doug