From c3aaf706c3a4945ff5f2beed348616262fefc5e8 Mon Sep 17 00:00:00 2001 From: Avinash Philip Date: Sun, 14 Jun 2020 15:08:38 +0530 Subject: [PATCH] drver:soc:llcc_perfmon: qdss clk node control qdss clock needs to be enabled on llcc_perfmon counter to function. Enable/disable clock on Start/Stop llcc_perfmon commands. Change-Id: Ic75119a08f0be1deadcdc694f27098296bfda07e Signed-off-by: Avinash Philip --- drivers/soc/qcom/llcc_perfmon.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/soc/qcom/llcc_perfmon.c b/drivers/soc/qcom/llcc_perfmon.c index 99278c99cc31..f1794e906351 100644 --- a/drivers/soc/qcom/llcc_perfmon.c +++ b/drivers/soc/qcom/llcc_perfmon.c @@ -69,6 +69,7 @@ struct event_port_ops { * @expires: timer expire time in nano seconds * @num_mc: number of MCS * @version: Version information of llcc block + * @clk: clock node to enable qdss */ struct llcc_perfmon_private { struct regmap *llcc_map; @@ -86,6 +87,7 @@ struct llcc_perfmon_private { ktime_t expires; unsigned int num_mc; unsigned int version; + struct clk *clock; }; static inline void llcc_bcast_write(struct llcc_perfmon_private *llcc_priv, @@ -500,6 +502,7 @@ static ssize_t perfmon_start_store(struct device *dev, struct llcc_perfmon_private *llcc_priv = dev_get_drvdata(dev); uint32_t val = 0, mask_val; unsigned long start; + int ret; if (kstrtoul(buf, 0, &start)) return -EINVAL; @@ -512,6 +515,12 @@ static ssize_t perfmon_start_store(struct device *dev, return -EINVAL; } + ret = clk_prepare_enable(llcc_priv->clock); + if (ret) { + mutex_unlock(&llcc_priv->mutex); + return -EINVAL; + } + val = MANUAL_MODE | MONITOR_EN; if (llcc_priv->expires) { if (hrtimer_is_queued(&llcc_priv->hrtimer)) @@ -534,6 +543,10 @@ static ssize_t perfmon_start_store(struct device *dev, mask_val = PERFMON_MODE_MONITOR_MODE_MASK | PERFMON_MODE_MONITOR_EN_MASK; llcc_bcast_modify(llcc_priv, PERFMON_MODE, val, mask_val); + + if (!start) + clk_disable_unprepare(llcc_priv->clock); + mutex_unlock(&llcc_priv->mutex); return count; } @@ -1269,6 +1282,12 @@ static int llcc_perfmon_probe(struct platform_device *pdev) else if (val == LLCC_VERSION_2) llcc_priv->version = REV_2; + llcc_priv->clock = devm_clk_get(pdev->dev.parent, "qdss_clk"); + if (IS_ERR_OR_NULL(llcc_priv->clock)) { + pr_err("failed to get clock node\n"); + return PTR_ERR(llcc_priv->clock); + } + result = sysfs_create_group(&pdev->dev.kobj, &llcc_perfmon_group); if (result) { pr_err("Unable to create sysfs group\n");