mirror of https://github.com/torvalds/linux.git
coresight: Appropriately disable trace bus clocks
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: d1839e6877 ("coresight: etm: retrieve and handle atclk")
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250731-arm_cs_fix_clock_v4-v6-5-1dfe10bb3f6f@arm.com
This commit is contained in:
parent
1abc1b212e
commit
a8f2d480f1
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -261,10 +255,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);
|
||||
|
|
@ -274,17 +267,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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -272,10 +266,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);
|
||||
|
|
@ -286,17 +278,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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue