diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 1e347092a7d8d..45fb7b080e345 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -361,7 +361,9 @@ static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host) if (!host->is_lane_clks_enabled) return; - clk_bulk_disable_unprepare(host->num_clks, host->clks); + clk_disable_unprepare(host->rx_lane1_sync_clk); + clk_disable_unprepare(host->rx_lane0_sync_clk); + clk_disable_unprepare(host->tx_lane0_sync_clk); host->is_lane_clks_enabled = false; } @@ -370,28 +372,56 @@ static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host) { int err; - err = clk_bulk_prepare_enable(host->num_clks, host->clks); + if (host->is_lane_clks_enabled) + return 0; + + err = clk_prepare_enable(host->tx_lane0_sync_clk); if (err) - return err; + goto out; - host->is_lane_clks_enabled = true; + err = clk_prepare_enable(host->rx_lane0_sync_clk); + if (err) + goto out_disable_tx_lane0; + + err = clk_prepare_enable(host->rx_lane1_sync_clk); + if (err) + goto out_disable_rx_lane0; + host->is_lane_clks_enabled = true; return 0; + +out_disable_rx_lane0: + clk_disable_unprepare(host->rx_lane0_sync_clk); +out_disable_tx_lane0: + clk_disable_unprepare(host->tx_lane0_sync_clk); +out: + return err; } static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host) { - int err; struct device *dev = host->hba->dev; if (has_acpi_companion(dev)) return 0; - err = devm_clk_bulk_get_all(dev, &host->clks); - if (err <= 0) - return err; - - host->num_clks = err; + host->tx_lane0_sync_clk = devm_clk_get(dev, "tx_lane0_sync_clk"); + if (IS_ERR(host->tx_lane0_sync_clk)) + return dev_err_probe(dev, PTR_ERR(host->tx_lane0_sync_clk), + "failed to get tx_lane0_sync_clk\n"); + + host->rx_lane0_sync_clk = devm_clk_get(dev, "rx_lane0_sync_clk"); + if (IS_ERR(host->rx_lane0_sync_clk)) + return dev_err_probe(dev, PTR_ERR(host->rx_lane0_sync_clk), + "failed to get rx_lane0_sync_clk\n"); + + /* In case of single lane per direction, don't read lane1 clocks */ + if (host->hba->lanes_per_direction > 1) { + host->rx_lane1_sync_clk = devm_clk_get(dev, "rx_lane1_sync_clk"); + if (IS_ERR(host->rx_lane1_sync_clk)) + return dev_err_probe(dev, PTR_ERR(host->rx_lane1_sync_clk), + "failed to get rx_lane1_sync_clk\n"); + } return 0; } diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h index 380d02333d382..bad2dd769f7fa 100644 --- a/drivers/ufs/host/ufs-qcom.h +++ b/drivers/ufs/host/ufs-qcom.h @@ -279,8 +279,9 @@ struct ufs_qcom_host { struct phy *generic_phy; struct ufs_hba *hba; struct ufs_pa_layer_attr dev_req_params; - struct clk_bulk_data *clks; - u32 num_clks; + struct clk *tx_lane0_sync_clk; + struct clk *rx_lane0_sync_clk; + struct clk *rx_lane1_sync_clk; bool is_lane_clks_enabled; struct icc_path *icc_ddr;