Skip to content

Commit 1abc1b2

Browse files
Leo-YanSuzuki K Poulose
authored andcommitted
coresight: Appropriately disable programming clocks
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 programming clock by replacing clk_get() and clk_prepare_enable() with devm_clk_get_optional_enabled() for enabling APB clock. If the "apb_pclk" clock is not found, a NULL pointer is returned, and the function proceeds to attempt enabling the "apb" clock. Since ACPI platforms rely on firmware to manage clocks, returning a NULL pointer in this case leaves clock management to the firmware rather than the driver. This effectively avoids a clock imbalance issue during module removal - where the clock could be disabled twice: once during the ACPI runtime suspend and again during the devm resource release. 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: 73d779a ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices") Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com> Tested-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20250731-arm_cs_fix_clock_v4-v6-4-1dfe10bb3f6f@arm.com
1 parent 40c0cdc commit 1abc1b2

10 files changed

Lines changed: 21 additions & 59 deletions

drivers/hwtracing/coresight/coresight-catu.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ static int catu_platform_probe(struct platform_device *pdev)
636636

637637
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
638638
if (IS_ERR(drvdata->pclk))
639-
return -ENODEV;
639+
return PTR_ERR(drvdata->pclk);
640640

641641
pm_runtime_get_noresume(&pdev->dev);
642642
pm_runtime_set_active(&pdev->dev);
@@ -645,11 +645,8 @@ static int catu_platform_probe(struct platform_device *pdev)
645645
dev_set_drvdata(&pdev->dev, drvdata);
646646
ret = __catu_probe(&pdev->dev, res);
647647
pm_runtime_put(&pdev->dev);
648-
if (ret) {
648+
if (ret)
649649
pm_runtime_disable(&pdev->dev);
650-
if (!IS_ERR_OR_NULL(drvdata->pclk))
651-
clk_put(drvdata->pclk);
652-
}
653650

654651
return ret;
655652
}
@@ -663,8 +660,6 @@ static void catu_platform_remove(struct platform_device *pdev)
663660

664661
__catu_remove(&pdev->dev);
665662
pm_runtime_disable(&pdev->dev);
666-
if (!IS_ERR_OR_NULL(drvdata->pclk))
667-
clk_put(drvdata->pclk);
668663
}
669664

670665
#ifdef CONFIG_PM

drivers/hwtracing/coresight/coresight-cpu-debug.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ static int debug_platform_probe(struct platform_device *pdev)
699699

700700
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
701701
if (IS_ERR(drvdata->pclk))
702-
return -ENODEV;
702+
return PTR_ERR(drvdata->pclk);
703703

704704
dev_set_drvdata(&pdev->dev, drvdata);
705705
pm_runtime_get_noresume(&pdev->dev);
@@ -710,8 +710,6 @@ static int debug_platform_probe(struct platform_device *pdev)
710710
if (ret) {
711711
pm_runtime_put_noidle(&pdev->dev);
712712
pm_runtime_disable(&pdev->dev);
713-
if (!IS_ERR_OR_NULL(drvdata->pclk))
714-
clk_put(drvdata->pclk);
715713
}
716714
return ret;
717715
}
@@ -725,8 +723,6 @@ static void debug_platform_remove(struct platform_device *pdev)
725723

726724
__debug_remove(&pdev->dev);
727725
pm_runtime_disable(&pdev->dev);
728-
if (!IS_ERR_OR_NULL(drvdata->pclk))
729-
clk_put(drvdata->pclk);
730726
}
731727

732728
#ifdef CONFIG_ACPI

drivers/hwtracing/coresight/coresight-ctcu-core.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static int ctcu_probe(struct platform_device *pdev)
209209

210210
drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
211211
if (IS_ERR(drvdata->apb_clk))
212-
return -ENODEV;
212+
return PTR_ERR(drvdata->apb_clk);
213213

214214
cfgs = of_device_get_match_data(dev);
215215
if (cfgs) {
@@ -233,12 +233,8 @@ static int ctcu_probe(struct platform_device *pdev)
233233
desc.access = CSDEV_ACCESS_IOMEM(base);
234234

235235
drvdata->csdev = coresight_register(&desc);
236-
if (IS_ERR(drvdata->csdev)) {
237-
if (!IS_ERR_OR_NULL(drvdata->apb_clk))
238-
clk_put(drvdata->apb_clk);
239-
236+
if (IS_ERR(drvdata->csdev))
240237
return PTR_ERR(drvdata->csdev);
241-
}
242238

243239
return 0;
244240
}
@@ -275,8 +271,6 @@ static void ctcu_platform_remove(struct platform_device *pdev)
275271

276272
ctcu_remove(pdev);
277273
pm_runtime_disable(&pdev->dev);
278-
if (!IS_ERR_OR_NULL(drvdata->apb_clk))
279-
clk_put(drvdata->apb_clk);
280274
}
281275

282276
#ifdef CONFIG_PM

drivers/hwtracing/coresight/coresight-etm4x-core.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,14 +2309,12 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
23092309

23102310
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
23112311
if (IS_ERR(drvdata->pclk))
2312-
return -ENODEV;
2312+
return PTR_ERR(drvdata->pclk);
23132313

23142314
if (res) {
23152315
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
2316-
if (IS_ERR(drvdata->base)) {
2317-
clk_put(drvdata->pclk);
2316+
if (IS_ERR(drvdata->base))
23182317
return PTR_ERR(drvdata->base);
2319-
}
23202318
}
23212319

23222320
dev_set_drvdata(&pdev->dev, drvdata);
@@ -2423,9 +2421,6 @@ static void etm4_remove_platform_dev(struct platform_device *pdev)
24232421
if (drvdata)
24242422
etm4_remove_dev(drvdata);
24252423
pm_runtime_disable(&pdev->dev);
2426-
2427-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
2428-
clk_put(drvdata->pclk);
24292424
}
24302425

24312426
static const struct amba_id etm4_ids[] = {

drivers/hwtracing/coresight/coresight-funnel.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
240240

241241
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
242242
if (IS_ERR(drvdata->pclk))
243-
return -ENODEV;
243+
return PTR_ERR(drvdata->pclk);
244244

245245
/*
246246
* Map the device base for dynamic-funnel, which has been
@@ -284,8 +284,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
284284
out_disable_clk:
285285
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
286286
clk_disable_unprepare(drvdata->atclk);
287-
if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
288-
clk_disable_unprepare(drvdata->pclk);
289287
return ret;
290288
}
291289

@@ -355,8 +353,6 @@ static void funnel_platform_remove(struct platform_device *pdev)
355353

356354
funnel_remove(&pdev->dev);
357355
pm_runtime_disable(&pdev->dev);
358-
if (!IS_ERR_OR_NULL(drvdata->pclk))
359-
clk_put(drvdata->pclk);
360356
}
361357

362358
static const struct of_device_id funnel_match[] = {

drivers/hwtracing/coresight/coresight-replicator.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
247247

248248
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
249249
if (IS_ERR(drvdata->pclk))
250-
return -ENODEV;
250+
return PTR_ERR(drvdata->pclk);
251251

252252
/*
253253
* Map the device base for dynamic-replicator, which has been
@@ -296,8 +296,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
296296
out_disable_clk:
297297
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
298298
clk_disable_unprepare(drvdata->atclk);
299-
if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
300-
clk_disable_unprepare(drvdata->pclk);
301299
return ret;
302300
}
303301

@@ -335,8 +333,6 @@ static void replicator_platform_remove(struct platform_device *pdev)
335333

336334
replicator_remove(&pdev->dev);
337335
pm_runtime_disable(&pdev->dev);
338-
if (!IS_ERR_OR_NULL(drvdata->pclk))
339-
clk_put(drvdata->pclk);
340336
}
341337

342338
#ifdef CONFIG_PM

drivers/hwtracing/coresight/coresight-stm.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ static int __stm_probe(struct device *dev, struct resource *res)
851851

852852
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
853853
if (IS_ERR(drvdata->pclk))
854-
return -ENODEV;
854+
return PTR_ERR(drvdata->pclk);
855855
dev_set_drvdata(dev, drvdata);
856856

857857
base = devm_ioremap_resource(dev, res);
@@ -1033,8 +1033,6 @@ static void stm_platform_remove(struct platform_device *pdev)
10331033

10341034
__stm_remove(&pdev->dev);
10351035
pm_runtime_disable(&pdev->dev);
1036-
if (!IS_ERR_OR_NULL(drvdata->pclk))
1037-
clk_put(drvdata->pclk);
10381036
}
10391037

10401038
#ifdef CONFIG_ACPI

drivers/hwtracing/coresight/coresight-tmc-core.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ static int tmc_platform_probe(struct platform_device *pdev)
981981

982982
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
983983
if (IS_ERR(drvdata->pclk))
984-
return -ENODEV;
984+
return PTR_ERR(drvdata->pclk);
985985

986986
dev_set_drvdata(&pdev->dev, drvdata);
987987
pm_runtime_get_noresume(&pdev->dev);
@@ -1005,8 +1005,6 @@ static void tmc_platform_remove(struct platform_device *pdev)
10051005

10061006
__tmc_remove(&pdev->dev);
10071007
pm_runtime_disable(&pdev->dev);
1008-
if (!IS_ERR_OR_NULL(drvdata->pclk))
1009-
clk_put(drvdata->pclk);
10101008
}
10111009

10121010
#ifdef CONFIG_PM

drivers/hwtracing/coresight/coresight-tpiu.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
153153

154154
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
155155
if (IS_ERR(drvdata->pclk))
156-
return -ENODEV;
156+
return PTR_ERR(drvdata->pclk);
157157
dev_set_drvdata(dev, drvdata);
158158

159159
/* Validity for the resource is already checked by the AMBA core */
@@ -293,8 +293,6 @@ static void tpiu_platform_remove(struct platform_device *pdev)
293293

294294
__tpiu_remove(&pdev->dev);
295295
pm_runtime_disable(&pdev->dev);
296-
if (!IS_ERR_OR_NULL(drvdata->pclk))
297-
clk_put(drvdata->pclk);
298296
}
299297

300298
#ifdef CONFIG_ACPI

include/linux/coresight.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef _LINUX_CORESIGHT_H
77
#define _LINUX_CORESIGHT_H
88

9+
#include <linux/acpi.h>
910
#include <linux/amba/bus.h>
1011
#include <linux/clk.h>
1112
#include <linux/device.h>
@@ -480,26 +481,21 @@ static inline bool is_coresight_device(void __iomem *base)
480481
* Returns:
481482
*
482483
* clk - Clock is found and enabled
483-
* NULL - clock is not found
484+
* NULL - Clock is controlled by firmware (ACPI device only)
484485
* ERROR - Clock is found but failed to enable
485486
*/
486487
static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
487488
{
488489
struct clk *pclk;
489-
int ret;
490490

491-
pclk = clk_get(dev, "apb_pclk");
492-
if (IS_ERR(pclk)) {
493-
pclk = clk_get(dev, "apb");
494-
if (IS_ERR(pclk))
495-
return NULL;
496-
}
491+
/* Firmware controls clocks for an ACPI device. */
492+
if (has_acpi_companion(dev))
493+
return NULL;
494+
495+
pclk = devm_clk_get_optional_enabled(dev, "apb_pclk");
496+
if (!pclk)
497+
pclk = devm_clk_get_optional_enabled(dev, "apb");
497498

498-
ret = clk_prepare_enable(pclk);
499-
if (ret) {
500-
clk_put(pclk);
501-
return ERR_PTR(ret);
502-
}
503499
return pclk;
504500
}
505501

0 commit comments

Comments
 (0)