coresight: Refactor runtime PM

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.

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-10-1dfe10bb3f6f@arm.com
This commit is contained in:
Leo Yan 2025-07-31 13:23:46 +01:00 committed by Suzuki K Poulose
parent 7b20a4fac7
commit dc783892cc
8 changed files with 53 additions and 60 deletions

View File

@ -731,8 +731,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;
}
@ -740,9 +740,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

View File

@ -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

View File

@ -809,8 +809,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;
}
@ -819,10 +818,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

View File

@ -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

View File

@ -284,11 +284,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;
}
@ -296,13 +293,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;
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

View File

@ -323,24 +323,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

View File

@ -957,24 +957,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

View File

@ -206,24 +206,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