From 8a21ff1c8a07ccb8ef6cb353891f133da7949168 Mon Sep 17 00:00:00 2001 From: Deepak Katragadda Date: Mon, 28 Aug 2017 13:14:34 -0700 Subject: [PATCH 1/2] clk: qcom: clk-aop-qmp: Fix issue with registering the clock provider While registering the QDSS clock provider with the framework, pass in the clk data array with references to both the QDSS clocks. In its current implementation, the QDSS clock driver only adds the clk_get callback for one of the clocks which leads to clients getting the clock handle to it when they try to reference either of the clocks. Change-Id: I41fc4c1ea57ad0f59a1af126b6025c21af72cbe2 Signed-off-by: Deepak Katragadda --- drivers/clk/qcom/clk-aop-qmp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-aop-qmp.c b/drivers/clk/qcom/clk-aop-qmp.c index 903ef9e171dd..3884fd1913a8 100644 --- a/drivers/clk/qcom/clk-aop-qmp.c +++ b/drivers/clk/qcom/clk-aop-qmp.c @@ -256,6 +256,7 @@ static int aop_qmp_clk_probe(struct platform_device *pdev) struct clk *clk = NULL; struct device_node *np = pdev->dev.of_node; struct mbox_chan *mbox = NULL; + struct clk_onecell_data *clk_data; int num_clks = ARRAY_SIZE(aop_qmp_clk_hws); int ret = 0, i = 0; @@ -267,6 +268,17 @@ static int aop_qmp_clk_probe(struct platform_device *pdev) if (ret < 0) return ret; + clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->clks = devm_kcalloc(&pdev->dev, num_clks, + sizeof(*clk_data->clks), GFP_KERNEL); + if (!clk_data->clks) + return -ENOMEM; + + clk_data->clk_num = num_clks; + for (i = 1; i < num_clks; i++) { if (!aop_qmp_clk_hws[i]) continue; @@ -289,14 +301,16 @@ static int aop_qmp_clk_probe(struct platform_device *pdev) for (i = 0; i < num_clks; i++) { if (!aop_qmp_clk_hws[i]) continue; + clk = devm_clk_register(&pdev->dev, aop_qmp_clk_hws[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); goto fail; } + clk_data->clks[i] = clk; } - ret = of_clk_add_provider(np, of_clk_src_simple_get, clk); + ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); if (ret) { dev_err(&pdev->dev, "Failed to register clock provider\n"); goto fail; From 860fa9a8ce2304422a35a5894d571b55849667eb Mon Sep 17 00:00:00 2001 From: David Collins Date: Fri, 26 Jan 2018 18:05:53 -0800 Subject: [PATCH 2/2] clk: qcom: clk-aop-qmp: pass mbox pointer by reference in qmp_update_client Pass the mbox pointer to qmp_update_client() by reference so that it is possible to update its value inside of the function. Change-Id: Iefa4587f6e77b6e7029ed07236fa3a51ca09c129 Signed-off-by: David Collins --- drivers/clk/qcom/clk-aop-qmp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clk/qcom/clk-aop-qmp.c b/drivers/clk/qcom/clk-aop-qmp.c index 3884fd1913a8..ea6c8a4f93ca 100644 --- a/drivers/clk/qcom/clk-aop-qmp.c +++ b/drivers/clk/qcom/clk-aop-qmp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -222,7 +222,7 @@ static struct clk_hw *aop_qmp_clk_hws[] = { }; static int qmp_update_client(struct clk_hw *hw, struct device *dev, - struct mbox_chan *mbox) + struct mbox_chan **mbox) { struct clk_aop_qmp *clk_aop = to_aop_qmp_clk(hw); int ret; @@ -233,13 +233,13 @@ static int qmp_update_client(struct clk_hw *hw, struct device *dev, clk_aop->cl.tx_tout = MBOX_TOUT_MS; clk_aop->cl.knows_txdone = false; - if (mbox) { - clk_aop->mbox = mbox; + if (*mbox) { + clk_aop->mbox = *mbox; return 0; } /* Allocate mailbox channel */ - mbox = clk_aop->mbox = mbox_request_channel(&clk_aop->cl, 0); + *mbox = clk_aop->mbox = mbox_request_channel(&clk_aop->cl, 0); if (IS_ERR(clk_aop->mbox)) { ret = PTR_ERR(clk_aop->mbox); if (ret != -EPROBE_DEFER) @@ -264,7 +264,7 @@ static int aop_qmp_clk_probe(struct platform_device *pdev) * Allocate mbox channel for the first clock client. The same channel * would be used for the rest of the clock clients. */ - ret = qmp_update_client(aop_qmp_clk_hws[i], &pdev->dev, mbox); + ret = qmp_update_client(aop_qmp_clk_hws[i], &pdev->dev, &mbox); if (ret < 0) return ret; @@ -282,7 +282,7 @@ static int aop_qmp_clk_probe(struct platform_device *pdev) for (i = 1; i < num_clks; i++) { if (!aop_qmp_clk_hws[i]) continue; - ret = qmp_update_client(aop_qmp_clk_hws[i], &pdev->dev, mbox); + ret = qmp_update_client(aop_qmp_clk_hws[i], &pdev->dev, &mbox); if (ret < 0) { dev_err(&pdev->dev, "Failed to update QMP client %d\n", ret);