coresight: Take a reference on csdev

coresight_get_ref() currently pins the provider module and takes a
reference on the parent device, but it does not pin &csdev->dev. Take a
reference on &csdev->dev when grabbing a CoreSight device and drop it in
coresight_put_ref().

Reorder the sequence to follow child-to-parent dependencies: first take
a reference on csdev, then on the parent device and grab the driver
module. Once the data and module are pinned, take a PM runtime
reference to power on the hardware.

Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Tested-by: James Clark <james.clark@linaro.org>
Tested-by: Jie Gan <jie.gan@oss.qualcomm.com>
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/20260515-arm_coresight_path_power_management_improvement-v14-8-f88c4a3ecfe9@arm.com
This commit is contained in:
Leo Yan 2026-05-15 21:08:15 +01:00 committed by Suzuki K Poulose
parent f37bc31447
commit 6317302ae2

View File

@ -651,15 +651,29 @@ struct coresight_device *coresight_get_sink_by_id(u32 id)
*/
static bool coresight_get_ref(struct coresight_device *csdev)
{
struct device *dev = csdev->dev.parent;
struct device *dev = &csdev->dev;
struct device *parent = csdev->dev.parent;
struct device_driver *drv;
/* Make sure csdev can't go away */
get_device(dev);
/* Make sure parent device can't go away */
get_device(parent);
/* Make sure the driver can't be removed */
if (!try_module_get(dev->driver->owner))
return false;
/* Make sure the device can't go away */
get_device(dev);
pm_runtime_get_sync(dev);
drv = parent->driver;
if (!drv || !try_module_get(drv->owner))
goto err_module;
/* Make sure the device is powered on */
pm_runtime_get_sync(parent);
return true;
err_module:
put_device(parent);
put_device(dev);
return false;
}
/**
@ -670,11 +684,15 @@ static bool coresight_get_ref(struct coresight_device *csdev)
*/
static void coresight_put_ref(struct coresight_device *csdev)
{
struct device *dev = csdev->dev.parent;
struct device *dev = &csdev->dev;
struct device *parent = csdev->dev.parent;
struct device_driver *drv = parent->driver;
pm_runtime_put(dev);
pm_runtime_put(parent);
if (drv)
module_put(drv->owner);
put_device(parent);
put_device(dev);
module_put(dev->driver->owner);
}
/*