* [PATCH v1 0/9] coresight: Fix and improve clock usage
@ 2025-03-27 11:37 Leo Yan
2025-03-27 11:37 ` [PATCH v1 1/9] coresight: tmc: Support atclk Leo Yan
` (8 more replies)
0 siblings, 9 replies; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:37 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
This series fixes and improves clock usage in the Arm CoreSight drivers.
Based on the DT binding documents, the trace clock (atclk) is defined in
some CoreSight modules, but the corresponding drivers to support it are
absent. In most cases, the issue is hidden because atclk is shared by
multiple CoreSight modules and is enabled anyway by other drivers.
The first three patches address this issue.
The programming clock (pclk) management in CoreSight drivers does not
use the devm_XXX() variant APIs, so the drivers needs to manually
disable and release clocks for errors and for normal module exit.
However, the drivers miss to disable clocks during module exit.
Another issue is pclk might be enabled twice in init phase - once by
AMBA bus driver, and again by CoreSight drivers.
Patches 04 and 05 fix pclk issues.
The atclk may also not be disabled in CoreSight drivers during module
exit. This is fixed in patch 06.
Patches 07 to 09 refactor the clock related code. Patch 07 makes the
clock enabling sequence consistent. Patch 08 removes redundant
condition checks and adds error handling in runtime PM. Patch 09
consolidats the clock initialization into a central place.
This series is verified on Arm64 Hikey960 platform.
Leo Yan (9):
coresight: tmc: Support atclk
coresight: catu: Support atclk
coresight: etm4x: Support atclk
coresight: Disable programming clock properly
coresight: Avoid enable programming clock duplicately
coresight: Disable trace bus clock properly
coresight: Make clock sequence consistent
coresight: Refactor runtime PM
coresight: Consolidate clock enabling
drivers/hwtracing/coresight/coresight-catu.c | 53 ++++++++++++++++-----------------
drivers/hwtracing/coresight/coresight-catu.h | 1 +
drivers/hwtracing/coresight/coresight-cpu-debug.c | 41 +++++++++-----------------
drivers/hwtracing/coresight/coresight-ctcu-core.c | 24 +++++----------
drivers/hwtracing/coresight/coresight-etb10.c | 18 ++++--------
drivers/hwtracing/coresight/coresight-etm3x-core.c | 17 ++++-------
drivers/hwtracing/coresight/coresight-etm4x-core.c | 32 ++++++++++----------
drivers/hwtracing/coresight/coresight-etm4x.h | 4 ++-
drivers/hwtracing/coresight/coresight-funnel.c | 66 +++++++++++++++---------------------------
drivers/hwtracing/coresight/coresight-replicator.c | 63 ++++++++++++++--------------------------
drivers/hwtracing/coresight/coresight-stm.c | 34 +++++++++-------------
drivers/hwtracing/coresight/coresight-tmc-core.c | 48 +++++++++++++++---------------
drivers/hwtracing/coresight/coresight-tmc.h | 2 ++
drivers/hwtracing/coresight/coresight-tpiu.c | 36 ++++++++++-------------
include/linux/coresight.h | 47 ++++++++++++++++++------------
15 files changed, 206 insertions(+), 280 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v1 1/9] coresight: tmc: Support atclk
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
@ 2025-03-27 11:37 ` Leo Yan
2025-04-03 5:50 ` Anshuman Khandual
2025-03-27 11:37 ` [PATCH v1 2/9] coresight: catu: " Leo Yan
` (7 subsequent siblings)
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:37 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
The atclk is an optional clock for the CoreSight TMC, but the driver
misses to initialize it. In most cases, the TMC shares the same atclk
with other CoreSight components. Since these components enable the
clock before the TMC device is initialized, the TMC continues properly,
which is why we don’t observe any lockup issues.
This change enables atclk in probe of the TMC driver. Given the clock
is optional, it is possible to return NULL if the clock does not exist.
IS_ERR() is tolerant for this case.
Dynamically disable and enable atclk during suspend and resume. The
clock pointers will never be error values if the driver has successfully
probed, and the case of a NULL pointer case will be handled by the clock
core layer. The driver data is always valid after probe. Therefore,
remove the related checks. Also in the resume flow adds error handling.
Fixes: bc4bf7fe98da ("coresight-tmc: add CoreSight TMC driver")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-tmc-core.c | 22 +++++++++++++++++-----
drivers/hwtracing/coresight/coresight-tmc.h | 2 ++
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 5978bcda2556..6aad2acd0378 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -789,6 +789,10 @@ static int __tmc_probe(struct device *dev, struct resource *res)
struct coresight_desc desc = { 0 };
struct coresight_dev_list *dev_list = NULL;
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
ret = -ENOMEM;
/* Validity for the resource is already checked by the AMBA core */
@@ -1019,18 +1023,26 @@ static int tmc_runtime_suspend(struct device *dev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
+
return 0;
}
static int tmc_runtime_resume(struct device *dev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6541a27a018e..cbb4ba439158 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -210,6 +210,7 @@ struct tmc_resrv_buf {
/**
* struct tmc_drvdata - specifics associated to an TMC component
+ * @atclk: optional clock for the core parts of the TMC.
* @pclk: APB clock if present, otherwise NULL
* @base: memory mapped base address for this component.
* @csdev: component vitals needed by the framework.
@@ -244,6 +245,7 @@ struct tmc_resrv_buf {
* Used by ETR/ETF.
*/
struct tmc_drvdata {
+ struct clk *atclk;
struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 2/9] coresight: catu: Support atclk
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
2025-03-27 11:37 ` [PATCH v1 1/9] coresight: tmc: Support atclk Leo Yan
@ 2025-03-27 11:37 ` Leo Yan
2025-04-03 6:02 ` Anshuman Khandual
2025-03-27 11:37 ` [PATCH v1 3/9] coresight: etm4x: " Leo Yan
` (6 subsequent siblings)
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:37 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
The atclk is an optional clock for the CoreSight CATU, but the driver
misses to initialize it.
This change enables atclk in probe of the CATU driver, and dynamically
control the clock during suspend and resume.
The checks for driver data and clocks in suspend and resume are not
needed, remove them. Add error handling in the resume function.
Fixes: fcacb5c154ba ("coresight: Introduce support for Coresight Address Translation Unit")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-catu.c | 22 +++++++++++++++++-----
drivers/hwtracing/coresight/coresight-catu.h | 1 +
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index fa170c966bc3..9fcda5e49253 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -513,6 +513,10 @@ static int __catu_probe(struct device *dev, struct resource *res)
struct coresight_platform_data *pdata = NULL;
void __iomem *base;
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
if (!catu_desc.name)
return -ENOMEM;
@@ -659,18 +663,26 @@ static int catu_runtime_suspend(struct device *dev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
+
return 0;
}
static int catu_runtime_resume(struct device *dev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
index 141feac1c14b..2fe31fed6cf1 100644
--- a/drivers/hwtracing/coresight/coresight-catu.h
+++ b/drivers/hwtracing/coresight/coresight-catu.h
@@ -62,6 +62,7 @@
struct catu_drvdata {
struct clk *pclk;
+ struct clk *atclk;
void __iomem *base;
struct coresight_device *csdev;
int irq;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 3/9] coresight: etm4x: Support atclk
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
2025-03-27 11:37 ` [PATCH v1 1/9] coresight: tmc: Support atclk Leo Yan
2025-03-27 11:37 ` [PATCH v1 2/9] coresight: catu: " Leo Yan
@ 2025-03-27 11:37 ` Leo Yan
2025-04-03 6:23 ` Anshuman Khandual
2025-03-27 11:37 ` [PATCH v1 4/9] coresight: Disable programming clock properly Leo Yan
` (5 subsequent siblings)
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:37 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
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")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 20 +++++++++++++++-----
drivers/hwtracing/coresight/coresight-etm4x.h | 4 +++-
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index e5972f16abff..537d57006a25 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2149,6 +2149,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;
@@ -2397,8 +2401,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;
}
@@ -2406,11 +2410,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
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index bd7db36ba197..0c21832b5d69 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -919,7 +919,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.
@@ -987,6 +988,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;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 4/9] coresight: Disable programming clock properly
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
` (2 preceding siblings ...)
2025-03-27 11:37 ` [PATCH v1 3/9] coresight: etm4x: " Leo Yan
@ 2025-03-27 11:37 ` Leo Yan
2025-03-27 11:37 ` [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately Leo Yan
` (4 subsequent siblings)
8 siblings, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:37 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
Some CoreSight components have programming clocks (pclk) and are enabled
using clk_get() and clk_prepare_enable(). However, in many cases, these
clocks are not disabled when modules exit and only released by clk_put().
To fix the issue, this commit refactors coresight_get_enable_apb_pclk()
by replacing clk_get() and clk_prepare_enable() with
devm_clk_get_enabled() for enabling APB clock. Callers are updated
to reuse the returned error value.
With the change, programming clocks are managed as resources in driver
model layer, allowing clock cleanup to be handled automatically. As a
result, manual cleanup operations are no longer needed and are removed
from the Coresight drivers.
Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-catu.c | 9 ++-------
drivers/hwtracing/coresight/coresight-cpu-debug.c | 6 +-----
drivers/hwtracing/coresight/coresight-ctcu-core.c | 10 ++--------
drivers/hwtracing/coresight/coresight-etm4x-core.c | 9 ++-------
drivers/hwtracing/coresight/coresight-funnel.c | 6 +-----
drivers/hwtracing/coresight/coresight-replicator.c | 6 +-----
drivers/hwtracing/coresight/coresight-stm.c | 4 +---
drivers/hwtracing/coresight/coresight-tmc-core.c | 4 +---
drivers/hwtracing/coresight/coresight-tpiu.c | 4 +---
include/linux/coresight.h | 16 +++-------------
10 files changed, 15 insertions(+), 59 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 9fcda5e49253..c0a51ab0312c 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -627,7 +627,7 @@ static int catu_platform_probe(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
@@ -636,11 +636,8 @@ static int catu_platform_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, drvdata);
ret = __catu_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
- if (ret) {
+ if (ret)
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
- }
return ret;
}
@@ -654,8 +651,6 @@ static void catu_platform_remove(struct platform_device *pdev)
__catu_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 342c3aaf414d..744b6f9b065e 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -699,7 +699,7 @@ static int debug_platform_probe(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
@@ -710,8 +710,6 @@ static int debug_platform_probe(struct platform_device *pdev)
if (ret) {
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
return ret;
}
@@ -725,8 +723,6 @@ static void debug_platform_remove(struct platform_device *pdev)
__debug_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index c6bafc96db96..de279efe3405 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -209,7 +209,7 @@ static int ctcu_probe(struct platform_device *pdev)
drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->apb_clk))
- return -ENODEV;
+ return PTR_ERR(drvdata->apb_clk);
cfgs = of_device_get_match_data(dev);
if (cfgs) {
@@ -233,12 +233,8 @@ static int ctcu_probe(struct platform_device *pdev)
desc.access = CSDEV_ACCESS_IOMEM(base);
drvdata->csdev = coresight_register(&desc);
- if (IS_ERR(drvdata->csdev)) {
- if (!IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_put(drvdata->apb_clk);
-
+ if (IS_ERR(drvdata->csdev))
return PTR_ERR(drvdata->csdev);
- }
return 0;
}
@@ -275,8 +271,6 @@ static void ctcu_platform_remove(struct platform_device *pdev)
ctcu_remove(pdev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_put(drvdata->apb_clk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 537d57006a25..ff4ac4b686c4 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2237,14 +2237,12 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
if (res) {
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(drvdata->base)) {
- clk_put(drvdata->pclk);
+ if (IS_ERR(drvdata->base))
return PTR_ERR(drvdata->base);
- }
}
dev_set_drvdata(&pdev->dev, drvdata);
@@ -2351,9 +2349,6 @@ static void etm4_remove_platform_dev(struct platform_device *pdev)
if (drvdata)
etm4_remove_dev(drvdata);
pm_runtime_disable(&pdev->dev);
-
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
static const struct amba_id etm4_ids[] = {
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 0541712b2bcb..3fb9d0a37d55 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -240,7 +240,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
/*
* Map the device base for dynamic-funnel, which has been
@@ -283,8 +283,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
- if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return ret;
}
@@ -354,8 +352,6 @@ static void funnel_platform_remove(struct platform_device *pdev)
funnel_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
static const struct of_device_id funnel_match[] = {
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index ee7ee79f6cf7..87346617b852 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -247,7 +247,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
/*
* Map the device base for dynamic-replicator, which has been
@@ -295,8 +295,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
- if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return ret;
}
@@ -334,8 +332,6 @@ static void replicator_platform_remove(struct platform_device *pdev)
replicator_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 26f9339f38b9..c32d0bd92f30 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -851,7 +851,7 @@ static int __stm_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, res);
@@ -1033,8 +1033,6 @@ static void stm_platform_remove(struct platform_device *pdev)
__stm_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 6aad2acd0378..86ea3fea7abb 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -990,7 +990,7 @@ static int tmc_platform_probe(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
@@ -1014,8 +1014,6 @@ static void tmc_platform_remove(struct platform_device *pdev)
__tmc_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 97ef36f03ec2..4b9634941752 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -153,7 +153,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
@@ -293,8 +293,6 @@ static void tpiu_platform_remove(struct platform_device *pdev)
__tpiu_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d79a242b271d..b888f6ed59b2 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -476,26 +476,16 @@ static inline bool is_coresight_device(void __iomem *base)
* Returns:
*
* clk - Clock is found and enabled
- * NULL - clock is not found
* ERROR - Clock is found but failed to enable
*/
static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
{
struct clk *pclk;
- int ret;
- pclk = clk_get(dev, "apb_pclk");
- if (IS_ERR(pclk)) {
- pclk = clk_get(dev, "apb");
- if (IS_ERR(pclk))
- return NULL;
- }
+ pclk = devm_clk_get_enabled(dev, "apb_pclk");
+ if (IS_ERR(pclk))
+ pclk = devm_clk_get_enabled(dev, "apb");
- ret = clk_prepare_enable(pclk);
- if (ret) {
- clk_put(pclk);
- return ERR_PTR(ret);
- }
return pclk;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
` (3 preceding siblings ...)
2025-03-27 11:37 ` [PATCH v1 4/9] coresight: Disable programming clock properly Leo Yan
@ 2025-03-27 11:37 ` Leo Yan
2025-04-03 6:48 ` Anshuman Khandual
2025-03-27 11:38 ` [PATCH v1 6/9] coresight: Disable trace bus clock properly Leo Yan
` (3 subsequent siblings)
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:37 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
The programming clock is enabled by AMBA bus driver before a dynamic
probe. As a result, a CoreSight driver may redundantly enable the same
clock.
To avoid this, add a check for device type and skip enabling the
programming clock for AMBA devices. The returned NULL pointer will be
tolerated by the drivers.
Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
include/linux/coresight.h | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index b888f6ed59b2..26eb4a61b992 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -476,15 +476,18 @@ static inline bool is_coresight_device(void __iomem *base)
* Returns:
*
* clk - Clock is found and enabled
+ * NULL - Clock is not needed as it is managed by the AMBA bus driver
* ERROR - Clock is found but failed to enable
*/
static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
{
- struct clk *pclk;
+ struct clk *pclk = NULL;
- pclk = devm_clk_get_enabled(dev, "apb_pclk");
- if (IS_ERR(pclk))
- pclk = devm_clk_get_enabled(dev, "apb");
+ if (!dev_is_amba(dev)) {
+ pclk = devm_clk_get_enabled(dev, "apb_pclk");
+ if (IS_ERR(pclk))
+ pclk = devm_clk_get_enabled(dev, "apb");
+ }
return pclk;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 6/9] coresight: Disable trace bus clock properly
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
` (4 preceding siblings ...)
2025-03-27 11:37 ` [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately Leo Yan
@ 2025-03-27 11:38 ` Leo Yan
2025-04-03 7:25 ` Anshuman Khandual
2025-03-27 11:38 ` [PATCH v1 7/9] coresight: Make clock sequence consistent Leo Yan
` (2 subsequent siblings)
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:38 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
Some CoreSight components have trace bus clocks 'atclk' and are enabled
using clk_prepare_enable(). These clocks are not disabled when modules
exit.
As atclk is optional, use devm_clk_get_optional_enabled() to manage it.
The benefit is the driver model layer can automatically disable and
release clocks.
Check the returned value with IS_ERR() to detect errors but leave the
NULL pointer case if the clock is not found. And remove the error
handling codes which are no longer needed.
Fixes: d1839e687773 ("coresight: etm: retrieve and handle atclk")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-etb10.c | 10 ++++------
drivers/hwtracing/coresight/coresight-etm3x-core.c | 9 +++------
drivers/hwtracing/coresight/coresight-funnel.c | 36 +++++++++++-------------------------
drivers/hwtracing/coresight/coresight-replicator.c | 34 ++++++++++------------------------
drivers/hwtracing/coresight/coresight-stm.c | 9 +++------
drivers/hwtracing/coresight/coresight-tpiu.c | 10 +++-------
6 files changed, 34 insertions(+), 74 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 7948597d483d..45c2f8f50a3f 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -730,12 +730,10 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
dev_set_drvdata(dev, drvdata);
/* validity for the resource is already checked by the AMBA core */
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 8927bfaf3af2..adbb134f80e6 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -832,12 +832,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->cpu = coresight_get_cpu(dev);
if (drvdata->cpu < 0)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 3fb9d0a37d55..ec6d3e656548 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -213,7 +213,6 @@ ATTRIBUTE_GROUPS(coresight_funnel);
static int funnel_probe(struct device *dev, struct resource *res)
{
- int ret;
void __iomem *base;
struct coresight_platform_data *pdata = NULL;
struct funnel_drvdata *drvdata;
@@ -231,12 +230,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
@@ -248,10 +244,8 @@ static int funnel_probe(struct device *dev, struct resource *res)
*/
if (res) {
base = devm_ioremap_resource(dev, res);
- if (IS_ERR(base)) {
- ret = PTR_ERR(base);
- goto out_disable_clk;
- }
+ if (IS_ERR(base))
+ return PTR_ERR(base);
drvdata->base = base;
desc.groups = coresight_funnel_groups;
desc.access = CSDEV_ACCESS_IOMEM(base);
@@ -260,10 +254,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
dev_set_drvdata(dev, drvdata);
pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
- ret = PTR_ERR(pdata);
- goto out_disable_clk;
- }
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
dev->platform_data = pdata;
raw_spin_lock_init(&drvdata->spinlock);
@@ -273,17 +266,10 @@ static int funnel_probe(struct device *dev, struct resource *res)
desc.pdata = pdata;
desc.dev = dev;
drvdata->csdev = coresight_register(&desc);
- if (IS_ERR(drvdata->csdev)) {
- ret = PTR_ERR(drvdata->csdev);
- goto out_disable_clk;
- }
+ if (IS_ERR(drvdata->csdev))
+ return PTR_ERR(drvdata->csdev);
- ret = 0;
-
-out_disable_clk:
- if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
- return ret;
+ return 0;
}
static int funnel_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 87346617b852..460af0f7b537 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -219,7 +219,6 @@ static const struct attribute_group *replicator_groups[] = {
static int replicator_probe(struct device *dev, struct resource *res)
{
- int ret = 0;
struct coresight_platform_data *pdata = NULL;
struct replicator_drvdata *drvdata;
struct coresight_desc desc = { 0 };
@@ -238,12 +237,9 @@ static int replicator_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
@@ -255,10 +251,8 @@ static int replicator_probe(struct device *dev, struct resource *res)
*/
if (res) {
base = devm_ioremap_resource(dev, res);
- if (IS_ERR(base)) {
- ret = PTR_ERR(base);
- goto out_disable_clk;
- }
+ if (IS_ERR(base))
+ return PTR_ERR(base);
drvdata->base = base;
desc.groups = replicator_groups;
desc.access = CSDEV_ACCESS_IOMEM(base);
@@ -271,10 +265,8 @@ static int replicator_probe(struct device *dev, struct resource *res)
dev_set_drvdata(dev, drvdata);
pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
- ret = PTR_ERR(pdata);
- goto out_disable_clk;
- }
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
dev->platform_data = pdata;
raw_spin_lock_init(&drvdata->spinlock);
@@ -285,17 +277,11 @@ static int replicator_probe(struct device *dev, struct resource *res)
desc.dev = dev;
drvdata->csdev = coresight_register(&desc);
- if (IS_ERR(drvdata->csdev)) {
- ret = PTR_ERR(drvdata->csdev);
- goto out_disable_clk;
- }
+ if (IS_ERR(drvdata->csdev))
+ return PTR_ERR(drvdata->csdev);
replicator_reset(drvdata);
-
-out_disable_clk:
- if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
- return ret;
+ return 0;
}
static int replicator_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index c32d0bd92f30..f13fbab4d7a2 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -842,12 +842,9 @@ static int __stm_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 4b9634941752..cac1b5bba086 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -128,7 +128,6 @@ static const struct coresight_ops tpiu_cs_ops = {
static int __tpiu_probe(struct device *dev, struct resource *res)
{
- int ret;
void __iomem *base;
struct coresight_platform_data *pdata = NULL;
struct tpiu_drvdata *drvdata;
@@ -144,12 +143,9 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 7/9] coresight: Make clock sequence consistent
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
` (5 preceding siblings ...)
2025-03-27 11:38 ` [PATCH v1 6/9] coresight: Disable trace bus clock properly Leo Yan
@ 2025-03-27 11:38 ` Leo Yan
2025-04-03 7:10 ` Anshuman Khandual
2025-03-27 11:38 ` [PATCH v1 8/9] coresight: Refactor runtime PM Leo Yan
2025-03-27 11:38 ` [PATCH v1 9/9] coresight: Consolidate clock enabling Leo Yan
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:38 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
Since atclk is enabled after pclk during the probe phase, this commit
maintains the same sequence for the runtime resume flow.
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-funnel.c | 6 +++---
drivers/hwtracing/coresight/coresight-replicator.c | 6 +++---
drivers/hwtracing/coresight/coresight-stm.c | 6 +++---
drivers/hwtracing/coresight/coresight-tpiu.c | 6 +++---
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index ec6d3e656548..e378c2fffca9 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -299,11 +299,11 @@ static int funnel_runtime_resume(struct device *dev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 460af0f7b537..78854f586e89 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -337,11 +337,11 @@ static int replicator_runtime_resume(struct device *dev)
{
struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index f13fbab4d7a2..ddb4f6678efd 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -972,11 +972,11 @@ static int stm_runtime_resume(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index cac1b5bba086..8212959f60d4 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -220,11 +220,11 @@ static int tpiu_runtime_resume(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 8/9] coresight: Refactor runtime PM
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
` (6 preceding siblings ...)
2025-03-27 11:38 ` [PATCH v1 7/9] coresight: Make clock sequence consistent Leo Yan
@ 2025-03-27 11:38 ` Leo Yan
2025-03-27 11:38 ` [PATCH v1 9/9] coresight: Consolidate clock enabling Leo Yan
8 siblings, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:38 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
The validation for driver data pointers and clock pointers are redundant
in the runtime PM callbacks. After a driver's probing, its driver data
and clocks have been initialized successfully, this ensures it is safe
to access driver data and clocks in the runtime PM callbacks. A corner
case is a clock pointer is NULL, in this case, the clock core layer can
handle it properly. So remove these redundant checking.
In runtime resume, respect values returned from clock function and add
error handling.
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-cpu-debug.c | 8 +++-----
drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++------
drivers/hwtracing/coresight/coresight-etb10.c | 8 ++------
drivers/hwtracing/coresight/coresight-etm3x-core.c | 8 ++------
drivers/hwtracing/coresight/coresight-funnel.c | 21 +++++++++++----------
drivers/hwtracing/coresight/coresight-replicator.c | 20 +++++++++++---------
drivers/hwtracing/coresight/coresight-stm.c | 20 +++++++++++---------
drivers/hwtracing/coresight/coresight-tpiu.c | 20 +++++++++++---------
8 files changed, 53 insertions(+), 60 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 744b6f9b065e..5f90351778ee 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -738,8 +738,8 @@ static int debug_runtime_suspend(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->pclk);
+
return 0;
}
@@ -747,9 +747,7 @@ static int debug_runtime_resume(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
- return 0;
+ return clk_prepare_enable(drvdata->pclk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index de279efe3405..edd93ff2d3c5 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -278,8 +278,7 @@ static int ctcu_runtime_suspend(struct device *dev)
{
struct ctcu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_disable_unprepare(drvdata->apb_clk);
+ clk_disable_unprepare(drvdata->apb_clk);
return 0;
}
@@ -288,10 +287,7 @@ static int ctcu_runtime_resume(struct device *dev)
{
struct ctcu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_prepare_enable(drvdata->apb_clk);
-
- return 0;
+ return clk_prepare_enable(drvdata->apb_clk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 45c2f8f50a3f..3f3b0eb48fdb 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -807,8 +807,7 @@ static int etb_runtime_suspend(struct device *dev)
{
struct etb_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
return 0;
}
@@ -817,10 +816,7 @@ static int etb_runtime_resume(struct device *dev)
{
struct etb_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
- return 0;
+ return clk_prepare_enable(drvdata->atclk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index adbb134f80e6..615ff743eef0 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -925,8 +925,7 @@ static int etm_runtime_suspend(struct device *dev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
return 0;
}
@@ -935,10 +934,7 @@ static int etm_runtime_resume(struct device *dev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
- return 0;
+ return clk_prepare_enable(drvdata->atclk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index e378c2fffca9..fd60491c9a19 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -286,11 +286,8 @@ static int funnel_runtime_suspend(struct device *dev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
-
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
return 0;
}
@@ -298,13 +295,17 @@ static int funnel_runtime_suspend(struct device *dev)
static int funnel_runtime_resume(struct device *dev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 78854f586e89..aeb2b3d8e210 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -325,24 +325,26 @@ static int replicator_runtime_suspend(struct device *dev)
{
struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int replicator_runtime_resume(struct device *dev)
{
struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index ddb4f6678efd..d589fc61a00e 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -960,24 +960,26 @@ static int stm_runtime_suspend(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int stm_runtime_resume(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 8212959f60d4..5821ae73a34a 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -208,24 +208,26 @@ static int tpiu_runtime_suspend(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int tpiu_runtime_resume(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v1 9/9] coresight: Consolidate clock enabling
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
` (7 preceding siblings ...)
2025-03-27 11:38 ` [PATCH v1 8/9] coresight: Refactor runtime PM Leo Yan
@ 2025-03-27 11:38 ` Leo Yan
2025-04-01 14:58 ` James Clark
8 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-03-27 11:38 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
Cc: Leo Yan
CoreSight drivers enable pclk and atclk conditionally. For example,
pclk is only enabled in the static probe, while atclk is an optional
clock that it is enabled for both dynamic and static probes, if it is
present. In the current CoreSight drivers, these two clocks are
initialized separately. This causes complex and duplicate codes.
This patch consolidates clock enabling into a central place. It renames
coresight_get_enable_apb_pclk() to coresight_get_enable_clocks() and
encapsulates clock initialization logic:
- If a clock is initialized successfully, its clock pointer is assigned
to the double pointer passed as an argument.
- If pclk is skipped for an AMBA device, or if atclk is not found, the
corresponding double pointer is set to NULL. The function returns
Success (0) to guide callers can proceed with no error.
- Otherwise, an error number is returned for failures.
CoreSight drivers are refined so that clocks are initialized in one go.
As a result, driver data no longer needs to be allocated separately in
the static and dynamic probes. Moved the allocation into a low-level
function to avoid code duplication.
Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-catu.c | 30 ++++++++++--------------------
drivers/hwtracing/coresight/coresight-cpu-debug.c | 29 +++++++++++------------------
drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++++----
drivers/hwtracing/coresight/coresight-etm4x-core.c | 11 ++++-------
drivers/hwtracing/coresight/coresight-funnel.c | 11 ++++-------
drivers/hwtracing/coresight/coresight-replicator.c | 11 ++++-------
drivers/hwtracing/coresight/coresight-stm.c | 9 +++------
drivers/hwtracing/coresight/coresight-tmc-core.c | 30 ++++++++++--------------------
drivers/hwtracing/coresight/coresight-tpiu.c | 10 ++++------
include/linux/coresight.h | 38 +++++++++++++++++++++++++++-----------
10 files changed, 81 insertions(+), 106 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index c0a51ab0312c..c63dee1ac997 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -508,14 +508,20 @@ static int __catu_probe(struct device *dev, struct resource *res)
{
int ret = 0;
u32 dma_mask;
- struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+ struct catu_drvdata *drvdata;
struct coresight_desc catu_desc;
struct coresight_platform_data *pdata = NULL;
void __iomem *base;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
+
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
if (!catu_desc.name)
@@ -571,14 +577,8 @@ static int __catu_probe(struct device *dev, struct resource *res)
static int catu_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct catu_drvdata *drvdata;
int ret;
- drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- amba_set_drvdata(adev, drvdata);
ret = __catu_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
@@ -618,22 +618,12 @@ static struct amba_driver catu_driver = {
static int catu_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct catu_drvdata *drvdata;
int ret = 0;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- dev_set_drvdata(&pdev->dev, drvdata);
ret = __catu_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 5f90351778ee..dff663ac7805 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -562,10 +562,20 @@ static void debug_func_exit(void)
static int __debug_probe(struct device *dev, struct resource *res)
{
- struct debug_drvdata *drvdata = dev_get_drvdata(dev);
+ struct debug_drvdata *drvdata;
void __iomem *base;
int ret;
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
+
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL);
+ if (ret)
+ return ret;
+
drvdata->cpu = coresight_get_cpu(dev);
if (drvdata->cpu < 0)
return drvdata->cpu;
@@ -625,13 +635,6 @@ static int __debug_probe(struct device *dev, struct resource *res)
static int debug_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct debug_drvdata *drvdata;
-
- drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- amba_set_drvdata(adev, drvdata);
return __debug_probe(&adev->dev, &adev->res);
}
@@ -690,18 +693,8 @@ static struct amba_driver debug_driver = {
static int debug_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct debug_drvdata *drvdata;
int ret = 0;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
- dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index edd93ff2d3c5..c586495e9a08 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -188,7 +188,7 @@ static int ctcu_probe(struct platform_device *pdev)
const struct ctcu_config *cfgs;
struct ctcu_drvdata *drvdata;
void __iomem *base;
- int i;
+ int i, ret;
desc.name = coresight_alloc_device_name(&ctcu_devs, dev);
if (!desc.name)
@@ -207,9 +207,9 @@ static int ctcu_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
- drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->apb_clk))
- return PTR_ERR(drvdata->apb_clk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->apb_clk, NULL);
+ if (ret)
+ return ret;
cfgs = of_device_get_match_data(dev);
if (cfgs) {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index ff4ac4b686c4..ba5d1a015140 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2145,13 +2145,14 @@ static int etm4_probe(struct device *dev)
struct csdev_access access = { 0 };
struct etm4_init_arg init_arg = { 0 };
struct etm4_init_arg *delayed;
+ int ret;
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);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
pm_save_enable = coresight_loses_context_with_cpu(dev) ?
@@ -2235,10 +2236,6 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
if (res) {
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(drvdata->base))
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index fd60491c9a19..6494a3b5d18e 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -217,6 +217,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
struct coresight_platform_data *pdata = NULL;
struct funnel_drvdata *drvdata;
struct coresight_desc desc = { 0 };
+ int ret;
if (is_of_node(dev_fwnode(dev)) &&
of_device_is_compatible(dev->of_node, "arm,coresight-funnel"))
@@ -230,13 +231,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
-
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
/*
* Map the device base for dynamic-funnel, which has been
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index aeb2b3d8e210..8595dc104795 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -223,6 +223,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
struct replicator_drvdata *drvdata;
struct coresight_desc desc = { 0 };
void __iomem *base;
+ int ret;
if (is_of_node(dev_fwnode(dev)) &&
of_device_is_compatible(dev->of_node, "arm,coresight-replicator"))
@@ -237,13 +238,9 @@ static int replicator_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
-
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
/*
* Map the device base for dynamic-replicator, which has been
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index d589fc61a00e..f859ab932d22 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -842,13 +842,10 @@ static int __stm_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, res);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 86ea3fea7abb..745d33d0646f 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -785,13 +785,19 @@ static int __tmc_probe(struct device *dev, struct resource *res)
u32 devid;
void __iomem *base;
struct coresight_platform_data *pdata = NULL;
- struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+ struct tmc_drvdata *drvdata;
struct coresight_desc desc = { 0 };
struct coresight_dev_list *dev_list = NULL;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
+
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
ret = -ENOMEM;
@@ -897,14 +903,8 @@ static int __tmc_probe(struct device *dev, struct resource *res)
static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct tmc_drvdata *drvdata;
int ret;
- drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- amba_set_drvdata(adev, drvdata);
ret = __tmc_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
@@ -981,18 +981,8 @@ static struct amba_driver tmc_driver = {
static int tmc_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct tmc_drvdata *drvdata;
int ret = 0;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
- dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 5821ae73a34a..a68ed6b97bf7 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -132,6 +132,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
struct coresight_platform_data *pdata = NULL;
struct tpiu_drvdata *drvdata;
struct coresight_desc desc = { 0 };
+ int ret;
desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
if (!desc.name)
@@ -143,13 +144,10 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 26eb4a61b992..cf3fbbc0076a 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -471,25 +471,41 @@ static inline bool is_coresight_device(void __iomem *base)
}
/*
- * Attempt to find and enable "APB clock" for the given device
+ * Attempt to find and enable programming clock (pclk) and trace clock (atclk)
+ * for the given device.
*
- * Returns:
+ * The AMBA bus driver will cover the pclk, to avoid duplicate operations,
+ * skip to get and enable the pclk for an AMBA device.
*
- * clk - Clock is found and enabled
- * NULL - Clock is not needed as it is managed by the AMBA bus driver
- * ERROR - Clock is found but failed to enable
+ * atclk is an optional clock, it will be only enabled when it is existed.
+ * Otherwise, a NULL pointer will be returned to caller.
+ *
+ * Returns: '0' on Success; Error code otherwise.
*/
-static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
+static inline int coresight_get_enable_clocks(struct device *dev,
+ struct clk **pclk,
+ struct clk **atclk)
{
- struct clk *pclk = NULL;
+ WARN_ON(!pclk);
if (!dev_is_amba(dev)) {
- pclk = devm_clk_get_enabled(dev, "apb_pclk");
- if (IS_ERR(pclk))
- pclk = devm_clk_get_enabled(dev, "apb");
+ *pclk = devm_clk_get_enabled(dev, "apb_pclk");
+ if (IS_ERR(*pclk))
+ *pclk = devm_clk_get_enabled(dev, "apb");
+ if (IS_ERR(*pclk))
+ return PTR_ERR(*pclk);
+ } else {
+ /* Don't enable pclk for an AMBA device */
+ *pclk = NULL;
}
- return pclk;
+ if (atclk) {
+ *atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(*atclk))
+ return PTR_ERR(*atclk);
+ }
+
+ return 0;
}
#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v1 9/9] coresight: Consolidate clock enabling
2025-03-27 11:38 ` [PATCH v1 9/9] coresight: Consolidate clock enabling Leo Yan
@ 2025-04-01 14:58 ` James Clark
2025-04-01 15:29 ` Leo Yan
2025-04-02 0:55 ` Jie Gan
0 siblings, 2 replies; 25+ messages in thread
From: James Clark @ 2025-04-01 14:58 UTC (permalink / raw)
To: Leo Yan, Jie Gan
Cc: Suzuki K Poulose, Mike Leach, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 27/03/2025 11:38 am, Leo Yan wrote:
> CoreSight drivers enable pclk and atclk conditionally. For example,
> pclk is only enabled in the static probe, while atclk is an optional
> clock that it is enabled for both dynamic and static probes, if it is
> present. In the current CoreSight drivers, these two clocks are
> initialized separately. This causes complex and duplicate codes.
>
> This patch consolidates clock enabling into a central place. It renames
> coresight_get_enable_apb_pclk() to coresight_get_enable_clocks() and
> encapsulates clock initialization logic:
>
> - If a clock is initialized successfully, its clock pointer is assigned
> to the double pointer passed as an argument.
> - If pclk is skipped for an AMBA device, or if atclk is not found, the
> corresponding double pointer is set to NULL. The function returns
> Success (0) to guide callers can proceed with no error.
> - Otherwise, an error number is returned for failures.
>
> CoreSight drivers are refined so that clocks are initialized in one go.
> As a result, driver data no longer needs to be allocated separately in
> the static and dynamic probes. Moved the allocation into a low-level
> function to avoid code duplication.
>
> Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-catu.c | 30 ++++++++++--------------------
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 29 +++++++++++------------------
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++++----
> drivers/hwtracing/coresight/coresight-etm4x-core.c | 11 ++++-------
> drivers/hwtracing/coresight/coresight-funnel.c | 11 ++++-------
> drivers/hwtracing/coresight/coresight-replicator.c | 11 ++++-------
> drivers/hwtracing/coresight/coresight-stm.c | 9 +++------
> drivers/hwtracing/coresight/coresight-tmc-core.c | 30 ++++++++++--------------------
> drivers/hwtracing/coresight/coresight-tpiu.c | 10 ++++------
> include/linux/coresight.h | 38 +++++++++++++++++++++++++++-----------
> 10 files changed, 81 insertions(+), 106 deletions(-)
>
[...]
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 26eb4a61b992..cf3fbbc0076a 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -471,25 +471,41 @@ static inline bool is_coresight_device(void __iomem *base)
> }
>
> /*
> - * Attempt to find and enable "APB clock" for the given device
> + * Attempt to find and enable programming clock (pclk) and trace clock (atclk)
> + * for the given device.
> *
> - * Returns:
> + * The AMBA bus driver will cover the pclk, to avoid duplicate operations,
> + * skip to get and enable the pclk for an AMBA device.
> *
> - * clk - Clock is found and enabled
> - * NULL - Clock is not needed as it is managed by the AMBA bus driver
> - * ERROR - Clock is found but failed to enable
> + * atclk is an optional clock, it will be only enabled when it is existed.
> + * Otherwise, a NULL pointer will be returned to caller.
> + *
> + * Returns: '0' on Success; Error code otherwise.
> */
> -static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> +static inline int coresight_get_enable_clocks(struct device *dev,
> + struct clk **pclk,
> + struct clk **atclk)
This function has grown a bit now, probably best to remove it from the
header and export it instead.
> {
> - struct clk *pclk = NULL;
> + WARN_ON(!pclk);
>
> if (!dev_is_amba(dev)) {
> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> - if (IS_ERR(pclk))
> - pclk = devm_clk_get_enabled(dev, "apb");
> + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(*pclk))
> + *pclk = devm_clk_get_enabled(dev, "apb");
> + if (IS_ERR(*pclk))
> + return PTR_ERR(*pclk);
> + } else {
> + /* Don't enable pclk for an AMBA device */
> + *pclk = NULL;
Now the "apb" clock won't be enabled for amba devices. I'm assuming
that's fine if the clock was always called "apb_pclk" for them, but the
commit that added the new clock name didn't specify any special casing
either.
Can we have a comment that says it's deliberate? But the more I think
about it the more I'm confused why CTCU needed a different clock name to
be defined, when all the other Coresight devices use "apb_pclk".
> }
>
> - return pclk;
> + if (atclk) {
> + *atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(*atclk))
> + return PTR_ERR(*atclk);
> + }
> +
> + return 0;
> }
>
> #define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 9/9] coresight: Consolidate clock enabling
2025-04-01 14:58 ` James Clark
@ 2025-04-01 15:29 ` Leo Yan
2025-04-02 0:55 ` Jie Gan
1 sibling, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-04-01 15:29 UTC (permalink / raw)
To: James Clark
Cc: Jie Gan, Suzuki K Poulose, Mike Leach, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On Tue, Apr 01, 2025 at 03:58:42PM +0100, James Clark wrote:
[...]
> > /*
> > - * Attempt to find and enable "APB clock" for the given device
> > + * Attempt to find and enable programming clock (pclk) and trace clock (atclk)
> > + * for the given device.
> > *
> > - * Returns:
> > + * The AMBA bus driver will cover the pclk, to avoid duplicate operations,
> > + * skip to get and enable the pclk for an AMBA device.
> > *
> > - * clk - Clock is found and enabled
> > - * NULL - Clock is not needed as it is managed by the AMBA bus driver
> > - * ERROR - Clock is found but failed to enable
> > + * atclk is an optional clock, it will be only enabled when it is existed.
> > + * Otherwise, a NULL pointer will be returned to caller.
> > + *
> > + * Returns: '0' on Success; Error code otherwise.
> > */
> > -static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> > +static inline int coresight_get_enable_clocks(struct device *dev,
> > + struct clk **pclk,
> > + struct clk **atclk)
>
> This function has grown a bit now, probably best to remove it from the
> header and export it instead.
Sure. I can move this function into coresight-core.c file.
> > {
> > - struct clk *pclk = NULL;
> > + WARN_ON(!pclk);
> > if (!dev_is_amba(dev)) {
> > - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > - if (IS_ERR(pclk))
> > - pclk = devm_clk_get_enabled(dev, "apb");
> > + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > + if (IS_ERR(*pclk))
> > + *pclk = devm_clk_get_enabled(dev, "apb");
> > + if (IS_ERR(*pclk))
> > + return PTR_ERR(*pclk);
> > + } else {
> > + /* Don't enable pclk for an AMBA device */
> > + *pclk = NULL;
>
> Now the "apb" clock won't be enabled for amba devices. I'm assuming that's
> fine if the clock was always called "apb_pclk" for them, but the commit that
> added the new clock name didn't specify any special casing either.
> Can we have a comment that says it's deliberate? But the more I think about
> it the more I'm confused why CTCU needed a different clock name to be
> defined, when all the other Coresight devices use "apb_pclk".
Yes, seems to me, "apb" clock is the same thing with "apb_pclk". As
CTCU DT binding has been merged, for backward compatible, we cannot
remove it now.
CTCU driver only supports static probe, it is never probed by AMBA bus
driver. I think this is another reason that "apb_pclk" is not used in
CTCU driver. I can add a comment like:
"apb_pclk" is the default clock name used by the AMBA bus driver,
while "apb" is used only by the CTCU driver. A CoreSight driver
should use "apb_pclk" as its programming clock name.
Thanks,
Leo
> > }
> > - return pclk;
> > + if (atclk) {
> > + *atclk = devm_clk_get_optional_enabled(dev, "atclk");
> > + if (IS_ERR(*atclk))
> > + return PTR_ERR(*atclk);
> > + }
> > +
> > + return 0;
> > }
> > #define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 9/9] coresight: Consolidate clock enabling
2025-04-01 14:58 ` James Clark
2025-04-01 15:29 ` Leo Yan
@ 2025-04-02 0:55 ` Jie Gan
2025-04-02 9:01 ` Leo Yan
1 sibling, 1 reply; 25+ messages in thread
From: Jie Gan @ 2025-04-02 0:55 UTC (permalink / raw)
To: James Clark, Leo Yan
Cc: Suzuki K Poulose, Mike Leach, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 4/1/2025 10:58 PM, James Clark wrote:
>
>
> On 27/03/2025 11:38 am, Leo Yan wrote:
>> CoreSight drivers enable pclk and atclk conditionally. For example,
>> pclk is only enabled in the static probe, while atclk is an optional
>> clock that it is enabled for both dynamic and static probes, if it is
>> present. In the current CoreSight drivers, these two clocks are
>> initialized separately. This causes complex and duplicate codes.
>>
>> This patch consolidates clock enabling into a central place. It renames
>> coresight_get_enable_apb_pclk() to coresight_get_enable_clocks() and
>> encapsulates clock initialization logic:
>>
>> - If a clock is initialized successfully, its clock pointer is assigned
>> to the double pointer passed as an argument.
>> - If pclk is skipped for an AMBA device, or if atclk is not found, the
>> corresponding double pointer is set to NULL. The function returns
>> Success (0) to guide callers can proceed with no error.
>> - Otherwise, an error number is returned for failures.
>>
>> CoreSight drivers are refined so that clocks are initialized in one go.
>> As a result, driver data no longer needs to be allocated separately in
>> the static and dynamic probes. Moved the allocation into a low-level
>> function to avoid code duplication.
>>
>> Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Signed-off-by: Leo Yan <leo.yan@arm.com>
>> ---
>> drivers/hwtracing/coresight/coresight-catu.c | 30 +++++++++
>> +--------------------
>> drivers/hwtracing/coresight/coresight-cpu-debug.c | 29 ++++++++++
>> +------------------
>> drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++++----
>> drivers/hwtracing/coresight/coresight-etm4x-core.c | 11 ++++-------
>> drivers/hwtracing/coresight/coresight-funnel.c | 11 ++++-------
>> drivers/hwtracing/coresight/coresight-replicator.c | 11 ++++-------
>> drivers/hwtracing/coresight/coresight-stm.c | 9 +++------
>> drivers/hwtracing/coresight/coresight-tmc-core.c | 30 +++++++++
>> +--------------------
>> drivers/hwtracing/coresight/coresight-tpiu.c | 10 ++++------
>> include/linux/coresight.h | 38 ++++++++++++
>> +++++++++++++++-----------
>> 10 files changed, 81 insertions(+), 106 deletions(-)
>>
> [...]
>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> index 26eb4a61b992..cf3fbbc0076a 100644
>> --- a/include/linux/coresight.h
>> +++ b/include/linux/coresight.h
>> @@ -471,25 +471,41 @@ static inline bool is_coresight_device(void
>> __iomem *base)
>> }
>> /*
>> - * Attempt to find and enable "APB clock" for the given device
>> + * Attempt to find and enable programming clock (pclk) and trace
>> clock (atclk)
>> + * for the given device.
>> *
>> - * Returns:
>> + * The AMBA bus driver will cover the pclk, to avoid duplicate
>> operations,
>> + * skip to get and enable the pclk for an AMBA device.
>> *
>> - * clk - Clock is found and enabled
>> - * NULL - Clock is not needed as it is managed by the AMBA bus driver
>> - * ERROR - Clock is found but failed to enable
>> + * atclk is an optional clock, it will be only enabled when it is
>> existed.
>> + * Otherwise, a NULL pointer will be returned to caller.
>> + *
>> + * Returns: '0' on Success; Error code otherwise.
>> */
>> -static inline struct clk *coresight_get_enable_apb_pclk(struct device
>> *dev)
>> +static inline int coresight_get_enable_clocks(struct device *dev,
>> + struct clk **pclk,
>> + struct clk **atclk)
>
> This function has grown a bit now, probably best to remove it from the
> header and export it instead.
>
>> {
>> - struct clk *pclk = NULL;
>> + WARN_ON(!pclk);
>> if (!dev_is_amba(dev)) {
>> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
>> - if (IS_ERR(pclk))
>> - pclk = devm_clk_get_enabled(dev, "apb");
>> + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
>> + if (IS_ERR(*pclk))
>> + *pclk = devm_clk_get_enabled(dev, "apb");
>> + if (IS_ERR(*pclk))
>> + return PTR_ERR(*pclk);
>> + } else {
>> + /* Don't enable pclk for an AMBA device */
>> + *pclk = NULL;
>
> Now the "apb" clock won't be enabled for amba devices. I'm assuming
> that's fine if the clock was always called "apb_pclk" for them, but the
> commit that added the new clock name didn't specify any special casing
> either.
>
> Can we have a comment that says it's deliberate? But the more I think
> about it the more I'm confused why CTCU needed a different clock name to
> be defined, when all the other Coresight devices use "apb_pclk".
Hi James,
The original clock-name for CTCU is apb_pclk, but the dt-binding
maintainer request me to change it to apb, that's why the clock name is
different from others.
I am not why we need apb instead of apb_pclk in dt-binding. Maybe some
rules have changed for dt-binding requirement.
Thanks,
Jie
>
>> }
>> - return pclk;
>> + if (atclk) {
>> + *atclk = devm_clk_get_optional_enabled(dev, "atclk");
>> + if (IS_ERR(*atclk))
>> + return PTR_ERR(*atclk);
>> + }
>> +
>> + return 0;
>> }
>> #define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 9/9] coresight: Consolidate clock enabling
2025-04-02 0:55 ` Jie Gan
@ 2025-04-02 9:01 ` Leo Yan
2025-04-03 0:29 ` Jie Gan
0 siblings, 1 reply; 25+ messages in thread
From: Leo Yan @ 2025-04-02 9:01 UTC (permalink / raw)
To: Jie Gan
Cc: James Clark, Suzuki K Poulose, Mike Leach, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32, Rob Herring
Hi Jie,
[ + Rob ]
On Wed, Apr 02, 2025 at 08:55:51AM +0800, Jie Gan wrote:
[...]
> > > {
> > > - struct clk *pclk = NULL;
> > > + WARN_ON(!pclk);
> > > if (!dev_is_amba(dev)) {
> > > - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > > - if (IS_ERR(pclk))
> > > - pclk = devm_clk_get_enabled(dev, "apb");
> > > + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > > + if (IS_ERR(*pclk))
> > > + *pclk = devm_clk_get_enabled(dev, "apb");
> > > + if (IS_ERR(*pclk))
> > > + return PTR_ERR(*pclk);
> > > + } else {
> > > + /* Don't enable pclk for an AMBA device */
> > > + *pclk = NULL;
> >
> > Now the "apb" clock won't be enabled for amba devices. I'm assuming
> > that's fine if the clock was always called "apb_pclk" for them, but the
> > commit that added the new clock name didn't specify any special casing
> > either.
> >
> > Can we have a comment that says it's deliberate? But the more I think
> > about it the more I'm confused why CTCU needed a different clock name to
> > be defined, when all the other Coresight devices use "apb_pclk".
>
> Hi James,
>
> The original clock-name for CTCU is apb_pclk, but the dt-binding maintainer
> request me to change it to apb, that's why the clock name is different from
> others.
>
> I am not why we need apb instead of apb_pclk in dt-binding. Maybe some rules
> have changed for dt-binding requirement.
My conclusion is that if a device is an Arm Primecell peripheral, it
should use the clock name "apb_pclk" (See the DT binding doc [1]).
CTCU is not an Arm Primecell peripheral, so it does not need to strictly
follow up the clock naming for Primecell peripheral.
In Arm CoreSight framework, for code consistency, I would suggest
using the clock naming "apb_pclk" for the APB clock for a newly added
device that even it is not a Primecell peripheral.
(We don't need to make any change to the CTCU driver, as we need to
remain compatible with existed DTB blobs).
Cc'ing Rob in case he has any suggestions.
Thanks,
Leo
[1] Documentation/devicetree/bindings/arm/primecell.yaml
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 9/9] coresight: Consolidate clock enabling
2025-04-02 9:01 ` Leo Yan
@ 2025-04-03 0:29 ` Jie Gan
0 siblings, 0 replies; 25+ messages in thread
From: Jie Gan @ 2025-04-03 0:29 UTC (permalink / raw)
To: Leo Yan
Cc: James Clark, Suzuki K Poulose, Mike Leach, Anshuman Khandual,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32, Rob Herring
On 4/2/2025 5:01 PM, Leo Yan wrote:
> Hi Jie,
>
> [ + Rob ]
>
> On Wed, Apr 02, 2025 at 08:55:51AM +0800, Jie Gan wrote:
>
> [...]
>
>>>> {
>>>> - struct clk *pclk = NULL;
>>>> + WARN_ON(!pclk);
>>>> if (!dev_is_amba(dev)) {
>>>> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
>>>> - if (IS_ERR(pclk))
>>>> - pclk = devm_clk_get_enabled(dev, "apb");
>>>> + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
>>>> + if (IS_ERR(*pclk))
>>>> + *pclk = devm_clk_get_enabled(dev, "apb");
>>>> + if (IS_ERR(*pclk))
>>>> + return PTR_ERR(*pclk);
>>>> + } else {
>>>> + /* Don't enable pclk for an AMBA device */
>>>> + *pclk = NULL;
>>>
>>> Now the "apb" clock won't be enabled for amba devices. I'm assuming
>>> that's fine if the clock was always called "apb_pclk" for them, but the
>>> commit that added the new clock name didn't specify any special casing
>>> either.
>>>
>>> Can we have a comment that says it's deliberate? But the more I think
>>> about it the more I'm confused why CTCU needed a different clock name to
>>> be defined, when all the other Coresight devices use "apb_pclk".
>>
>> Hi James,
>>
>> The original clock-name for CTCU is apb_pclk, but the dt-binding maintainer
>> request me to change it to apb, that's why the clock name is different from
>> others.
>>
>> I am not why we need apb instead of apb_pclk in dt-binding. Maybe some rules
>> have changed for dt-binding requirement.
>
> My conclusion is that if a device is an Arm Primecell peripheral, it
> should use the clock name "apb_pclk" (See the DT binding doc [1]).
>
> CTCU is not an Arm Primecell peripheral, so it does not need to strictly
> follow up the clock naming for Primecell peripheral.
>
> In Arm CoreSight framework, for code consistency, I would suggest
> using the clock naming "apb_pclk" for the APB clock for a newly added
> device that even it is not a Primecell peripheral.
>
> (We don't need to make any change to the CTCU driver, as we need to
> remain compatible with existed DTB blobs).
>
> Cc'ing Rob in case he has any suggestions.
Hi Leo,
Thanks for the explanation. I agree with you, we should use the
"apb_pclk" for the APB clock for a newly added device.
Thanks,
Jie
>
> Thanks,
> Leo
>
> [1] Documentation/devicetree/bindings/arm/primecell.yaml
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/9] coresight: tmc: Support atclk
2025-03-27 11:37 ` [PATCH v1 1/9] coresight: tmc: Support atclk Leo Yan
@ 2025-04-03 5:50 ` Anshuman Khandual
2025-04-22 8:21 ` Leo Yan
0 siblings, 1 reply; 25+ messages in thread
From: Anshuman Khandual @ 2025-04-03 5:50 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 3/27/25 17:07, Leo Yan wrote:
> The atclk is an optional clock for the CoreSight TMC, but the driver
> misses to initialize it. In most cases, the TMC shares the same atclk
TMC shares the atclk or pclk clock with other coresight components ?
> with other CoreSight components. Since these components enable the
> clock before the TMC device is initialized, the TMC continues properly,
> which is why we don’t observe any lockup issues.
>
> This change enables atclk in probe of the TMC driver. Given the clock
> is optional, it is possible to return NULL if the clock does not exist.
> IS_ERR() is tolerant for this case.
Makes sense.
>
> Dynamically disable and enable atclk during suspend and resume. The
> clock pointers will never be error values if the driver has successfully
> probed, and the case of a NULL pointer case will be handled by the clock
> core layer. The driver data is always valid after probe. Therefore,
> remove the related checks. Also in the resume flow adds error handling.
Probably a good clean up.
>
> Fixes: bc4bf7fe98da ("coresight-tmc: add CoreSight TMC driver")
Right commit to attribute.
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-tmc-core.c | 22 +++++++++++++++++-----
> drivers/hwtracing/coresight/coresight-tmc.h | 2 ++
> 2 files changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 5978bcda2556..6aad2acd0378 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -789,6 +789,10 @@ static int __tmc_probe(struct device *dev, struct resource *res)
> struct coresight_desc desc = { 0 };
> struct coresight_dev_list *dev_list = NULL;
>
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
> +
Adding this check here in __tmc_probe() ensures that it gets called
both during AMBA and platform probe methods.
> ret = -ENOMEM;
>
> /* Validity for the resource is already checked by the AMBA core */
> @@ -1019,18 +1023,26 @@ static int tmc_runtime_suspend(struct device *dev)
> {
> struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> + clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->pclk);
> +
> return 0;
> }
>
> static int tmc_runtime_resume(struct device *dev)
> {
> struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
> + int ret;
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> - return 0;
> + ret = clk_prepare_enable(drvdata->pclk);
> + if (ret)
> + return ret;
> +
> + ret = clk_prepare_enable(drvdata->atclk);
> + if (ret)
> + clk_disable_unprepare(drvdata->pclk);
> +
> + return ret;
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 6541a27a018e..cbb4ba439158 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -210,6 +210,7 @@ struct tmc_resrv_buf {
>
> /**
> * struct tmc_drvdata - specifics associated to an TMC component
> + * @atclk: optional clock for the core parts of the TMC.
> * @pclk: APB clock if present, otherwise NULL
> * @base: memory mapped base address for this component.
> * @csdev: component vitals needed by the framework.
> @@ -244,6 +245,7 @@ struct tmc_resrv_buf {
> * Used by ETR/ETF.
> */
> struct tmc_drvdata {
> + struct clk *atclk;
> struct clk *pclk;
> void __iomem *base;
> struct coresight_device *csdev;
Otherwise, LGTM.
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 2/9] coresight: catu: Support atclk
2025-03-27 11:37 ` [PATCH v1 2/9] coresight: catu: " Leo Yan
@ 2025-04-03 6:02 ` Anshuman Khandual
0 siblings, 0 replies; 25+ messages in thread
From: Anshuman Khandual @ 2025-04-03 6:02 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 3/27/25 17:07, Leo Yan wrote:
> The atclk is an optional clock for the CoreSight CATU, but the driver
> misses to initialize it.
>
> This change enables atclk in probe of the CATU driver, and dynamically
> control the clock during suspend and resume.
>
> The checks for driver data and clocks in suspend and resume are not
> needed, remove them. Add error handling in the resume function.
>
> Fixes: fcacb5c154ba ("coresight: Introduce support for Coresight Address Translation Unit")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-catu.c | 22 +++++++++++++++++-----
> drivers/hwtracing/coresight/coresight-catu.h | 1 +
> 2 files changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
> index fa170c966bc3..9fcda5e49253 100644
> --- a/drivers/hwtracing/coresight/coresight-catu.c
> +++ b/drivers/hwtracing/coresight/coresight-catu.c
> @@ -513,6 +513,10 @@ static int __catu_probe(struct device *dev, struct resource *res)
> struct coresight_platform_data *pdata = NULL;
> void __iomem *base;
>
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
> +
> catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
> if (!catu_desc.name)
> return -ENOMEM;
> @@ -659,18 +663,26 @@ static int catu_runtime_suspend(struct device *dev)
> {
> struct catu_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> + clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->pclk);
> +
> return 0;
> }
>
> static int catu_runtime_resume(struct device *dev)
> {
> struct catu_drvdata *drvdata = dev_get_drvdata(dev);
> + int ret;
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> - return 0;
> + ret = clk_prepare_enable(drvdata->pclk);
> + if (ret)
> + return ret;
> +
> + ret = clk_prepare_enable(drvdata->atclk);
> + if (ret)
> + clk_disable_unprepare(drvdata->pclk);
> +
> + return ret;
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
> index 141feac1c14b..2fe31fed6cf1 100644
> --- a/drivers/hwtracing/coresight/coresight-catu.h
> +++ b/drivers/hwtracing/coresight/coresight-catu.h
> @@ -62,6 +62,7 @@
>
> struct catu_drvdata {
> struct clk *pclk;
> + struct clk *atclk;
> void __iomem *base;
> struct coresight_device *csdev;
> int irq;
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 3/9] coresight: etm4x: Support atclk
2025-03-27 11:37 ` [PATCH v1 3/9] coresight: etm4x: " Leo Yan
@ 2025-04-03 6:23 ` Anshuman Khandual
0 siblings, 0 replies; 25+ messages in thread
From: Anshuman Khandual @ 2025-04-03 6:23 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 3/27/25 17:07, Leo Yan wrote:
> 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")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-etm4x-core.c | 20 +++++++++++++++-----
> drivers/hwtracing/coresight/coresight-etm4x.h | 4 +++-
> 2 files changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index e5972f16abff..537d57006a25 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -2149,6 +2149,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;
> @@ -2397,8 +2401,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;
> }
> @@ -2406,11 +2410,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
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index bd7db36ba197..0c21832b5d69 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -919,7 +919,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.
> @@ -987,6 +988,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;
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately
2025-03-27 11:37 ` [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately Leo Yan
@ 2025-04-03 6:48 ` Anshuman Khandual
2025-04-22 12:24 ` Leo Yan
0 siblings, 1 reply; 25+ messages in thread
From: Anshuman Khandual @ 2025-04-03 6:48 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 3/27/25 17:07, Leo Yan wrote:
> The programming clock is enabled by AMBA bus driver before a dynamic
> probe. As a result, a CoreSight driver may redundantly enable the same
> clock.
>
> To avoid this, add a check for device type and skip enabling the
> programming clock for AMBA devices. The returned NULL pointer will be
> tolerated by the drivers.
>
> Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> include/linux/coresight.h | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index b888f6ed59b2..26eb4a61b992 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -476,15 +476,18 @@ static inline bool is_coresight_device(void __iomem *base)
> * Returns:
> *
> * clk - Clock is found and enabled
> + * NULL - Clock is not needed as it is managed by the AMBA bus driver
> * ERROR - Clock is found but failed to enable
> */
> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> {
> - struct clk *pclk;
> + struct clk *pclk = NULL;
>
> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> - if (IS_ERR(pclk))
> - pclk = devm_clk_get_enabled(dev, "apb");
> + if (!dev_is_amba(dev)) {
> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(pclk))
> + pclk = devm_clk_get_enabled(dev, "apb");
> + }
>
> return pclk;
> }
coresight_get_enable_apb_pclk() mostly gets called in the platform driver
probe paths but they are also present in some AMBA probe paths. Hence why
cannot the callers in AMBA probe paths get fixed instead ? Besides return
value never gets checked for NULL, which would have to be changed as well
if coresight_get_enable_apb_pclk() starts returning NULL values for AMBA
devices.
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
I guess this redundancy should be fixed at the AMBA probe callers.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 7/9] coresight: Make clock sequence consistent
2025-03-27 11:38 ` [PATCH v1 7/9] coresight: Make clock sequence consistent Leo Yan
@ 2025-04-03 7:10 ` Anshuman Khandual
2025-04-22 9:21 ` Leo Yan
0 siblings, 1 reply; 25+ messages in thread
From: Anshuman Khandual @ 2025-04-03 7:10 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 3/27/25 17:08, Leo Yan wrote:
> Since atclk is enabled after pclk during the probe phase, this commit
> maintains the same sequence for the runtime resume flow.
>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-funnel.c | 6 +++---
> drivers/hwtracing/coresight/coresight-replicator.c | 6 +++---
> drivers/hwtracing/coresight/coresight-stm.c | 6 +++---
> drivers/hwtracing/coresight/coresight-tpiu.c | 6 +++---
> 4 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index ec6d3e656548..e378c2fffca9 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -299,11 +299,11 @@ static int funnel_runtime_resume(struct device *dev)
> {
> struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> -
> if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> clk_prepare_enable(drvdata->pclk);
> +
> + if (drvdata && !IS_ERR(drvdata->atclk))
> + clk_prepare_enable(drvdata->atclk);
> return 0;
> }
funnel_probe() enables pclk after atclk though - which needs to be
reversed as well ?
static int funnel_probe(struct device *dev, struct resource *res)
{
..................
drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
if (IS_ERR(drvdata->atclk))
return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
return PTR_ERR(drvdata->pclk);
> #endif
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 460af0f7b537..78854f586e89 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -337,11 +337,11 @@ static int replicator_runtime_resume(struct device *dev)
> {
> struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> -
> if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> clk_prepare_enable(drvdata->pclk);
> +
> + if (drvdata && !IS_ERR(drvdata->atclk))
> + clk_prepare_enable(drvdata->atclk);
> return 0;
> }
replicator_probe() enables pclk after atclk though - which needs to be
reversed as well ?
static int replicator_probe(struct device *dev, struct resource *res)
{
..................
drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
if (IS_ERR(drvdata->atclk))
return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
return PTR_ERR(drvdata->pclk);
> #endif
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index f13fbab4d7a2..ddb4f6678efd 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -972,11 +972,11 @@ static int stm_runtime_resume(struct device *dev)
> {
> struct stm_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> -
> if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> clk_prepare_enable(drvdata->pclk);
> +
> + if (drvdata && !IS_ERR(drvdata->atclk))
> + clk_prepare_enable(drvdata->atclk);
> return 0;
> }
> #endif
same here as well.
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index cac1b5bba086..8212959f60d4 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -220,11 +220,11 @@ static int tpiu_runtime_resume(struct device *dev)
> {
> struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> -
> if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> clk_prepare_enable(drvdata->pclk);
> +
> + if (drvdata && !IS_ERR(drvdata->atclk))
> + clk_prepare_enable(drvdata->atclk);
> return 0;
> }
> #endif
same here as well.
I assume this patch is trying to have the same clock sequence enablement
during original probe and resume path and then just the reverse sequence
during suspend path.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 6/9] coresight: Disable trace bus clock properly
2025-03-27 11:38 ` [PATCH v1 6/9] coresight: Disable trace bus clock properly Leo Yan
@ 2025-04-03 7:25 ` Anshuman Khandual
2025-04-22 12:29 ` Leo Yan
0 siblings, 1 reply; 25+ messages in thread
From: Anshuman Khandual @ 2025-04-03 7:25 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel,
linux-stm32
On 3/27/25 17:08, Leo Yan wrote:
> Some CoreSight components have trace bus clocks 'atclk' and are enabled
> using clk_prepare_enable(). These clocks are not disabled when modules
> exit.
>
> As atclk is optional, use devm_clk_get_optional_enabled() to manage it.
> The benefit is the driver model layer can automatically disable and
> release clocks.
>
> Check the returned value with IS_ERR() to detect errors but leave the
> NULL pointer case if the clock is not found. And remove the error
> handling codes which are no longer needed.
>
> Fixes: d1839e687773 ("coresight: etm: retrieve and handle atclk")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
This patch probably should be positioned right after [PATCH 4/9] which
replaces pclk clock init with devm_clk_get_enabled().
> ---
> drivers/hwtracing/coresight/coresight-etb10.c | 10 ++++------
> drivers/hwtracing/coresight/coresight-etm3x-core.c | 9 +++------
> drivers/hwtracing/coresight/coresight-funnel.c | 36 +++++++++++-------------------------
> drivers/hwtracing/coresight/coresight-replicator.c | 34 ++++++++++------------------------
> drivers/hwtracing/coresight/coresight-stm.c | 9 +++------
> drivers/hwtracing/coresight/coresight-tpiu.c | 10 +++-------
> 6 files changed, 34 insertions(+), 74 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
> index 7948597d483d..45c2f8f50a3f 100644
> --- a/drivers/hwtracing/coresight/coresight-etb10.c
> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
> @@ -730,12 +730,10 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
> - if (!IS_ERR(drvdata->atclk)) {
> - ret = clk_prepare_enable(drvdata->atclk);
> - if (ret)
> - return ret;
> - }
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
> +
> dev_set_drvdata(dev, drvdata);
>
> /* validity for the resource is already checked by the AMBA core */
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> index 8927bfaf3af2..adbb134f80e6 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> @@ -832,12 +832,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
>
> spin_lock_init(&drvdata->spinlock);
>
> - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
> - if (!IS_ERR(drvdata->atclk)) {
> - ret = clk_prepare_enable(drvdata->atclk);
> - if (ret)
> - return ret;
> - }
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
>
> drvdata->cpu = coresight_get_cpu(dev);
> if (drvdata->cpu < 0)
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index 3fb9d0a37d55..ec6d3e656548 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -213,7 +213,6 @@ ATTRIBUTE_GROUPS(coresight_funnel);
>
> static int funnel_probe(struct device *dev, struct resource *res)
> {
> - int ret;
> void __iomem *base;
> struct coresight_platform_data *pdata = NULL;
> struct funnel_drvdata *drvdata;
> @@ -231,12 +230,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
> - if (!IS_ERR(drvdata->atclk)) {
> - ret = clk_prepare_enable(drvdata->atclk);
> - if (ret)
> - return ret;
> - }
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> @@ -248,10 +244,8 @@ static int funnel_probe(struct device *dev, struct resource *res)
> */
> if (res) {
> base = devm_ioremap_resource(dev, res);
> - if (IS_ERR(base)) {
> - ret = PTR_ERR(base);
> - goto out_disable_clk;
> - }
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> drvdata->base = base;
> desc.groups = coresight_funnel_groups;
> desc.access = CSDEV_ACCESS_IOMEM(base);
> @@ -260,10 +254,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
> dev_set_drvdata(dev, drvdata);
>
> pdata = coresight_get_platform_data(dev);
> - if (IS_ERR(pdata)) {
> - ret = PTR_ERR(pdata);
> - goto out_disable_clk;
> - }
> + if (IS_ERR(pdata))
> + return PTR_ERR(pdata);
> +
> dev->platform_data = pdata;
>
> raw_spin_lock_init(&drvdata->spinlock);
> @@ -273,17 +266,10 @@ static int funnel_probe(struct device *dev, struct resource *res)
> desc.pdata = pdata;
> desc.dev = dev;
> drvdata->csdev = coresight_register(&desc);
> - if (IS_ERR(drvdata->csdev)) {
> - ret = PTR_ERR(drvdata->csdev);
> - goto out_disable_clk;
> - }
> + if (IS_ERR(drvdata->csdev))
> + return PTR_ERR(drvdata->csdev);
>
> - ret = 0;
> -
> -out_disable_clk:
> - if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> - return ret;
> + return 0;
> }
>
> static int funnel_remove(struct device *dev)
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 87346617b852..460af0f7b537 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -219,7 +219,6 @@ static const struct attribute_group *replicator_groups[] = {
>
> static int replicator_probe(struct device *dev, struct resource *res)
> {
> - int ret = 0;
> struct coresight_platform_data *pdata = NULL;
> struct replicator_drvdata *drvdata;
> struct coresight_desc desc = { 0 };
> @@ -238,12 +237,9 @@ static int replicator_probe(struct device *dev, struct resource *res)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
> - if (!IS_ERR(drvdata->atclk)) {
> - ret = clk_prepare_enable(drvdata->atclk);
> - if (ret)
> - return ret;
> - }
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> @@ -255,10 +251,8 @@ static int replicator_probe(struct device *dev, struct resource *res)
> */
> if (res) {
> base = devm_ioremap_resource(dev, res);
> - if (IS_ERR(base)) {
> - ret = PTR_ERR(base);
> - goto out_disable_clk;
> - }
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> drvdata->base = base;
> desc.groups = replicator_groups;
> desc.access = CSDEV_ACCESS_IOMEM(base);
> @@ -271,10 +265,8 @@ static int replicator_probe(struct device *dev, struct resource *res)
> dev_set_drvdata(dev, drvdata);
>
> pdata = coresight_get_platform_data(dev);
> - if (IS_ERR(pdata)) {
> - ret = PTR_ERR(pdata);
> - goto out_disable_clk;
> - }
> + if (IS_ERR(pdata))
> + return PTR_ERR(pdata);
> dev->platform_data = pdata;
>
> raw_spin_lock_init(&drvdata->spinlock);
> @@ -285,17 +277,11 @@ static int replicator_probe(struct device *dev, struct resource *res)
> desc.dev = dev;
>
> drvdata->csdev = coresight_register(&desc);
> - if (IS_ERR(drvdata->csdev)) {
> - ret = PTR_ERR(drvdata->csdev);
> - goto out_disable_clk;
> - }
> + if (IS_ERR(drvdata->csdev))
> + return PTR_ERR(drvdata->csdev);
>
> replicator_reset(drvdata);
> -
> -out_disable_clk:
> - if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> - return ret;
> + return 0;
> }
>
> static int replicator_remove(struct device *dev)
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index c32d0bd92f30..f13fbab4d7a2 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -842,12 +842,9 @@ static int __stm_probe(struct device *dev, struct resource *res)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
> - if (!IS_ERR(drvdata->atclk)) {
> - ret = clk_prepare_enable(drvdata->atclk);
> - if (ret)
> - return ret;
> - }
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index 4b9634941752..cac1b5bba086 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -128,7 +128,6 @@ static const struct coresight_ops tpiu_cs_ops = {
>
> static int __tpiu_probe(struct device *dev, struct resource *res)
> {
> - int ret;
> void __iomem *base;
> struct coresight_platform_data *pdata = NULL;
> struct tpiu_drvdata *drvdata;
> @@ -144,12 +143,9 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
>
> spin_lock_init(&drvdata->spinlock);
>
> - drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
> - if (!IS_ERR(drvdata->atclk)) {
> - ret = clk_prepare_enable(drvdata->atclk);
> - if (ret)
> - return ret;
> - }
> + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(drvdata->atclk))
> + return PTR_ERR(drvdata->atclk);
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 1/9] coresight: tmc: Support atclk
2025-04-03 5:50 ` Anshuman Khandual
@ 2025-04-22 8:21 ` Leo Yan
0 siblings, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-04-22 8:21 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Greg Kroah-Hartman, coresight,
linux-arm-kernel, linux-kernel, linux-stm32
On Thu, Apr 03, 2025 at 11:20:38AM +0530, Anshuman Khandual wrote:
> On 3/27/25 17:07, Leo Yan wrote:
> > The atclk is an optional clock for the CoreSight TMC, but the driver
> > misses to initialize it. In most cases, the TMC shares the same atclk
>
> TMC shares the atclk or pclk clock with other coresight components ?
I will refine the commit log for this.
[...]
> > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > @@ -789,6 +789,10 @@ static int __tmc_probe(struct device *dev, struct resource *res)
> > struct coresight_desc desc = { 0 };
> > struct coresight_dev_list *dev_list = NULL;
> >
> > + drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> > + if (IS_ERR(drvdata->atclk))
> > + return PTR_ERR(drvdata->atclk);
> > +
>
> Adding this check here in __tmc_probe() ensures that it gets called
> both during AMBA and platform probe methods.
Yes.
> > /**
> > * struct tmc_drvdata - specifics associated to an TMC component
> > + * @atclk: optional clock for the core parts of the TMC.
> > * @pclk: APB clock if present, otherwise NULL
> > * @base: memory mapped base address for this component.
> > * @csdev: component vitals needed by the framework.
> > @@ -244,6 +245,7 @@ struct tmc_resrv_buf {
> > * Used by ETR/ETF.
> > */
> > struct tmc_drvdata {
> > + struct clk *atclk;
> > struct clk *pclk;
> > void __iomem *base;
> > struct coresight_device *csdev;
>
> Otherwise, LGTM.
>
> Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Thanks for reviewing!
Leo
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 7/9] coresight: Make clock sequence consistent
2025-04-03 7:10 ` Anshuman Khandual
@ 2025-04-22 9:21 ` Leo Yan
0 siblings, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-04-22 9:21 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Greg Kroah-Hartman, coresight,
linux-arm-kernel, linux-kernel, linux-stm32
On Thu, Apr 03, 2025 at 12:40:39PM +0530, Anshuman Khandual wrote:
> On 3/27/25 17:08, Leo Yan wrote:
> > Since atclk is enabled after pclk during the probe phase, this commit
> > maintains the same sequence for the runtime resume flow.
> >
> > Signed-off-by: Leo Yan <leo.yan@arm.com>
> > ---
> > drivers/hwtracing/coresight/coresight-funnel.c | 6 +++---
> > drivers/hwtracing/coresight/coresight-replicator.c | 6 +++---
> > drivers/hwtracing/coresight/coresight-stm.c | 6 +++---
> > drivers/hwtracing/coresight/coresight-tpiu.c | 6 +++---
> > 4 files changed, 12 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> > index ec6d3e656548..e378c2fffca9 100644
> > --- a/drivers/hwtracing/coresight/coresight-funnel.c
> > +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> > @@ -299,11 +299,11 @@ static int funnel_runtime_resume(struct device *dev)
> > {
> > struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
> >
> > - if (drvdata && !IS_ERR(drvdata->atclk))
> > - clk_prepare_enable(drvdata->atclk);
> > -
> > if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> > clk_prepare_enable(drvdata->pclk);
> > +
> > + if (drvdata && !IS_ERR(drvdata->atclk))
> > + clk_prepare_enable(drvdata->atclk);
> > return 0;
> > }
>
> funnel_probe() enables pclk after atclk though - which needs to be
> reversed as well ?
Good point!
The key point is a dynamic probe enables pclk clock in AMBA bus driver,
which is anyway prior to enable atclk.
We need to keep consistent flow for all flows (static probe, dynamic
probe, runtime PM resume). The patch 09 consolidates clock enabling for
static and dynamic probe, and this patch is for runtime PM.
For a better organization, I will place this patch after the patch 09
in the next spin.
[...]
> I assume this patch is trying to have the same clock sequence enablement
> during original probe and resume path and then just the reverse sequence
> during suspend path.
Correct. As said, the patch 09 is for clock enabling sequence in
probe, and this patch is for the resume path.
Thanks,
Leo
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately
2025-04-03 6:48 ` Anshuman Khandual
@ 2025-04-22 12:24 ` Leo Yan
0 siblings, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-04-22 12:24 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Greg Kroah-Hartman, coresight,
linux-arm-kernel, linux-kernel, linux-stm32
On Thu, Apr 03, 2025 at 12:18:56PM +0530, Anshuman Khandual wrote:
> On 3/27/25 17:07, Leo Yan wrote:
> > The programming clock is enabled by AMBA bus driver before a dynamic
> > probe. As a result, a CoreSight driver may redundantly enable the same
> > clock.
> >
> > To avoid this, add a check for device type and skip enabling the
> > programming clock for AMBA devices. The returned NULL pointer will be
> > tolerated by the drivers.
> >
> > Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
> > Signed-off-by: Leo Yan <leo.yan@arm.com>
> > ---
> > include/linux/coresight.h | 11 +++++++----
> > 1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > index b888f6ed59b2..26eb4a61b992 100644
> > --- a/include/linux/coresight.h
> > +++ b/include/linux/coresight.h
> > @@ -476,15 +476,18 @@ static inline bool is_coresight_device(void __iomem *base)
> > * Returns:
> > *
> > * clk - Clock is found and enabled
> > + * NULL - Clock is not needed as it is managed by the AMBA bus driver
> > * ERROR - Clock is found but failed to enable
> > */
> > static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> > {
> > - struct clk *pclk;
> > + struct clk *pclk = NULL;
> >
> > - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > - if (IS_ERR(pclk))
> > - pclk = devm_clk_get_enabled(dev, "apb");
> > + if (!dev_is_amba(dev)) {
> > + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > + if (IS_ERR(pclk))
> > + pclk = devm_clk_get_enabled(dev, "apb");
> > + }
> >
> > return pclk;
> > }
>
> coresight_get_enable_apb_pclk() mostly gets called in the platform driver
> probe paths but they are also present in some AMBA probe paths. Hence why
> cannot the callers in AMBA probe paths get fixed instead ?
With this approach, clocking operations are different in static probe
and dynamic probe. This causes complexity for CoreSight drivers.
After consideration, we decided to use a central place for clock
initialization. Patch 09 follows the idea to encapsulate pclk and atclk
operations in the coresight_get_enable_clocks() function.
> Besides return
> value never gets checked for NULL, which would have to be changed as well
> if coresight_get_enable_apb_pclk() starts returning NULL values for AMBA
> devices.
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> return -ENODEV;
I confirmed CoreSight drivers have used this condition, so it is safe
to return NULL pointer from coresight_get_enable_apb_pclk().
Thanks,
Leo
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v1 6/9] coresight: Disable trace bus clock properly
2025-04-03 7:25 ` Anshuman Khandual
@ 2025-04-22 12:29 ` Leo Yan
0 siblings, 0 replies; 25+ messages in thread
From: Leo Yan @ 2025-04-22 12:29 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Greg Kroah-Hartman, coresight,
linux-arm-kernel, linux-kernel, linux-stm32
On Thu, Apr 03, 2025 at 12:55:46PM +0530, Anshuman Khandual wrote:
>
> On 3/27/25 17:08, Leo Yan wrote:
> > Some CoreSight components have trace bus clocks 'atclk' and are enabled
> > using clk_prepare_enable(). These clocks are not disabled when modules
> > exit.
> >
> > As atclk is optional, use devm_clk_get_optional_enabled() to manage it.
> > The benefit is the driver model layer can automatically disable and
> > release clocks.
> >
> > Check the returned value with IS_ERR() to detect errors but leave the
> > NULL pointer case if the clock is not found. And remove the error
> > handling codes which are no longer needed.
> >
> > Fixes: d1839e687773 ("coresight: etm: retrieve and handle atclk")
> > Signed-off-by: Leo Yan <leo.yan@arm.com>
>
> This patch probably should be positioned right after [PATCH 4/9] which
> replaces pclk clock init with devm_clk_get_enabled().
Sure. Will reorder patches for this.
Thanks,
Leo
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2025-04-22 13:46 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-27 11:37 [PATCH v1 0/9] coresight: Fix and improve clock usage Leo Yan
2025-03-27 11:37 ` [PATCH v1 1/9] coresight: tmc: Support atclk Leo Yan
2025-04-03 5:50 ` Anshuman Khandual
2025-04-22 8:21 ` Leo Yan
2025-03-27 11:37 ` [PATCH v1 2/9] coresight: catu: " Leo Yan
2025-04-03 6:02 ` Anshuman Khandual
2025-03-27 11:37 ` [PATCH v1 3/9] coresight: etm4x: " Leo Yan
2025-04-03 6:23 ` Anshuman Khandual
2025-03-27 11:37 ` [PATCH v1 4/9] coresight: Disable programming clock properly Leo Yan
2025-03-27 11:37 ` [PATCH v1 5/9] coresight: Avoid enable programming clock duplicately Leo Yan
2025-04-03 6:48 ` Anshuman Khandual
2025-04-22 12:24 ` Leo Yan
2025-03-27 11:38 ` [PATCH v1 6/9] coresight: Disable trace bus clock properly Leo Yan
2025-04-03 7:25 ` Anshuman Khandual
2025-04-22 12:29 ` Leo Yan
2025-03-27 11:38 ` [PATCH v1 7/9] coresight: Make clock sequence consistent Leo Yan
2025-04-03 7:10 ` Anshuman Khandual
2025-04-22 9:21 ` Leo Yan
2025-03-27 11:38 ` [PATCH v1 8/9] coresight: Refactor runtime PM Leo Yan
2025-03-27 11:38 ` [PATCH v1 9/9] coresight: Consolidate clock enabling Leo Yan
2025-04-01 14:58 ` James Clark
2025-04-01 15:29 ` Leo Yan
2025-04-02 0:55 ` Jie Gan
2025-04-02 9:01 ` Leo Yan
2025-04-03 0:29 ` Jie Gan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.