From: Leo Yan Date: Fri, 15 May 2026 20:08:15 +0000 (+0100) Subject: coresight: Take a reference on csdev X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=6317302ae25268f53fc292226592a7776b39dffd;p=thirdparty%2Fkernel%2Flinux.git 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 Reviewed-by: James Clark Tested-by: James Clark Tested-by: Jie Gan Signed-off-by: Leo Yan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20260515-arm_coresight_path_power_management_improvement-v14-8-f88c4a3ecfe9@arm.com --- diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 3fc6a5db778c..6b098c3cab0b 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -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 the driver can't be removed */ - if (!try_module_get(dev->driver->owner)) - return false; - /* Make sure the device can't go away */ + /* Make sure csdev can't go away */ get_device(dev); - pm_runtime_get_sync(dev); + + /* Make sure parent device can't go away */ + get_device(parent); + + /* Make sure the driver can't be removed */ + 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); } /*