From 51cd983d87bb8ed8610bfcc10f7da768de76679e Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Tue, 18 Feb 2020 02:39:11 -0800 Subject: [PATCH] interconnect: qcom: Configure QoS when provider is sync stated In the current code, QoS configuration is attempted before the votes for MM0 are in place. That's why we may observe some hangs during boot. Move all QoS configuration to happen during the sync_state to ensure that the keepalive votes are already in place and also enable the relevant interface clocks while we setup QoS. Change-Id: Ief6817b8e32423f07fece4cf04068e7311c9f8cb Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/lahaina.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/interconnect/qcom/lahaina.c b/drivers/interconnect/qcom/lahaina.c index 907046c5b08b..66a3f80fc320 100644 --- a/drivers/interconnect/qcom/lahaina.c +++ b/drivers/interconnect/qcom/lahaina.c @@ -818,10 +818,6 @@ static int qnoc_probe(struct platform_device *pdev) if (qp->num_clks < 0) return qp->num_clks; - ret = clk_bulk_prepare_enable(qp->num_clks, qp->clks); - if (ret) - return ret; - for (i = 0; i < num_nodes; i++) { size_t j; @@ -848,14 +844,9 @@ static int qnoc_probe(struct platform_device *pdev) icc_link_create(node, qnodes[i]->links[j]); data->nodes[i] = node; - if (qnodes[i]->noc_ops) - qnodes[i]->noc_ops->set_qos(qnodes[i]); } data->num_nodes = num_nodes; - clk_bulk_disable_unprepare(qp->num_clks, qp->clks); - clk_bulk_put_all(qp->num_clks, qp->clks); - for (i = 0; i < qp->num_bcms; i++) qcom_icc_bcm_init(qp->bcms[i], &pdev->dev); @@ -869,8 +860,6 @@ static int qnoc_probe(struct platform_device *pdev) return ret; err: - clk_bulk_disable_unprepare(qp->num_clks, qp->clks); - clk_bulk_put_all(qp->num_clks, qp->clks); list_for_each_entry(node, &provider->nodes, node_list) { icc_node_del(node); icc_node_destroy(node->id); @@ -925,11 +914,26 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static void qnoc_sync_state(struct device *dev) { - struct qcom_icc_provider *qp; + struct platform_device *pdev = to_platform_device(dev); + struct qcom_icc_provider *qp = platform_get_drvdata(pdev); + struct icc_provider *provider = &qp->provider; + struct qcom_icc_node *qnode; + struct icc_node *node; mutex_lock(&probe_list_lock); probe_count++; + clk_bulk_prepare_enable(qp->num_clks, qp->clks); + + list_for_each_entry(node, &provider->nodes, node_list) { + qnode = node->data; + if (qnode && qnode->noc_ops) + qnode->noc_ops->set_qos(qnode); + } + + clk_bulk_disable_unprepare(qp->num_clks, qp->clks); + clk_bulk_put_all(qp->num_clks, qp->clks); + if (probe_count < ARRAY_SIZE(qnoc_of_match) - 1) { mutex_unlock(&probe_list_lock); return;