]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
coresight: etm4x: Support atclk
authorLeo Yan <leo.yan@arm.com>
Thu, 31 Jul 2025 12:23:39 +0000 (13:23 +0100)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Tue, 23 Sep 2025 13:14:12 +0000 (14:14 +0100)
The atclk is an optional clock for the CoreSight ETMv4, but the driver
misses to initialize it.

This change enables atclk in probe of the ETMv4 driver, and dynamically
control the clock during suspend and resume.

No need to check the driver data and clock pointer in the runtime
suspend and resume, so remove checks.  And add error handling in the
resume function.

Add a minor fix to the comment format when adding the atclk field.

Fixes: 2e1cdfe184b5 ("coresight-etm4x: Adding CoreSight ETM4x driver")
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250731-arm_cs_fix_clock_v4-v6-3-1dfe10bb3f6f@arm.com
drivers/hwtracing/coresight/coresight-etm4x-core.c
drivers/hwtracing/coresight/coresight-etm4x.h

index b4f1834a1af1e7a38a3afdf0b7b87e1fe87bfa22..81f20a167e001260baac9b12ed7da8b61fd0aaf0 100644 (file)
@@ -2221,6 +2221,10 @@ static int etm4_probe(struct device *dev)
        if (WARN_ON(!drvdata))
                return -ENOMEM;
 
+       drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+       if (IS_ERR(drvdata->atclk))
+               return PTR_ERR(drvdata->atclk);
+
        if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
                pm_save_enable = coresight_loses_context_with_cpu(dev) ?
                               PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER;
@@ -2469,8 +2473,8 @@ static int etm4_runtime_suspend(struct device *dev)
 {
        struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
 
-       if (drvdata->pclk && !IS_ERR(drvdata->pclk))
-               clk_disable_unprepare(drvdata->pclk);
+       clk_disable_unprepare(drvdata->atclk);
+       clk_disable_unprepare(drvdata->pclk);
 
        return 0;
 }
@@ -2478,11 +2482,17 @@ static int etm4_runtime_suspend(struct device *dev)
 static int etm4_runtime_resume(struct device *dev)
 {
        struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+       int ret;
+
+       ret = clk_prepare_enable(drvdata->pclk);
+       if (ret)
+               return ret;
 
-       if (drvdata->pclk && !IS_ERR(drvdata->pclk))
-               clk_prepare_enable(drvdata->pclk);
+       ret = clk_prepare_enable(drvdata->atclk);
+       if (ret)
+               clk_disable_unprepare(drvdata->pclk);
 
-       return 0;
+       return ret;
 }
 #endif
 
index 823914fefa90a36a328b652b0dc3828b9bddd990..13ec9ecef46f5b60a38c464e8ebde3ef72e7d50b 100644 (file)
@@ -920,7 +920,8 @@ struct etmv4_save_state {
 
 /**
  * struct etm4_drvdata - specifics associated to an ETM component
- * @pclk        APB clock if present, otherwise NULL
+ * @pclk:       APB clock if present, otherwise NULL
+ * @atclk:      Optional clock for the core parts of the ETMv4.
  * @base:       Memory mapped base address for this component.
  * @csdev:      Component vitals needed by the framework.
  * @spinlock:   Only one at a time pls.
@@ -989,6 +990,7 @@ struct etmv4_save_state {
  */
 struct etmv4_drvdata {
        struct clk                      *pclk;
+       struct clk                      *atclk;
        void __iomem                    *base;
        struct coresight_device         *csdev;
        raw_spinlock_t                  spinlock;