This series adds the support for CoreSight devices on ACPI based platforms. The device connections are encoded as _DSD graph property[0], with CoreSight specific extensions to indicate the direction of data flow as described in [1]. Components attached to CPUs are listed as child devices of the corresponding CPU, removing explicit links to the CPU like we do in the DT.
The majority of the series cleans up the driver and prepares the subsystem for platform agnostic firwmare probing, naming scheme, searching etc.
We introduce platform independent helpers to parse the platform supplied information. Thus we rename the platform handling code from: of_coresight.c => coresight-platform.c
The CoreSight driver creates shadow devices that appear on the Coresight bus, in addition to the real devices (e.g, AMBA bus devices). The name of these devices match the real device. This makes the device name a bit cryptic for ACPI platform. So this series also introduces a generic platform agnostic device naming scheme for the shadow Coresight devices. Towards this we also make changes to the way we lookup devices to resolve the connections, as we can't use the names to identify the devices. So, we use the "fwnode_handle" of the real device for the device lookups. Towards that we clean up the drivers to keep track of the "CoreSight" device rather than the "real" device. However, all real operations, like DMA allocation, Power management etc. must be performed on the real device which is the parent of the shadow device.
Finally we add the support for parsing the ACPI platform data. The power management support is missing in the ACPI (and this is not specific to CoreSight). The firmware must ensure that the respective power domains are turned on.
The last 3 patches in the series also exposes the device connections via sysfs by symlinks to indicate the trace data paths.
Patches 01 - 05 : General cleanups and a fix. Patches 06 - 13 : Cleanup the drivers for tracking the CoreSight device instead of the parent device. Patches 14 - 20 : Introduce platform agnostic APIs for firmware data probing. Patches 21 - 26 : Prepare for reusing and freeing up the platform data description for device connections and references. Patches 27 - 30 : Use fwnode handles and introduce generic naming scheme. Patches 31 - 33 : Introduce ACPI bindings support Patches 34 - 36 : RFC - expose device connections via sysfs
Applies on Mathieu's coresight/next tree.
Tested on a Juno-r0 board with ACPI bindings patch (Patch 37/36) added on top of [2]. You would need to make sure that the debug power domain is turned on before the Linux kernel boots. (e.g, connect the DS-5 to the Juno board while at UEFI). arm32 code is only compile tested.
[0] ACPI Device Graphs using _DSD (Not available online yet, approved but awaiting publish and eventually should be linked at). https://uefi.org/sites/default/files/resources/_DSD-implementation-guide-top... [1] https://developer.arm.com/docs/den0067/latest/acpi-for-coresighttm-10-platfo... [2] https://github.com/tianocore/edk2-platforms.git
Changes since v1:
[ http://lists.infradead.org/pipermail/linux-arm-kernel/2019-March/639963.html ]
- Dropped the replicator driver merge changes as they were pulled already. - Cleanups for Power management in the drivers. - Reuse platform description for connection information. Also introduce routines to clean up the platform description to make sure we drop the references (fwnode_handle). - Add RFC patches for exposing the device-links via sysfs. - Drop tracking the device in favour of coresight_device. - Name etb10 as "etb" - Fix other comments in v1. - Use a generic helper for searching with fwnode_handle rather than adding one for CoreSight.
Suzuki K Poulose (36): coresight: Fix freeing up the coresight connections coresight: etb10: Cleanup power management coresight: tpiu: Cleanup power management coresight: catu: Cleanup power management coresight: tmc: Cleanup power management coresight: funnel: Clean up device book keeping coresight: replicator: Cleanup device tracking coresight: tmc: Clean up device specific data coresight: catu: Cleanup device specific data coresight: tpiu: Clean up device specific data coresight: stm: Cleanup device specific data coresight: etm: Clean up device specific data coresight: etb10: Clean up device specific data coresight: Rename of_coresight to coresight-platform coresight: etm3x: Rearrange cp14 access detection coresight: stm: Rearrange probing the stimulus area coresight: tmc-etr: Rearrange probing default buffer size coresight: platform: Make memory allocation helper generic coresight: Introduce generic platform data helper coresight: Make device to CPU mapping generic coresight: Remove cpu field from platform data coresight: Remove name from platform description coresight: Cleanup coresight_remove_conns coresight: Reuse platform data structure for connection tracking coresight: Rearrange platform data probing coresight: Add support for releasing platform specific data drivers: Add a generic helper to match device by fwnode handle coresight: platform: Use fwnode handle for device search coresight: Use fwnode handle instead of device names coresight: Use platform agnostic names coresight: stm: ACPI support for parsing stimulus base coresight: Support for ACPI bindings coresight: acpi: Support for components [RFC] coresight: Pass coresight_device for coresight_release_platform_data [RFC] coresight: add return value for fixup connections [RFC] coresight: Expose device connections via sysfs
drivers/acpi/acpi_amba.c | 9 + drivers/base/devcon.c | 5 - drivers/base/property.c | 6 + drivers/hwtracing/coresight/Makefile | 3 +- drivers/hwtracing/coresight/coresight-catu.c | 43 +- drivers/hwtracing/coresight/coresight-catu.h | 1 - drivers/hwtracing/coresight/coresight-cpu-debug.c | 3 +- drivers/hwtracing/coresight/coresight-etb10.c | 65 +- drivers/hwtracing/coresight/coresight-etm.h | 6 +- .../hwtracing/coresight/coresight-etm3x-sysfs.c | 12 +- drivers/hwtracing/coresight/coresight-etm3x.c | 45 +- drivers/hwtracing/coresight/coresight-etm4x.c | 36 +- drivers/hwtracing/coresight/coresight-etm4x.h | 2 - drivers/hwtracing/coresight/coresight-funnel.c | 27 +- drivers/hwtracing/coresight/coresight-platform.c | 740 +++++++++++++++++++++ drivers/hwtracing/coresight/coresight-priv.h | 3 + drivers/hwtracing/coresight/coresight-replicator.c | 37 +- drivers/hwtracing/coresight/coresight-stm.c | 110 ++- drivers/hwtracing/coresight/coresight-tmc-etf.c | 9 +- drivers/hwtracing/coresight/coresight-tmc-etr.c | 44 +- drivers/hwtracing/coresight/coresight-tmc.c | 100 +-- drivers/hwtracing/coresight/coresight-tmc.h | 1 - drivers/hwtracing/coresight/coresight-tpiu.c | 30 +- drivers/hwtracing/coresight/coresight.c | 291 ++++++-- drivers/hwtracing/coresight/of_coresight.c | 297 --------- include/linux/coresight.h | 65 +- include/linux/property.h | 1 + 27 files changed, 1378 insertions(+), 613 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-platform.c delete mode 100644 drivers/hwtracing/coresight/of_coresight.c
ACPI bindings for Juno-r0 (applies on [2] above)
Suzuki K Poulose (1): edk2-platform: juno: Update ACPI CoreSight Bindings
Platform/ARM/JunoPkg/AcpiTables/Dsdt.asl | 241 +++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+)
With commit c2c729415b2d2132 ("coresight: platform: Cleanup coresight connection handling"), we switched to re-using coresight_connections for the coresight_device. However, that introduced a mismatch in the alloc/free of the connections. The allocation is made using devm_*, while we use kfree() to release the memory when a device is released (even though we don't support this at the moment). Fix this by leaving it to the automatic freeing of the memory.
Fixes: c2c729415b2d2132 ("coresight: platform: Cleanup coresight connection handling") Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 29cef89..55204dd 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -973,7 +973,6 @@ static void coresight_device_release(struct device *dev) { struct coresight_device *csdev = to_coresight_device(dev);
- kfree(csdev->conns); kfree(csdev->refcnt); kfree(csdev); }
We drop the power before we complete the probe successfully. We are supposed to drop it only when we are successful. Also, probing the etb_buffer_length happens with the power turned up. So we don't need to do that again in the helper.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-etb10.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 105782e..13c0a60 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -93,17 +93,9 @@ struct etb_drvdata { static int etb_set_buffer(struct coresight_device *csdev, struct perf_output_handle *handle);
-static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata) +static inline unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata) { - u32 depth = 0; - - pm_runtime_get_sync(drvdata->dev); - - /* RO registers don't need locking */ - depth = readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG); - - pm_runtime_put(drvdata->dev); - return depth; + return readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG); }
static void __etb_enable_hw(struct etb_drvdata *drvdata) @@ -720,7 +712,6 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock);
drvdata->buffer_depth = etb_get_buffer_depth(drvdata); - pm_runtime_put(&adev->dev);
if (drvdata->buffer_depth & 0x80000000) return -EINVAL; @@ -747,6 +738,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) if (ret) goto err_misc_register;
+ pm_runtime_put(&adev->dev); return 0;
err_misc_register:
Drop the power only when we have successfully probed. Otherwise leave it to the amba probe to do the rest.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-tpiu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index b2f72a1..4977467 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -153,7 +153,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) /* Disable tpiu to support older devices */ tpiu_disable_hw(drvdata);
- pm_runtime_put(&adev->dev);
desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PORT; @@ -162,7 +161,12 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) desc.dev = dev; drvdata->csdev = coresight_register(&desc);
- return PTR_ERR_OR_ZERO(drvdata->csdev); + if (!IS_ERR(drvdata->csdev)) { + pm_runtime_put(&adev->dev); + return 0; + } + + return PTR_ERR(drvdata->csdev); }
#ifdef CONFIG_PM
Drop the power handle only if we were successful. Otherwise the AMBA bus code would do the rest.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 170fbb6..f2a6a8d 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -557,8 +557,9 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) drvdata->csdev = coresight_register(&catu_desc); if (IS_ERR(drvdata->csdev)) ret = PTR_ERR(drvdata->csdev); + else + pm_runtime_put(&adev->dev); out: - pm_runtime_put(&adev->dev); return ret; }
Drop the power only if we were successful in probing the device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-tmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 647b6aa..c6a5462 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -432,8 +432,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; }
- pm_runtime_put(&adev->dev); - desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_tmc_groups; @@ -476,6 +474,8 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) ret = misc_register(&drvdata->miscdev); if (ret) coresight_unregister(drvdata->csdev); + else + pm_runtime_put(&adev->dev); out: return ret; }
On Mon, 15 Apr 2019 at 10:05, Suzuki K Poulose suzuki.poulose@arm.com wrote:
Drop the power only if we were successful in probing the device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-tmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 647b6aa..c6a5462 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -432,8 +432,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; }
pm_runtime_put(&adev->dev);
desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_tmc_groups;
@@ -476,6 +474,8 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) ret = misc_register(&drvdata->miscdev); if (ret) coresight_unregister(drvdata->csdev);
else
pm_runtime_put(&adev->dev);
out: return ret; }
I have applied patches 1 to 5.
-- 2.7.4
On 04/17/2019 09:03 PM, Mathieu Poirier wrote:
On Mon, 15 Apr 2019 at 10:05, Suzuki K Poulose suzuki.poulose@arm.com wrote:
Drop the power only if we were successful in probing the device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-tmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 647b6aa..c6a5462 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -432,8 +432,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; }
pm_runtime_put(&adev->dev);
desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_tmc_groups;
@@ -476,6 +474,8 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) ret = misc_register(&drvdata->miscdev); if (ret) coresight_unregister(drvdata->csdev);
else
out: return ret; }pm_runtime_put(&adev->dev);
I have applied patches 1 to 5.
Thanks Mathieu !
In preparation to use a consistent device naming scheme, clean up the device link tracking in funnel driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-funnel.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 9279251..1085f31 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -37,7 +37,6 @@ */ struct funnel_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; unsigned long priority; @@ -77,7 +76,7 @@ static int funnel_enable(struct coresight_device *csdev, int inport, rc = funnel_enable_hw(drvdata, inport);
if (!rc) - dev_dbg(drvdata->dev, "FUNNEL inport %d enabled\n", inport); + dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport); return rc; }
@@ -105,7 +104,7 @@ static void funnel_disable(struct coresight_device *csdev, int inport,
funnel_disable_hw(drvdata, inport);
- dev_dbg(drvdata->dev, "FUNNEL inport %d disabled\n", inport); + dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport); }
static const struct coresight_ops_link funnel_link_ops = { @@ -160,11 +159,11 @@ static ssize_t funnel_ctrl_show(struct device *dev, u32 val; struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
- pm_runtime_get_sync(drvdata->dev); + pm_runtime_get_sync(dev->parent);
val = get_funnel_ctrl_hw(drvdata);
- pm_runtime_put(drvdata->dev); + pm_runtime_put(dev->parent);
return sprintf(buf, "%#x\n", val); } @@ -199,7 +198,6 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
On Mon, Apr 15, 2019 at 05:03:49PM +0100, Suzuki K Poulose wrote:
In preparation to use a consistent device naming scheme, clean up the device link tracking in funnel driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-funnel.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 9279251..1085f31 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -37,7 +37,6 @@ */ struct funnel_drvdata { void __iomem *base;
- struct device *dev;
Please remove @dev from the structure documentation.
With that: Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
struct clk *atclk; struct coresight_device *csdev; unsigned long priority; @@ -77,7 +76,7 @@ static int funnel_enable(struct coresight_device *csdev, int inport, rc = funnel_enable_hw(drvdata, inport); if (!rc)
dev_dbg(drvdata->dev, "FUNNEL inport %d enabled\n", inport);
return rc;dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport);
} @@ -105,7 +104,7 @@ static void funnel_disable(struct coresight_device *csdev, int inport, funnel_disable_hw(drvdata, inport);
- dev_dbg(drvdata->dev, "FUNNEL inport %d disabled\n", inport);
- dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport);
} static const struct coresight_ops_link funnel_link_ops = { @@ -160,11 +159,11 @@ static ssize_t funnel_ctrl_show(struct device *dev, u32 val; struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
- pm_runtime_get_sync(drvdata->dev);
- pm_runtime_get_sync(dev->parent);
val = get_funnel_ctrl_hw(drvdata);
- pm_runtime_put(drvdata->dev);
- pm_runtime_put(dev->parent);
return sprintf(buf, "%#x\n", val); } @@ -199,7 +198,6 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
-- 2.7.4
In preparation to use a consistent device naming scheme, clean up the device link tracking in replicator driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-replicator.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 4e0da85..8bbb008 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -26,13 +26,11 @@ * struct replicator_drvdata - specifics associated to a replicator component * @base: memory mapped base address for this component. Also indicates * whether this one is programmable or not. - * @dev: the device entity associated with this component * @atclk: optional clock for the core parts of the replicator. * @csdev: component vitals needed by the framework */ struct replicator_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; }; @@ -100,7 +98,7 @@ static int replicator_enable(struct coresight_device *csdev, int inport, if (drvdata->base) rc = dynamic_replicator_enable(drvdata, inport, outport); if (!rc) - dev_dbg(drvdata->dev, "REPLICATOR enabled\n"); + dev_dbg(&csdev->dev, "REPLICATOR enabled\n"); return rc; }
@@ -139,7 +137,7 @@ static void replicator_disable(struct coresight_device *csdev, int inport,
if (drvdata->base) dynamic_replicator_disable(drvdata, inport, outport); - dev_dbg(drvdata->dev, "REPLICATOR disabled\n"); + dev_dbg(&csdev->dev, "REPLICATOR disabled\n"); }
static const struct coresight_ops_link replicator_link_ops = { @@ -193,7 +191,6 @@ static int replicator_probe(struct device *dev, struct resource *res) if (!drvdata) return -ENOMEM;
- drvdata->dev = dev; drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
On Mon, Apr 15, 2019 at 05:03:50PM +0100, Suzuki K Poulose wrote:
In preparation to use a consistent device naming scheme, clean up the device link tracking in replicator driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-replicator.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 4e0da85..8bbb008 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -26,13 +26,11 @@
- struct replicator_drvdata - specifics associated to a replicator component
- @base: memory mapped base address for this component. Also indicates
whether this one is programmable or not.
*/
- @dev: the device entity associated with this component
- @atclk: optional clock for the core parts of the replicator.
- @csdev: component vitals needed by the framework
struct replicator_drvdata { void __iomem *base;
- struct device *dev; struct clk *atclk; struct coresight_device *csdev;
}; @@ -100,7 +98,7 @@ static int replicator_enable(struct coresight_device *csdev, int inport, if (drvdata->base) rc = dynamic_replicator_enable(drvdata, inport, outport); if (!rc)
dev_dbg(drvdata->dev, "REPLICATOR enabled\n");
return rc;dev_dbg(&csdev->dev, "REPLICATOR enabled\n");
} @@ -139,7 +137,7 @@ static void replicator_disable(struct coresight_device *csdev, int inport, if (drvdata->base) dynamic_replicator_disable(drvdata, inport, outport);
- dev_dbg(drvdata->dev, "REPLICATOR disabled\n");
- dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
} static const struct coresight_ops_link replicator_link_ops = { @@ -193,7 +191,6 @@ static int replicator_probe(struct device *dev, struct resource *res) if (!drvdata) return -ENOMEM;
- drvdata->dev = dev; drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
-- 2.7.4
In preparation to use a consistent device naming scheme, clean up the device link tracking in replicator driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Since the CATU driver also uses the TMC-SG infrastructure, update the callers to ensure they pass the appropriate device argument for the tables.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 5 ++-- drivers/hwtracing/coresight/coresight-tmc-etf.c | 9 +++--- drivers/hwtracing/coresight/coresight-tmc-etr.c | 40 ++++++++++++++----------- drivers/hwtracing/coresight/coresight-tmc.c | 38 +++++++++++------------ drivers/hwtracing/coresight/coresight-tmc.h | 1 - 5 files changed, 47 insertions(+), 46 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index f2a6a8d..ba3c005 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -328,19 +328,18 @@ static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata, struct etr_buf *etr_buf, int node, void **pages) { struct coresight_device *csdev; - struct device *catu_dev; struct tmc_sg_table *catu_table; struct catu_etr_buf *catu_buf;
csdev = tmc_etr_get_catu_device(tmc_drvdata); if (!csdev) return -ENODEV; - catu_dev = csdev->dev.parent; catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL); if (!catu_buf) return -ENOMEM;
- catu_table = catu_init_sg_table(catu_dev, node, etr_buf->size, pages); + catu_table = catu_init_sg_table(&csdev->dev, node, + etr_buf->size, pages); if (IS_ERR(catu_table)) { kfree(catu_buf); return PTR_ERR(catu_table); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index a5f053f..6f60606 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -251,7 +251,6 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode, void *data) { int ret; - struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
switch (mode) { case CS_MODE_SYSFS: @@ -269,7 +268,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, if (ret) return ret;
- dev_dbg(drvdata->dev, "TMC-ETB/ETF enabled\n"); + dev_dbg(&csdev->dev, "TMC-ETB/ETF enabled\n"); return 0; }
@@ -292,7 +291,7 @@ static void tmc_disable_etf_sink(struct coresight_device *csdev)
spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "TMC-ETB/ETF disabled\n"); + dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n"); }
static int tmc_enable_etf_link(struct coresight_device *csdev, @@ -314,7 +313,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, spin_unlock_irqrestore(&drvdata->spinlock, flags);
if (!ret) - dev_dbg(drvdata->dev, "TMC-ETF enabled\n"); + dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); return ret; }
@@ -334,7 +333,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, drvdata->mode = CS_MODE_DISABLED; spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "TMC-ETF disabled\n"); + dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); }
static void *tmc_alloc_etf_buffer(struct coresight_device *csdev, int cpu, diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index f684283..0911f9c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -153,10 +153,11 @@ static void tmc_pages_free(struct tmc_pages *tmc_pages, struct device *dev, enum dma_data_direction dir) { int i; + struct device *real_dev = dev->parent;
for (i = 0; i < tmc_pages->nr_pages; i++) { if (tmc_pages->daddrs && tmc_pages->daddrs[i]) - dma_unmap_page(dev, tmc_pages->daddrs[i], + dma_unmap_page(real_dev, tmc_pages->daddrs[i], PAGE_SIZE, dir); if (tmc_pages->pages && tmc_pages->pages[i]) __free_page(tmc_pages->pages[i]); @@ -184,6 +185,7 @@ static int tmc_pages_alloc(struct tmc_pages *tmc_pages, int i, nr_pages; dma_addr_t paddr; struct page *page; + struct device *real_dev = dev->parent;
nr_pages = tmc_pages->nr_pages; tmc_pages->daddrs = kcalloc(nr_pages, sizeof(*tmc_pages->daddrs), @@ -207,8 +209,8 @@ static int tmc_pages_alloc(struct tmc_pages *tmc_pages, page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0); } - paddr = dma_map_page(dev, page, 0, PAGE_SIZE, dir); - if (dma_mapping_error(dev, paddr)) + paddr = dma_map_page(real_dev, page, 0, PAGE_SIZE, dir); + if (dma_mapping_error(real_dev, paddr)) goto err; tmc_pages->daddrs[i] = paddr; tmc_pages->pages[i] = page; @@ -295,7 +297,7 @@ static int tmc_alloc_data_pages(struct tmc_sg_table *sg_table, void **pages) * and data buffers. TMC writes to the data buffers and reads from the SG * Table pages. * - * @dev - Device to which page should be DMA mapped. + * @dev - Coresight device to which page should be DMA mapped. * @node - Numa node for mem allocations * @nr_tpages - Number of pages for the table entries. * @nr_dpages - Number of pages for Data buffer. @@ -339,13 +341,13 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table, { int i, index, start; int npages = DIV_ROUND_UP(size, PAGE_SIZE); - struct device *dev = table->dev; + struct device *real_dev = table->dev->parent; struct tmc_pages *data = &table->data_pages;
start = offset >> PAGE_SHIFT; for (i = start; i < (start + npages); i++) { index = i % data->nr_pages; - dma_sync_single_for_cpu(dev, data->daddrs[index], + dma_sync_single_for_cpu(real_dev, data->daddrs[index], PAGE_SIZE, DMA_FROM_DEVICE); } } @@ -354,11 +356,11 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table, void tmc_sg_table_sync_table(struct tmc_sg_table *sg_table) { int i; - struct device *dev = sg_table->dev; + struct device *real_dev = sg_table->dev->parent; struct tmc_pages *table_pages = &sg_table->table_pages;
for (i = 0; i < table_pages->nr_pages; i++) - dma_sync_single_for_device(dev, table_pages->daddrs[i], + dma_sync_single_for_device(real_dev, table_pages->daddrs[i], PAGE_SIZE, DMA_TO_DEVICE); }
@@ -581,6 +583,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, void **pages) { struct etr_flat_buf *flat_buf; + struct device *real_dev = drvdata->csdev->dev.parent;
/* We cannot reuse existing pages for flat buf */ if (pages) @@ -590,7 +593,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, if (!flat_buf) return -ENOMEM;
- flat_buf->vaddr = dma_alloc_coherent(drvdata->dev, etr_buf->size, + flat_buf->vaddr = dma_alloc_coherent(real_dev, etr_buf->size, &flat_buf->daddr, GFP_KERNEL); if (!flat_buf->vaddr) { kfree(flat_buf); @@ -598,7 +601,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, }
flat_buf->size = etr_buf->size; - flat_buf->dev = drvdata->dev; + flat_buf->dev = &drvdata->csdev->dev; etr_buf->hwaddr = flat_buf->daddr; etr_buf->mode = ETR_MODE_FLAT; etr_buf->private = flat_buf; @@ -608,9 +611,10 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, static void tmc_etr_free_flat_buf(struct etr_buf *etr_buf) { struct etr_flat_buf *flat_buf = etr_buf->private; + struct device *real_dev = flat_buf->dev->parent;
if (flat_buf && flat_buf->daddr) - dma_free_coherent(flat_buf->dev, flat_buf->size, + dma_free_coherent(real_dev, flat_buf->size, flat_buf->vaddr, flat_buf->daddr); kfree(flat_buf); } @@ -657,8 +661,9 @@ static int tmc_etr_alloc_sg_buf(struct tmc_drvdata *drvdata, void **pages) { struct etr_sg_table *etr_table; + struct device *dev = &drvdata->csdev->dev;
- etr_table = tmc_init_etr_sg_table(drvdata->dev, node, + etr_table = tmc_init_etr_sg_table(dev, node, etr_buf->size, pages); if (IS_ERR(etr_table)) return -ENOMEM; @@ -813,9 +818,10 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, bool has_etr_sg, has_iommu; bool has_sg, has_catu; struct etr_buf *etr_buf; + struct device *dev = &drvdata->csdev->dev;
has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG); - has_iommu = iommu_get_domain_for_dev(drvdata->dev); + has_iommu = iommu_get_domain_for_dev(dev->parent); has_catu = !!tmc_etr_get_catu_device(drvdata);
has_sg = has_catu || has_etr_sg; @@ -853,7 +859,7 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, return ERR_PTR(rc); }
- dev_dbg(drvdata->dev, "allocated buffer of size %ldKB in mode %d\n", + dev_dbg(dev, "allocated buffer of size %ldKB in mode %d\n", (unsigned long)size >> 10, etr_buf->mode); return etr_buf; } @@ -1148,7 +1154,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) tmc_etr_free_sysfs_buf(free_buf);
if (!ret) - dev_dbg(drvdata->dev, "TMC-ETR enabled\n"); + dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
return ret; } @@ -1217,7 +1223,7 @@ static void *tmc_alloc_etr_buffer(struct coresight_device *csdev, etr_perf = tmc_etr_setup_perf_buf(drvdata, cpu_to_node(cpu), nr_pages, pages, snapshot); if (IS_ERR(etr_perf)) { - dev_dbg(drvdata->dev, "Unable to allocate ETR buffer\n"); + dev_dbg(&csdev->dev, "Unable to allocate ETR buffer\n"); return NULL; }
@@ -1411,7 +1417,7 @@ static void tmc_disable_etr_sink(struct coresight_device *csdev)
spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "TMC-ETR disabled\n"); + dev_dbg(&csdev->dev, "TMC-ETR disabled\n"); }
static const struct coresight_ops_sink tmc_etr_sink_ops = { diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index c6a5462..819873a 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -30,7 +30,7 @@ void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata) /* Ensure formatter, unformatter and hardware fifo are empty */ if (coresight_timeout(drvdata->base, TMC_STS, TMC_STS_TMCREADY_BIT, 1)) { - dev_err(drvdata->dev, + dev_err(&drvdata->csdev->dev, "timeout while waiting for TMC to be Ready\n"); } } @@ -47,7 +47,7 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata) /* Ensure flush completes */ if (coresight_timeout(drvdata->base, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) { - dev_err(drvdata->dev, + dev_err(&drvdata->csdev->dev, "timeout while waiting for completion of Manual Flush\n"); }
@@ -81,7 +81,7 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata) }
if (!ret) - dev_dbg(drvdata->dev, "TMC read start\n"); + dev_dbg(&drvdata->csdev->dev, "TMC read start\n");
return ret; } @@ -103,7 +103,7 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata) }
if (!ret) - dev_dbg(drvdata->dev, "TMC read end\n"); + dev_dbg(&drvdata->csdev->dev, "TMC read end\n");
return ret; } @@ -120,7 +120,7 @@ static int tmc_open(struct inode *inode, struct file *file)
nonseekable_open(inode, file);
- dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__); + dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__); return 0; }
@@ -150,12 +150,13 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, return 0;
if (copy_to_user(data, bufp, actual)) { - dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__); + dev_dbg(&drvdata->csdev->dev, + "%s: copy_to_user failed\n", __func__); return -EFAULT; }
*ppos += actual; - dev_dbg(drvdata->dev, "%zu bytes copied\n", actual); + dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
return actual; } @@ -170,7 +171,7 @@ static int tmc_release(struct inode *inode, struct file *file) if (ret) return ret;
- dev_dbg(drvdata->dev, "%s: released\n", __func__); + dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__); return 0; }
@@ -330,24 +331,22 @@ const struct attribute_group *coresight_tmc_groups[] = { NULL, };
-static inline bool tmc_etr_can_use_sg(struct tmc_drvdata *drvdata) +static inline bool tmc_etr_can_use_sg(struct device *dev) { - return fwnode_property_present(drvdata->dev->fwnode, - "arm,scatter-gather"); + return fwnode_property_present(dev->fwnode, "arm,scatter-gather"); }
/* Detect and initialise the capabilities of a TMC ETR */ -static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata, - u32 devid, void *dev_caps) +static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps) { int rc; - u32 dma_mask = 0; + struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
/* Set the unadvertised capabilities */ tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
- if (!(devid & TMC_DEVID_NOSCAT) && tmc_etr_can_use_sg(drvdata)) + if (!(devid & TMC_DEVID_NOSCAT) && tmc_etr_can_use_sg(parent)) tmc_etr_set_cap(drvdata, TMC_ETR_SG);
/* Check if the AXI address width is available */ @@ -365,15 +364,15 @@ static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata, case 44: case 48: case 52: - dev_info(drvdata->dev, "Detected dma mask %dbits\n", dma_mask); + dev_info(parent, "Detected dma mask %dbits\n", dma_mask); break; default: dma_mask = 40; }
- rc = dma_set_mask_and_coherent(drvdata->dev, DMA_BIT_MASK(dma_mask)); + rc = dma_set_mask_and_coherent(parent, DMA_BIT_MASK(dma_mask)); if (rc) - dev_err(drvdata->dev, "Failed to setup DMA mask: %d\n", rc); + dev_err(parent, "Failed to setup DMA mask: %d\n", rc); return rc; }
@@ -403,7 +402,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) goto out;
- drvdata->dev = &adev->dev; dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -446,7 +444,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etr_cs_ops; - ret = tmc_etr_setup_caps(drvdata, devid, + ret = tmc_etr_setup_caps(dev, devid, coresight_get_uci_data(id)); if (ret) goto out; diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 487c537..3eeadcf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -175,7 +175,6 @@ struct etr_buf { */ struct tmc_drvdata { void __iomem *base; - struct device *dev; struct coresight_device *csdev; struct miscdevice miscdev; spinlock_t spinlock;
On Mon, Apr 15, 2019 at 05:03:51PM +0100, Suzuki K Poulose wrote:
In preparation to use a consistent device naming scheme, clean up the device link tracking in replicator driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Since the CATU driver also uses the TMC-SG infrastructure, update the callers to ensure they pass the appropriate device argument for the tables.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-catu.c | 5 ++-- drivers/hwtracing/coresight/coresight-tmc-etf.c | 9 +++--- drivers/hwtracing/coresight/coresight-tmc-etr.c | 40 ++++++++++++++----------- drivers/hwtracing/coresight/coresight-tmc.c | 38 +++++++++++------------ drivers/hwtracing/coresight/coresight-tmc.h | 1 - 5 files changed, 47 insertions(+), 46 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index f2a6a8d..ba3c005 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -328,19 +328,18 @@ static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata, struct etr_buf *etr_buf, int node, void **pages) { struct coresight_device *csdev;
- struct device *catu_dev; struct tmc_sg_table *catu_table; struct catu_etr_buf *catu_buf;
csdev = tmc_etr_get_catu_device(tmc_drvdata); if (!csdev) return -ENODEV;
- catu_dev = csdev->dev.parent; catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL); if (!catu_buf) return -ENOMEM;
- catu_table = catu_init_sg_table(catu_dev, node, etr_buf->size, pages);
- catu_table = catu_init_sg_table(&csdev->dev, node,
if (IS_ERR(catu_table)) { kfree(catu_buf); return PTR_ERR(catu_table);etr_buf->size, pages);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index a5f053f..6f60606 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -251,7 +251,6 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode, void *data) { int ret;
- struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
switch (mode) { case CS_MODE_SYSFS: @@ -269,7 +268,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, if (ret) return ret;
- dev_dbg(drvdata->dev, "TMC-ETB/ETF enabled\n");
- dev_dbg(&csdev->dev, "TMC-ETB/ETF enabled\n"); return 0;
} @@ -292,7 +291,7 @@ static void tmc_disable_etf_sink(struct coresight_device *csdev) spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "TMC-ETB/ETF disabled\n");
- dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
} static int tmc_enable_etf_link(struct coresight_device *csdev, @@ -314,7 +313,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, spin_unlock_irqrestore(&drvdata->spinlock, flags); if (!ret)
dev_dbg(drvdata->dev, "TMC-ETF enabled\n");
return ret;dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
} @@ -334,7 +333,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, drvdata->mode = CS_MODE_DISABLED; spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "TMC-ETF disabled\n");
- dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
} static void *tmc_alloc_etf_buffer(struct coresight_device *csdev, int cpu, diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index f684283..0911f9c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -153,10 +153,11 @@ static void tmc_pages_free(struct tmc_pages *tmc_pages, struct device *dev, enum dma_data_direction dir) { int i;
- struct device *real_dev = dev->parent;
I would have kept the 'dev' as it is quite obvious from the dev->parent that we are getting a reference on the parent. That is just my opinion and it is entirely up to you.
for (i = 0; i < tmc_pages->nr_pages; i++) { if (tmc_pages->daddrs && tmc_pages->daddrs[i])
dma_unmap_page(dev, tmc_pages->daddrs[i],
if (tmc_pages->pages && tmc_pages->pages[i]) __free_page(tmc_pages->pages[i]);dma_unmap_page(real_dev, tmc_pages->daddrs[i], PAGE_SIZE, dir);
@@ -184,6 +185,7 @@ static int tmc_pages_alloc(struct tmc_pages *tmc_pages, int i, nr_pages; dma_addr_t paddr; struct page *page;
- struct device *real_dev = dev->parent;
nr_pages = tmc_pages->nr_pages; tmc_pages->daddrs = kcalloc(nr_pages, sizeof(*tmc_pages->daddrs), @@ -207,8 +209,8 @@ static int tmc_pages_alloc(struct tmc_pages *tmc_pages, page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0); }
paddr = dma_map_page(dev, page, 0, PAGE_SIZE, dir);
if (dma_mapping_error(dev, paddr))
paddr = dma_map_page(real_dev, page, 0, PAGE_SIZE, dir);
tmc_pages->daddrs[i] = paddr; tmc_pages->pages[i] = page;if (dma_mapping_error(real_dev, paddr)) goto err;
@@ -295,7 +297,7 @@ static int tmc_alloc_data_pages(struct tmc_sg_table *sg_table, void **pages)
- and data buffers. TMC writes to the data buffers and reads from the SG
- Table pages.
- @dev - Device to which page should be DMA mapped.
- @dev - Coresight device to which page should be DMA mapped.
- @node - Numa node for mem allocations
- @nr_tpages - Number of pages for the table entries.
- @nr_dpages - Number of pages for Data buffer.
@@ -339,13 +341,13 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table, { int i, index, start; int npages = DIV_ROUND_UP(size, PAGE_SIZE);
- struct device *dev = table->dev;
- struct device *real_dev = table->dev->parent; struct tmc_pages *data = &table->data_pages;
start = offset >> PAGE_SHIFT; for (i = start; i < (start + npages); i++) { index = i % data->nr_pages;
dma_sync_single_for_cpu(dev, data->daddrs[index],
}dma_sync_single_for_cpu(real_dev, data->daddrs[index], PAGE_SIZE, DMA_FROM_DEVICE);
} @@ -354,11 +356,11 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table, void tmc_sg_table_sync_table(struct tmc_sg_table *sg_table) { int i;
- struct device *dev = sg_table->dev;
- struct device *real_dev = sg_table->dev->parent; struct tmc_pages *table_pages = &sg_table->table_pages;
for (i = 0; i < table_pages->nr_pages; i++)
dma_sync_single_for_device(dev, table_pages->daddrs[i],
dma_sync_single_for_device(real_dev, table_pages->daddrs[i], PAGE_SIZE, DMA_TO_DEVICE);
} @@ -581,6 +583,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, void **pages) { struct etr_flat_buf *flat_buf;
- struct device *real_dev = drvdata->csdev->dev.parent;
/* We cannot reuse existing pages for flat buf */ if (pages) @@ -590,7 +593,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, if (!flat_buf) return -ENOMEM;
- flat_buf->vaddr = dma_alloc_coherent(drvdata->dev, etr_buf->size,
- flat_buf->vaddr = dma_alloc_coherent(real_dev, etr_buf->size, &flat_buf->daddr, GFP_KERNEL); if (!flat_buf->vaddr) { kfree(flat_buf);
@@ -598,7 +601,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, } flat_buf->size = etr_buf->size;
- flat_buf->dev = drvdata->dev;
- flat_buf->dev = &drvdata->csdev->dev; etr_buf->hwaddr = flat_buf->daddr; etr_buf->mode = ETR_MODE_FLAT; etr_buf->private = flat_buf;
@@ -608,9 +611,10 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, static void tmc_etr_free_flat_buf(struct etr_buf *etr_buf) { struct etr_flat_buf *flat_buf = etr_buf->private;
- struct device *real_dev = flat_buf->dev->parent;
if (flat_buf && flat_buf->daddr)
dma_free_coherent(flat_buf->dev, flat_buf->size,
kfree(flat_buf);dma_free_coherent(real_dev, flat_buf->size, flat_buf->vaddr, flat_buf->daddr);
} @@ -657,8 +661,9 @@ static int tmc_etr_alloc_sg_buf(struct tmc_drvdata *drvdata, void **pages) { struct etr_sg_table *etr_table;
- struct device *dev = &drvdata->csdev->dev;
- etr_table = tmc_init_etr_sg_table(drvdata->dev, node,
- etr_table = tmc_init_etr_sg_table(dev, node, etr_buf->size, pages); if (IS_ERR(etr_table)) return -ENOMEM;
@@ -813,9 +818,10 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, bool has_etr_sg, has_iommu; bool has_sg, has_catu; struct etr_buf *etr_buf;
- struct device *dev = &drvdata->csdev->dev;
has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG);
- has_iommu = iommu_get_domain_for_dev(drvdata->dev);
- has_iommu = iommu_get_domain_for_dev(dev->parent); has_catu = !!tmc_etr_get_catu_device(drvdata);
has_sg = has_catu || has_etr_sg; @@ -853,7 +859,7 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, return ERR_PTR(rc); }
- dev_dbg(drvdata->dev, "allocated buffer of size %ldKB in mode %d\n",
- dev_dbg(dev, "allocated buffer of size %ldKB in mode %d\n", (unsigned long)size >> 10, etr_buf->mode); return etr_buf;
} @@ -1148,7 +1154,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) tmc_etr_free_sysfs_buf(free_buf); if (!ret)
dev_dbg(drvdata->dev, "TMC-ETR enabled\n");
dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
return ret; } @@ -1217,7 +1223,7 @@ static void *tmc_alloc_etr_buffer(struct coresight_device *csdev, etr_perf = tmc_etr_setup_perf_buf(drvdata, cpu_to_node(cpu), nr_pages, pages, snapshot); if (IS_ERR(etr_perf)) {
dev_dbg(drvdata->dev, "Unable to allocate ETR buffer\n");
return NULL; }dev_dbg(&csdev->dev, "Unable to allocate ETR buffer\n");
@@ -1411,7 +1417,7 @@ static void tmc_disable_etr_sink(struct coresight_device *csdev) spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "TMC-ETR disabled\n");
- dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
} static const struct coresight_ops_sink tmc_etr_sink_ops = { diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index c6a5462..819873a 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -30,7 +30,7 @@ void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata) /* Ensure formatter, unformatter and hardware fifo are empty */ if (coresight_timeout(drvdata->base, TMC_STS, TMC_STS_TMCREADY_BIT, 1)) {
dev_err(drvdata->dev,
}dev_err(&drvdata->csdev->dev, "timeout while waiting for TMC to be Ready\n");
} @@ -47,7 +47,7 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata) /* Ensure flush completes */ if (coresight_timeout(drvdata->base, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) {
dev_err(drvdata->dev,
"timeout while waiting for completion of Manual Flush\n"); }dev_err(&drvdata->csdev->dev,
@@ -81,7 +81,7 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata) } if (!ret)
dev_dbg(drvdata->dev, "TMC read start\n");
dev_dbg(&drvdata->csdev->dev, "TMC read start\n");
return ret; } @@ -103,7 +103,7 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata) } if (!ret)
dev_dbg(drvdata->dev, "TMC read end\n");
dev_dbg(&drvdata->csdev->dev, "TMC read end\n");
return ret; } @@ -120,7 +120,7 @@ static int tmc_open(struct inode *inode, struct file *file) nonseekable_open(inode, file);
- dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__);
- dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__); return 0;
} @@ -150,12 +150,13 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, return 0; if (copy_to_user(data, bufp, actual)) {
dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__);
dev_dbg(&drvdata->csdev->dev,
return -EFAULT; }"%s: copy_to_user failed\n", __func__);
*ppos += actual;
- dev_dbg(drvdata->dev, "%zu bytes copied\n", actual);
- dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
return actual; } @@ -170,7 +171,7 @@ static int tmc_release(struct inode *inode, struct file *file) if (ret) return ret;
- dev_dbg(drvdata->dev, "%s: released\n", __func__);
- dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__); return 0;
} @@ -330,24 +331,22 @@ const struct attribute_group *coresight_tmc_groups[] = { NULL, }; -static inline bool tmc_etr_can_use_sg(struct tmc_drvdata *drvdata) +static inline bool tmc_etr_can_use_sg(struct device *dev) {
- return fwnode_property_present(drvdata->dev->fwnode,
"arm,scatter-gather");
- return fwnode_property_present(dev->fwnode, "arm,scatter-gather");
} /* Detect and initialise the capabilities of a TMC ETR */ -static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata,
u32 devid, void *dev_caps)
+static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps) { int rc;
- u32 dma_mask = 0;
- struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
/* Set the unadvertised capabilities */ tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
- if (!(devid & TMC_DEVID_NOSCAT) && tmc_etr_can_use_sg(drvdata))
- if (!(devid & TMC_DEVID_NOSCAT) && tmc_etr_can_use_sg(parent)) tmc_etr_set_cap(drvdata, TMC_ETR_SG);
/* Check if the AXI address width is available */ @@ -365,15 +364,15 @@ static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata, case 44: case 48: case 52:
dev_info(drvdata->dev, "Detected dma mask %dbits\n", dma_mask);
break; default: dma_mask = 40; }dev_info(parent, "Detected dma mask %dbits\n", dma_mask);
- rc = dma_set_mask_and_coherent(drvdata->dev, DMA_BIT_MASK(dma_mask));
- rc = dma_set_mask_and_coherent(parent, DMA_BIT_MASK(dma_mask)); if (rc)
dev_err(drvdata->dev, "Failed to setup DMA mask: %d\n", rc);
return rc;dev_err(parent, "Failed to setup DMA mask: %d\n", rc);
} @@ -403,7 +402,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) goto out;
- drvdata->dev = &adev->dev; dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -446,7 +444,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etr_cs_ops;
ret = tmc_etr_setup_caps(drvdata, devid,
if (ret) goto out;ret = tmc_etr_setup_caps(dev, devid, coresight_get_uci_data(id));
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 487c537..3eeadcf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -175,7 +175,6 @@ struct etr_buf { */ struct tmc_drvdata { void __iomem *base;
- struct device *dev;
Please clean up the structure documentation.
With that and regardless of what you decide to do about the 'real_dev':
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
struct coresight_device *csdev; struct miscdevice miscdev; spinlock_t spinlock; -- 2.7.4
Hi Mathieu
On 17/04/2019 22:23, Mathieu Poirier wrote:
On Mon, Apr 15, 2019 at 05:03:51PM +0100, Suzuki K Poulose wrote:
In preparation to use a consistent device naming scheme, clean up the device link tracking in replicator driver. Use the "coresight" device instead of the "real" parent device for all internal purposes. All other requests (e.g, power management, DMA operations) must use the "real" device which is the parent device.
Since the CATU driver also uses the TMC-SG infrastructure, update the callers to ensure they pass the appropriate device argument for the tables.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index f684283..0911f9c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -153,10 +153,11 @@ static void tmc_pages_free(struct tmc_pages *tmc_pages, struct device *dev, enum dma_data_direction dir) { int i;
- struct device *real_dev = dev->parent;
I would have kept the 'dev' as it is quite obvious from the dev->parent that we are getting a reference on the parent. That is just my opinion and it is entirely up to you.
"dev" is already an argument to the function. Hence the "real_dev" choice.
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 487c537..3eeadcf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -175,7 +175,6 @@ struct etr_buf { */ struct tmc_drvdata { void __iomem *base;
- struct device *dev;
Please clean up the structure documentation.
With that and regardless of what you decide to do about the 'real_dev':
Done.
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
Cheers Suzuki
Switch to using the CoreSight device instead of the real amba device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 13 +++++++------ drivers/hwtracing/coresight/coresight-catu.h | 1 - 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index ba3c005..14d1cf5 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -408,13 +408,14 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, void *data) int rc; u32 control, mode; struct etr_buf *etr_buf = data; + struct device *dev = &drvdata->csdev->dev;
if (catu_wait_for_ready(drvdata)) - dev_warn(drvdata->dev, "Timeout while waiting for READY\n"); + dev_warn(dev, "Timeout while waiting for READY\n");
control = catu_read_control(drvdata); if (control & BIT(CATU_CONTROL_ENABLE)) { - dev_warn(drvdata->dev, "CATU is already enabled\n"); + dev_warn(dev, "CATU is already enabled\n"); return -EBUSY; }
@@ -440,7 +441,7 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, void *data) catu_write_irqen(drvdata, 0); catu_write_mode(drvdata, mode); catu_write_control(drvdata, control); - dev_dbg(drvdata->dev, "Enabled in %s mode\n", + dev_dbg(dev, "Enabled in %s mode\n", (mode == CATU_MODE_PASS_THROUGH) ? "Pass through" : "Translate"); @@ -461,15 +462,16 @@ static int catu_enable(struct coresight_device *csdev, void *data) static int catu_disable_hw(struct catu_drvdata *drvdata) { int rc = 0; + struct device *dev = &drvdata->csdev->dev;
catu_write_control(drvdata, 0); coresight_disclaim_device_unlocked(drvdata->base); if (catu_wait_for_ready(drvdata)) { - dev_info(drvdata->dev, "Timeout while waiting for READY\n"); + dev_info(dev, "Timeout while waiting for READY\n"); rc = -EAGAIN; }
- dev_dbg(drvdata->dev, "Disabled\n"); + dev_dbg(dev, "Disabled\n"); return rc; }
@@ -519,7 +521,6 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
- drvdata->dev = dev; dev_set_drvdata(dev, drvdata); base = devm_ioremap_resource(dev, &adev->res); if (IS_ERR(base)) { diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h index 1b281f0..96ea8c4 100644 --- a/drivers/hwtracing/coresight/coresight-catu.h +++ b/drivers/hwtracing/coresight/coresight-catu.h @@ -61,7 +61,6 @@ #define CATU_IRQEN_OFF 0x0
struct catu_drvdata { - struct device *dev; void __iomem *base; struct coresight_device *csdev; int irq;
On Mon, Apr 15, 2019 at 05:03:52PM +0100, Suzuki K Poulose wrote:
Switch to using the CoreSight device instead of the real amba device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-catu.c | 13 +++++++------ drivers/hwtracing/coresight/coresight-catu.h | 1 - 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index ba3c005..14d1cf5 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -408,13 +408,14 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, void *data) int rc; u32 control, mode; struct etr_buf *etr_buf = data;
- struct device *dev = &drvdata->csdev->dev;
if (catu_wait_for_ready(drvdata))
dev_warn(drvdata->dev, "Timeout while waiting for READY\n");
dev_warn(dev, "Timeout while waiting for READY\n");
control = catu_read_control(drvdata); if (control & BIT(CATU_CONTROL_ENABLE)) {
dev_warn(drvdata->dev, "CATU is already enabled\n");
return -EBUSY; }dev_warn(dev, "CATU is already enabled\n");
@@ -440,7 +441,7 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, void *data) catu_write_irqen(drvdata, 0); catu_write_mode(drvdata, mode); catu_write_control(drvdata, control);
- dev_dbg(drvdata->dev, "Enabled in %s mode\n",
- dev_dbg(dev, "Enabled in %s mode\n", (mode == CATU_MODE_PASS_THROUGH) ? "Pass through" : "Translate");
@@ -461,15 +462,16 @@ static int catu_enable(struct coresight_device *csdev, void *data) static int catu_disable_hw(struct catu_drvdata *drvdata) { int rc = 0;
- struct device *dev = &drvdata->csdev->dev;
catu_write_control(drvdata, 0); coresight_disclaim_device_unlocked(drvdata->base); if (catu_wait_for_ready(drvdata)) {
dev_info(drvdata->dev, "Timeout while waiting for READY\n");
rc = -EAGAIN; }dev_info(dev, "Timeout while waiting for READY\n");
- dev_dbg(drvdata->dev, "Disabled\n");
- dev_dbg(dev, "Disabled\n"); return rc;
} @@ -519,7 +521,6 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
- drvdata->dev = dev; dev_set_drvdata(dev, drvdata); base = devm_ioremap_resource(dev, &adev->res); if (IS_ERR(base)) {
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h index 1b281f0..96ea8c4 100644 --- a/drivers/hwtracing/coresight/coresight-catu.h +++ b/drivers/hwtracing/coresight/coresight-catu.h @@ -61,7 +61,6 @@ #define CATU_IRQEN_OFF 0x0 struct catu_drvdata {
- struct device *dev; void __iomem *base; struct coresight_device *csdev; int irq;
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
-- 2.7.4
Switch to using the coresight device instead of the parent amba device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-tpiu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 4977467..96af7d5 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -54,7 +54,6 @@ */ struct tpiu_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; }; @@ -74,7 +73,7 @@ static int tpiu_enable(struct coresight_device *csdev, u32 mode, void *__unused)
tpiu_enable_hw(drvdata);
- dev_dbg(drvdata->dev, "TPIU enabled\n"); + dev_dbg(&csdev->dev, "TPIU enabled\n"); return 0; }
@@ -100,7 +99,7 @@ static void tpiu_disable(struct coresight_device *csdev)
tpiu_disable_hw(drvdata);
- dev_dbg(drvdata->dev, "TPIU disabled\n"); + dev_dbg(&csdev->dev, "TPIU disabled\n"); }
static const struct coresight_ops_sink tpiu_sink_ops = { @@ -134,7 +133,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
On Mon, Apr 15, 2019 at 05:03:53PM +0100, Suzuki K Poulose wrote:
Switch to using the coresight device instead of the parent amba device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-tpiu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 4977467..96af7d5 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -54,7 +54,6 @@ */ struct tpiu_drvdata { void __iomem *base;
- struct device *dev;
Please cleanup structure documentation. With that:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
struct clk *atclk; struct coresight_device *csdev; }; @@ -74,7 +73,7 @@ static int tpiu_enable(struct coresight_device *csdev, u32 mode, void *__unused) tpiu_enable_hw(drvdata);
- dev_dbg(drvdata->dev, "TPIU enabled\n");
- dev_dbg(&csdev->dev, "TPIU enabled\n"); return 0;
} @@ -100,7 +99,7 @@ static void tpiu_disable(struct coresight_device *csdev) tpiu_disable_hw(drvdata);
- dev_dbg(drvdata->dev, "TPIU disabled\n");
- dev_dbg(&csdev->dev, "TPIU disabled\n");
} static const struct coresight_ops_sink tpiu_sink_ops = { @@ -134,7 +133,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
-- 2.7.4
Keep track of the STM coresight device which is a child device of the AMBA device. Since we can get to the coresight_device from the "device" instance, remove the explicit field.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-stm.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 9f8a844..8f50484 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -110,7 +110,6 @@ struct channel_space { /** * struct stm_drvdata - specifics associated to an STM component * @base: memory mapped base address for this component. - * @dev: the device entity associated to this component. * @atclk: optional clock for the core parts of the STM. * @csdev: component vitals needed by the framework. * @spinlock: only one at a time pls. @@ -128,7 +127,6 @@ struct channel_space { */ struct stm_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; spinlock_t spinlock; @@ -205,13 +203,13 @@ static int stm_enable(struct coresight_device *csdev, if (val) return -EBUSY;
- pm_runtime_get_sync(drvdata->dev); + pm_runtime_get_sync(csdev->dev.parent);
spin_lock(&drvdata->spinlock); stm_enable_hw(drvdata); spin_unlock(&drvdata->spinlock);
- dev_dbg(drvdata->dev, "STM tracing enabled\n"); + dev_dbg(&csdev->dev, "STM tracing enabled\n"); return 0; }
@@ -271,10 +269,10 @@ static void stm_disable(struct coresight_device *csdev, /* Wait until the engine has completely stopped */ coresight_timeout(drvdata->base, STMTCSR, STMTCSR_BUSY_BIT, 0);
- pm_runtime_put(drvdata->dev); + pm_runtime_put(csdev->dev.parent);
local_set(&drvdata->mode, CS_MODE_DISABLED); - dev_dbg(drvdata->dev, "STM tracing disabled\n"); + dev_dbg(&csdev->dev, "STM tracing disabled\n"); } }
@@ -763,9 +761,10 @@ static void stm_init_default_data(struct stm_drvdata *drvdata) bitmap_clear(drvdata->chs.guaranteed, 0, drvdata->numsp); }
-static void stm_init_generic_data(struct stm_drvdata *drvdata) +static void stm_init_generic_data(struct stm_drvdata *drvdata, + const char *name) { - drvdata->stm.name = dev_name(drvdata->dev); + drvdata->stm.name = name;
/* * MasterIDs are assigned at HW design phase. As such the core is @@ -807,7 +806,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk); @@ -848,7 +846,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock);
stm_init_default_data(drvdata); - stm_init_generic_data(drvdata); + stm_init_generic_data(drvdata, dev_name(dev));
if (stm_register_device(dev, &drvdata->stm, THIS_MODULE)) { dev_info(dev, @@ -870,7 +868,8 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
pm_runtime_put(&adev->dev);
- dev_info(dev, "%s initialized\n", (char *)coresight_get_uci_data(id)); + dev_info(&drvdata->csdev->dev, "%s initialized\n", + (char *)coresight_get_uci_data(id)); return 0;
stm_unregister:
On Mon, Apr 15, 2019 at 05:03:54PM +0100, Suzuki K Poulose wrote:
Keep track of the STM coresight device which is a child device of the AMBA device. Since we can get to the coresight_device from the "device" instance, remove the explicit field.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-stm.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 9f8a844..8f50484 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -110,7 +110,6 @@ struct channel_space { /**
- struct stm_drvdata - specifics associated to an STM component
- @base: memory mapped base address for this component.
- @dev: the device entity associated to this component.
- @atclk: optional clock for the core parts of the STM.
- @csdev: component vitals needed by the framework.
- @spinlock: only one at a time pls.
@@ -128,7 +127,6 @@ struct channel_space { */ struct stm_drvdata { void __iomem *base;
- struct device *dev; struct clk *atclk; struct coresight_device *csdev; spinlock_t spinlock;
@@ -205,13 +203,13 @@ static int stm_enable(struct coresight_device *csdev, if (val) return -EBUSY;
- pm_runtime_get_sync(drvdata->dev);
- pm_runtime_get_sync(csdev->dev.parent);
spin_lock(&drvdata->spinlock); stm_enable_hw(drvdata); spin_unlock(&drvdata->spinlock);
- dev_dbg(drvdata->dev, "STM tracing enabled\n");
- dev_dbg(&csdev->dev, "STM tracing enabled\n"); return 0;
} @@ -271,10 +269,10 @@ static void stm_disable(struct coresight_device *csdev, /* Wait until the engine has completely stopped */ coresight_timeout(drvdata->base, STMTCSR, STMTCSR_BUSY_BIT, 0);
pm_runtime_put(drvdata->dev);
pm_runtime_put(csdev->dev.parent);
local_set(&drvdata->mode, CS_MODE_DISABLED);
dev_dbg(drvdata->dev, "STM tracing disabled\n");
}dev_dbg(&csdev->dev, "STM tracing disabled\n");
} @@ -763,9 +761,10 @@ static void stm_init_default_data(struct stm_drvdata *drvdata) bitmap_clear(drvdata->chs.guaranteed, 0, drvdata->numsp); } -static void stm_init_generic_data(struct stm_drvdata *drvdata) +static void stm_init_generic_data(struct stm_drvdata *drvdata,
const char *name)
{
- drvdata->stm.name = dev_name(drvdata->dev);
- drvdata->stm.name = name;
/* * MasterIDs are assigned at HW design phase. As such the core is @@ -807,7 +806,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
@@ -848,7 +846,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock); stm_init_default_data(drvdata);
- stm_init_generic_data(drvdata);
- stm_init_generic_data(drvdata, dev_name(dev));
if (stm_register_device(dev, &drvdata->stm, THIS_MODULE)) { dev_info(dev, @@ -870,7 +868,8 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) pm_runtime_put(&adev->dev);
- dev_info(dev, "%s initialized\n", (char *)coresight_get_uci_data(id));
- dev_info(&drvdata->csdev->dev, "%s initialized\n",
return 0;(char *)coresight_get_uci_data(id));
stm_unregister:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
-- 2.7.4
Track the coresight device instead of the real device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-etm.h | 6 ++---- .../hwtracing/coresight/coresight-etm3x-sysfs.c | 12 ++++++------ drivers/hwtracing/coresight/coresight-etm3x.c | 22 ++++++++++++---------- drivers/hwtracing/coresight/coresight-etm4x.c | 17 +++++++++-------- drivers/hwtracing/coresight/coresight-etm4x.h | 2 -- 5 files changed, 29 insertions(+), 30 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h index 79e1ad8..f3ab96e 100644 --- a/drivers/hwtracing/coresight/coresight-etm.h +++ b/drivers/hwtracing/coresight/coresight-etm.h @@ -208,7 +208,6 @@ struct etm_config { /** * struct etm_drvdata - specifics associated to an ETM component * @base: memory mapped base address for this component. - * @dev: the device entity associated to this component. * @atclk: optional clock for the core parts of the ETM. * @csdev: component vitals needed by the framework. * @spinlock: only one at a time pls. @@ -232,7 +231,6 @@ struct etm_config { */ struct etm_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; spinlock_t spinlock; @@ -260,7 +258,7 @@ static inline void etm_writel(struct etm_drvdata *drvdata, { if (drvdata->use_cp14) { if (etm_writel_cp14(off, val)) { - dev_err(drvdata->dev, + dev_err(&drvdata->csdev->dev, "invalid CP14 access to ETM reg: %#x", off); } } else { @@ -274,7 +272,7 @@ static inline unsigned int etm_readl(struct etm_drvdata *drvdata, u32 off)
if (drvdata->use_cp14) { if (etm_readl_cp14(off, &val)) { - dev_err(drvdata->dev, + dev_err(&drvdata->csdev->dev, "invalid CP14 access to ETM reg: %#x", off); } } else { diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c index 75487b3..e8c7649 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c @@ -48,7 +48,7 @@ static ssize_t etmsr_show(struct device *dev, unsigned long flags, val; struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- pm_runtime_get_sync(drvdata->dev); + pm_runtime_get_sync(dev->parent); spin_lock_irqsave(&drvdata->spinlock, flags); CS_UNLOCK(drvdata->base);
@@ -56,7 +56,7 @@ static ssize_t etmsr_show(struct device *dev,
CS_LOCK(drvdata->base); spin_unlock_irqrestore(&drvdata->spinlock, flags); - pm_runtime_put(drvdata->dev); + pm_runtime_put(dev->parent);
return sprintf(buf, "%#lx\n", val); } @@ -131,7 +131,7 @@ static ssize_t mode_store(struct device *dev,
if (config->mode & ETM_MODE_STALL) { if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) { - dev_warn(drvdata->dev, "stall mode not supported\n"); + dev_warn(dev, "stall mode not supported\n"); ret = -EINVAL; goto err_unlock; } @@ -141,7 +141,7 @@ static ssize_t mode_store(struct device *dev,
if (config->mode & ETM_MODE_TIMESTAMP) { if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) { - dev_warn(drvdata->dev, "timestamp not supported\n"); + dev_warn(dev, "timestamp not supported\n"); ret = -EINVAL; goto err_unlock; } @@ -945,7 +945,7 @@ static ssize_t seq_curr_state_show(struct device *dev, goto out; }
- pm_runtime_get_sync(drvdata->dev); + pm_runtime_get_sync(dev->parent); spin_lock_irqsave(&drvdata->spinlock, flags);
CS_UNLOCK(drvdata->base); @@ -953,7 +953,7 @@ static ssize_t seq_curr_state_show(struct device *dev, CS_LOCK(drvdata->base);
spin_unlock_irqrestore(&drvdata->spinlock, flags); - pm_runtime_put(drvdata->dev); + pm_runtime_put(dev->parent); out: return sprintf(buf, "%#lx\n", val); } diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index be302ec..9c92491 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -165,7 +165,7 @@ static void etm_set_prog(struct etm_drvdata *drvdata) */ isb(); if (coresight_timeout_etm(drvdata, ETMSR, ETMSR_PROG_BIT, 1)) { - dev_err(drvdata->dev, + dev_err(&drvdata->csdev->dev, "%s: timeout observed when probing at offset %#x\n", __func__, ETMSR); } @@ -184,7 +184,7 @@ static void etm_clr_prog(struct etm_drvdata *drvdata) */ isb(); if (coresight_timeout_etm(drvdata, ETMSR, ETMSR_PROG_BIT, 0)) { - dev_err(drvdata->dev, + dev_err(&drvdata->csdev->dev, "%s: timeout observed when probing at offset %#x\n", __func__, ETMSR); } @@ -425,7 +425,7 @@ static int etm_enable_hw(struct etm_drvdata *drvdata) done: CS_LOCK(drvdata->base);
- dev_dbg(drvdata->dev, "cpu: %d enable smp call done: %d\n", + dev_dbg(&drvdata->csdev->dev, "cpu: %d enable smp call done: %d\n", drvdata->cpu, rc); return rc; } @@ -455,6 +455,7 @@ int etm_get_trace_id(struct etm_drvdata *drvdata) { unsigned long flags; int trace_id = -1; + struct device *etm_dev = drvdata->csdev->dev.parent;
if (!drvdata) goto out; @@ -462,7 +463,7 @@ int etm_get_trace_id(struct etm_drvdata *drvdata) if (!local_read(&drvdata->mode)) return drvdata->traceid;
- pm_runtime_get_sync(drvdata->dev); + pm_runtime_get_sync(etm_dev);
spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -471,7 +472,7 @@ int etm_get_trace_id(struct etm_drvdata *drvdata) CS_LOCK(drvdata->base);
spin_unlock_irqrestore(&drvdata->spinlock, flags); - pm_runtime_put(drvdata->dev); + pm_runtime_put(etm_dev);
out: return trace_id; @@ -526,7 +527,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev) spin_unlock(&drvdata->spinlock);
if (!ret) - dev_dbg(drvdata->dev, "ETM tracing enabled\n"); + dev_dbg(&csdev->dev, "ETM tracing enabled\n"); return ret; }
@@ -581,7 +582,8 @@ static void etm_disable_hw(void *info)
CS_LOCK(drvdata->base);
- dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu); + dev_dbg(&drvdata->csdev->dev, + "cpu: %d disable smp call done\n", drvdata->cpu); }
static void etm_disable_perf(struct coresight_device *csdev) @@ -628,7 +630,7 @@ static void etm_disable_sysfs(struct coresight_device *csdev) spin_unlock(&drvdata->spinlock); cpus_read_unlock();
- dev_dbg(drvdata->dev, "ETM tracing disabled\n"); + dev_dbg(&csdev->dev, "ETM tracing disabled\n"); }
static void etm_disable(struct coresight_device *csdev, @@ -803,7 +805,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) drvdata->use_cp14 = of_property_read_bool(np, "arm,cp14"); }
- drvdata->dev = &adev->dev; dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -871,7 +872,8 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) }
pm_runtime_put(&adev->dev); - dev_info(dev, "%s initialized\n", (char *)coresight_get_uci_data(id)); + dev_info(&drvdata->csdev->dev, + "%s initialized\n", (char *)coresight_get_uci_data(id)); if (boot_enable) { coresight_enable(drvdata->csdev); drvdata->boot_enable = true; diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 08ce37c..75b923f 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -88,6 +88,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) { int i, rc; struct etmv4_config *config = &drvdata->config; + struct device *etm_dev = &drvdata->csdev->dev;
CS_UNLOCK(drvdata->base);
@@ -102,7 +103,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
/* wait for TRCSTATR.IDLE to go up */ if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) - dev_err(drvdata->dev, + dev_err(etm_dev, "timeout while waiting for Idle Trace Status\n");
writel_relaxed(config->pe_sel, drvdata->base + TRCPROCSELR); @@ -181,13 +182,13 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
/* wait for TRCSTATR.IDLE to go back down to '0' */ if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 0)) - dev_err(drvdata->dev, + dev_err(etm_dev, "timeout while waiting for Idle Trace Status\n");
done: CS_LOCK(drvdata->base);
- dev_dbg(drvdata->dev, "cpu: %d enable smp call done: %d\n", + dev_dbg(etm_dev, "cpu: %d enable smp call done: %d\n", drvdata->cpu, rc); return rc; } @@ -292,7 +293,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev) spin_unlock(&drvdata->spinlock);
if (!ret) - dev_dbg(drvdata->dev, "ETM tracing enabled\n"); + dev_dbg(&csdev->dev, "ETM tracing enabled\n"); return ret; }
@@ -353,7 +354,8 @@ static void etm4_disable_hw(void *info)
CS_LOCK(drvdata->base);
- dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu); + dev_dbg(&drvdata->csdev->dev, + "cpu: %d disable smp call done\n", drvdata->cpu); }
static int etm4_disable_perf(struct coresight_device *csdev, @@ -403,7 +405,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev) spin_unlock(&drvdata->spinlock); cpus_read_unlock();
- dev_dbg(drvdata->dev, "ETM tracing disabled\n"); + dev_dbg(&csdev->dev, "ETM tracing disabled\n"); }
static void etm4_disable(struct coresight_device *csdev, @@ -987,7 +989,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) adev->dev.platform_data = pdata; }
- drvdata->dev = &adev->dev; dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -1049,7 +1050,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) }
pm_runtime_put(&adev->dev); - dev_info(dev, "CPU%d: ETM v%d.%d initialized\n", + dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n", drvdata->cpu, drvdata->arch >> 4, drvdata->arch & 0xf);
if (boot_enable) { diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 52786e9..4523f10 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -284,7 +284,6 @@ struct etmv4_config { /** * struct etm4_drvdata - specifics associated to an ETM component * @base: Memory mapped base address for this component. - * @dev: The device entity associated to this component. * @csdev: Component vitals needed by the framework. * @spinlock: Only one at a time pls. * @mode: This tracer's mode, i.e sysFS, Perf or disabled. @@ -340,7 +339,6 @@ struct etmv4_config { */ struct etmv4_drvdata { void __iomem *base; - struct device *dev; struct coresight_device *csdev; spinlock_t spinlock; local_t mode;
Track the coresight device instead of the real device.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-etb10.c | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 13c0a60..6e6e9aa 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -65,7 +65,6 @@ /** * struct etb_drvdata - specifics associated to an ETB component * @base: memory mapped base address for this component. - * @dev: the device entity associated to this component. * @atclk: optional clock for the core parts of the ETB. * @csdev: component vitals needed by the framework. * @miscdev: specifics to handle "/dev/xyz.etb" entry. @@ -78,7 +77,6 @@ */ struct etb_drvdata { void __iomem *base; - struct device *dev; struct clk *atclk; struct coresight_device *csdev; struct miscdevice miscdev; @@ -199,7 +197,6 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data) static int etb_enable(struct coresight_device *csdev, u32 mode, void *data) { int ret; - struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
switch (mode) { case CS_MODE_SYSFS: @@ -216,13 +213,14 @@ static int etb_enable(struct coresight_device *csdev, u32 mode, void *data) if (ret) return ret;
- dev_dbg(drvdata->dev, "ETB enabled\n"); + dev_dbg(&csdev->dev, "ETB enabled\n"); return 0; }
static void __etb_disable_hw(struct etb_drvdata *drvdata) { u32 ffcr; + struct device *dev = &drvdata->csdev->dev;
CS_UNLOCK(drvdata->base);
@@ -235,7 +233,7 @@ static void __etb_disable_hw(struct etb_drvdata *drvdata) writel_relaxed(ffcr, drvdata->base + ETB_FFCR);
if (coresight_timeout(drvdata->base, ETB_FFCR, ETB_FFCR_BIT, 0)) { - dev_err(drvdata->dev, + dev_err(dev, "timeout while waiting for completion of Manual Flush\n"); }
@@ -243,7 +241,7 @@ static void __etb_disable_hw(struct etb_drvdata *drvdata) writel_relaxed(0x0, drvdata->base + ETB_CTL_REG);
if (coresight_timeout(drvdata->base, ETB_FFSR, ETB_FFSR_BIT, 1)) { - dev_err(drvdata->dev, + dev_err(dev, "timeout while waiting for Formatter to Stop\n"); }
@@ -258,6 +256,7 @@ static void etb_dump_hw(struct etb_drvdata *drvdata) u32 read_data, depth; u32 read_ptr, write_ptr; u32 frame_off, frame_endoff; + struct device *dev = &drvdata->csdev->dev;
CS_UNLOCK(drvdata->base);
@@ -267,10 +266,10 @@ static void etb_dump_hw(struct etb_drvdata *drvdata) frame_off = write_ptr % ETB_FRAME_SIZE_WORDS; frame_endoff = ETB_FRAME_SIZE_WORDS - frame_off; if (frame_off) { - dev_err(drvdata->dev, + dev_err(dev, "write_ptr: %lu not aligned to formatter frame size\n", (unsigned long)write_ptr); - dev_err(drvdata->dev, "frameoff: %lu, frame_endoff: %lu\n", + dev_err(dev, "frameoff: %lu, frame_endoff: %lu\n", (unsigned long)frame_off, (unsigned long)frame_endoff); write_ptr += frame_endoff; } @@ -331,7 +330,7 @@ static void etb_disable(struct coresight_device *csdev) } spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "ETB disabled\n"); + dev_dbg(&csdev->dev, "ETB disabled\n"); }
static void *etb_alloc_buffer(struct coresight_device *csdev, int cpu, @@ -418,7 +417,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev, * chance to fix things. */ if (write_ptr % ETB_FRAME_SIZE_WORDS) { - dev_err(drvdata->dev, + dev_err(&csdev->dev, "write_ptr: %lu not aligned to formatter frame size\n", (unsigned long)write_ptr);
@@ -543,7 +542,7 @@ static void etb_dump(struct etb_drvdata *drvdata) } spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_dbg(drvdata->dev, "ETB dumped\n"); + dev_dbg(&drvdata->csdev->dev, "ETB dumped\n"); }
static int etb_open(struct inode *inode, struct file *file) @@ -554,7 +553,7 @@ static int etb_open(struct inode *inode, struct file *file) if (local_cmpxchg(&drvdata->reading, 0, 1)) return -EBUSY;
- dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__); + dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__); return 0; }
@@ -564,6 +563,7 @@ static ssize_t etb_read(struct file *file, char __user *data, u32 depth; struct etb_drvdata *drvdata = container_of(file->private_data, struct etb_drvdata, miscdev); + struct device *dev = &drvdata->csdev->dev;
etb_dump(drvdata);
@@ -572,13 +572,14 @@ static ssize_t etb_read(struct file *file, char __user *data, len = depth * 4 - *ppos;
if (copy_to_user(data, drvdata->buf + *ppos, len)) { - dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__); + dev_dbg(dev, + "%s: copy_to_user failed\n", __func__); return -EFAULT; }
*ppos += len;
- dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n", + dev_dbg(dev, "%s: %zu bytes copied, %d bytes left\n", __func__, len, (int)(depth * 4 - *ppos)); return len; } @@ -589,7 +590,7 @@ static int etb_release(struct inode *inode, struct file *file) struct etb_drvdata, miscdev); local_set(&drvdata->reading, 0);
- dev_dbg(drvdata->dev, "%s: released\n", __func__); + dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__); return 0; }
@@ -693,7 +694,6 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk);
Rename the firmware handling file to a more generic name, in preparation for adding ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/Makefile | 3 +- drivers/hwtracing/coresight/coresight-platform.c | 298 +++++++++++++++++++++++ drivers/hwtracing/coresight/of_coresight.c | 297 ---------------------- 3 files changed, 299 insertions(+), 299 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-platform.c delete mode 100644 drivers/hwtracing/coresight/of_coresight.c
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 3b435aa..3c0ac42 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -2,8 +2,7 @@ # # Makefile for CoreSight drivers. # -obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o -obj-$(CONFIG_OF) += of_coresight.o +obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o coresight-platform.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o \ coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c new file mode 100644 index 0000000..514cc2b --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + */ + +#include <linux/types.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_graph.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/amba/bus.h> +#include <linux/coresight.h> +#include <linux/cpumask.h> +#include <asm/smp_plat.h> + +#ifdef CONFIG_OF +static int of_dev_node_match(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static struct device * +of_coresight_get_endpoint_device(struct device_node *endpoint) +{ + struct device *dev = NULL; + + /* + * If we have a non-configurable replicator, it will be found on the + * platform bus. + */ + dev = bus_find_device(&platform_bus_type, NULL, + endpoint, of_dev_node_match); + if (dev) + return dev; + + /* + * We have a configurable component - circle through the AMBA bus + * looking for the device that matches the endpoint node. + */ + return bus_find_device(&amba_bustype, NULL, + endpoint, of_dev_node_match); +} + +static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) +{ + return of_property_read_bool(ep, "slave-mode"); +} + +static void of_coresight_get_ports_legacy(const struct device_node *node, + int *nr_inport, int *nr_outport) +{ + struct device_node *ep = NULL; + int in = 0, out = 0; + + do { + ep = of_graph_get_next_endpoint(node, ep); + if (!ep) + break; + + if (of_coresight_legacy_ep_is_input(ep)) + in++; + else + out++; + + } while (ep); + + *nr_inport = in; + *nr_outport = out; +} + +static struct device_node *of_coresight_get_port_parent(struct device_node *ep) +{ + struct device_node *parent = of_graph_get_port_parent(ep); + + /* + * Skip one-level up to the real device node, if we + * are using the new bindings. + */ + if (of_node_name_eq(parent, "in-ports") || + of_node_name_eq(parent, "out-ports")) + parent = of_get_next_parent(parent); + + return parent; +} + +static inline struct device_node * +of_coresight_get_input_ports_node(const struct device_node *node) +{ + return of_get_child_by_name(node, "in-ports"); +} + +static inline struct device_node * +of_coresight_get_output_ports_node(const struct device_node *node) +{ + return of_get_child_by_name(node, "out-ports"); +} + +static inline int +of_coresight_count_ports(struct device_node *port_parent) +{ + int i = 0; + struct device_node *ep = NULL; + + while ((ep = of_graph_get_next_endpoint(port_parent, ep))) + i++; + return i; +} + +static void of_coresight_get_ports(const struct device_node *node, + int *nr_inport, int *nr_outport) +{ + struct device_node *input_ports = NULL, *output_ports = NULL; + + input_ports = of_coresight_get_input_ports_node(node); + output_ports = of_coresight_get_output_ports_node(node); + + if (input_ports || output_ports) { + if (input_ports) { + *nr_inport = of_coresight_count_ports(input_ports); + of_node_put(input_ports); + } + if (output_ports) { + *nr_outport = of_coresight_count_ports(output_ports); + of_node_put(output_ports); + } + } else { + /* Fall back to legacy DT bindings parsing */ + of_coresight_get_ports_legacy(node, nr_inport, nr_outport); + } +} + +static int of_coresight_alloc_memory(struct device *dev, + struct coresight_platform_data *pdata) +{ + if (pdata->nr_outport) { + pdata->conns = devm_kzalloc(dev, pdata->nr_outport * + sizeof(*pdata->conns), + GFP_KERNEL); + if (!pdata->conns) + return -ENOMEM; + } + + return 0; +} + +int of_coresight_get_cpu(const struct device_node *node) +{ + int cpu; + struct device_node *dn; + + dn = of_parse_phandle(node, "cpu", 0); + /* Affinity defaults to CPU0 */ + if (!dn) + return 0; + cpu = of_cpu_node_to_id(dn); + of_node_put(dn); + + /* Affinity to CPU0 if no cpu nodes are found */ + return (cpu < 0) ? 0 : cpu; +} +EXPORT_SYMBOL_GPL(of_coresight_get_cpu); + +/* + * of_coresight_parse_endpoint : Parse the given output endpoint @ep + * and fill the connection information in @conn + * + * Parses the local port, remote device name and the remote port. + * + * Returns : + * 1 - If the parsing is successful and a connection record + * was created for an output connection. + * 0 - If the parsing completed without any fatal errors. + * -Errno - Fatal error, abort the scanning. + */ +static int of_coresight_parse_endpoint(struct device *dev, + struct device_node *ep, + struct coresight_connection *conn) +{ + int ret = 0; + struct of_endpoint endpoint, rendpoint; + struct device_node *rparent = NULL; + struct device_node *rep = NULL; + struct device *rdev = NULL; + + do { + /* Parse the local port details */ + if (of_graph_parse_endpoint(ep, &endpoint)) + break; + /* + * Get a handle on the remote endpoint and the device it is + * attached to. + */ + rep = of_graph_get_remote_endpoint(ep); + if (!rep) + break; + rparent = of_coresight_get_port_parent(rep); + if (!rparent) + break; + if (of_graph_parse_endpoint(rep, &rendpoint)) + break; + + /* If the remote device is not available, defer probing */ + rdev = of_coresight_get_endpoint_device(rparent); + if (!rdev) { + ret = -EPROBE_DEFER; + break; + } + + conn->outport = endpoint.port; + conn->child_name = devm_kstrdup(dev, + dev_name(rdev), + GFP_KERNEL); + conn->child_port = rendpoint.port; + /* Connection record updated */ + ret = 1; + } while (0); + + of_node_put(rparent); + of_node_put(rep); + put_device(rdev); + + return ret; +} + +struct coresight_platform_data * +of_get_coresight_platform_data(struct device *dev, + const struct device_node *node) +{ + int ret = 0; + struct coresight_platform_data *pdata; + struct coresight_connection *conn; + struct device_node *ep = NULL; + const struct device_node *parent = NULL; + bool legacy_binding = false; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + /* Use device name as sysfs handle */ + pdata->name = dev_name(dev); + pdata->cpu = of_coresight_get_cpu(node); + + /* Get the number of input and output port for this component */ + of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport); + + /* If there are no output connections, we are done */ + if (!pdata->nr_outport) + return pdata; + + ret = of_coresight_alloc_memory(dev, pdata); + if (ret) + return ERR_PTR(ret); + + parent = of_coresight_get_output_ports_node(node); + /* + * If the DT uses obsoleted bindings, the ports are listed + * under the device and we need to filter out the input + * ports. + */ + if (!parent) { + legacy_binding = true; + parent = node; + dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n"); + } + + conn = pdata->conns; + + /* Iterate through each output port to discover topology */ + while ((ep = of_graph_get_next_endpoint(parent, ep))) { + /* + * Legacy binding mixes input/output ports under the + * same parent. So, skip the input ports if we are dealing + * with legacy binding, as they processed with their + * connected output ports. + */ + if (legacy_binding && of_coresight_legacy_ep_is_input(ep)) + continue; + + ret = of_coresight_parse_endpoint(dev, ep, conn); + switch (ret) { + case 1: + conn++; /* Fall through */ + case 0: + break; + default: + return ERR_PTR(ret); + } + } + + return pdata; +} +EXPORT_SYMBOL_GPL(of_get_coresight_platform_data); +#endif diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c deleted file mode 100644 index 7045930..0000000 --- a/drivers/hwtracing/coresight/of_coresight.c +++ /dev/null @@ -1,297 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2012, The Linux Foundation. All rights reserved. - */ - -#include <linux/types.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/clk.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_graph.h> -#include <linux/of_platform.h> -#include <linux/platform_device.h> -#include <linux/amba/bus.h> -#include <linux/coresight.h> -#include <linux/cpumask.h> -#include <asm/smp_plat.h> - - -static int of_dev_node_match(struct device *dev, void *data) -{ - return dev->of_node == data; -} - -static struct device * -of_coresight_get_endpoint_device(struct device_node *endpoint) -{ - struct device *dev = NULL; - - /* - * If we have a non-configurable replicator, it will be found on the - * platform bus. - */ - dev = bus_find_device(&platform_bus_type, NULL, - endpoint, of_dev_node_match); - if (dev) - return dev; - - /* - * We have a configurable component - circle through the AMBA bus - * looking for the device that matches the endpoint node. - */ - return bus_find_device(&amba_bustype, NULL, - endpoint, of_dev_node_match); -} - -static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) -{ - return of_property_read_bool(ep, "slave-mode"); -} - -static void of_coresight_get_ports_legacy(const struct device_node *node, - int *nr_inport, int *nr_outport) -{ - struct device_node *ep = NULL; - int in = 0, out = 0; - - do { - ep = of_graph_get_next_endpoint(node, ep); - if (!ep) - break; - - if (of_coresight_legacy_ep_is_input(ep)) - in++; - else - out++; - - } while (ep); - - *nr_inport = in; - *nr_outport = out; -} - -static struct device_node *of_coresight_get_port_parent(struct device_node *ep) -{ - struct device_node *parent = of_graph_get_port_parent(ep); - - /* - * Skip one-level up to the real device node, if we - * are using the new bindings. - */ - if (of_node_name_eq(parent, "in-ports") || - of_node_name_eq(parent, "out-ports")) - parent = of_get_next_parent(parent); - - return parent; -} - -static inline struct device_node * -of_coresight_get_input_ports_node(const struct device_node *node) -{ - return of_get_child_by_name(node, "in-ports"); -} - -static inline struct device_node * -of_coresight_get_output_ports_node(const struct device_node *node) -{ - return of_get_child_by_name(node, "out-ports"); -} - -static inline int -of_coresight_count_ports(struct device_node *port_parent) -{ - int i = 0; - struct device_node *ep = NULL; - - while ((ep = of_graph_get_next_endpoint(port_parent, ep))) - i++; - return i; -} - -static void of_coresight_get_ports(const struct device_node *node, - int *nr_inport, int *nr_outport) -{ - struct device_node *input_ports = NULL, *output_ports = NULL; - - input_ports = of_coresight_get_input_ports_node(node); - output_ports = of_coresight_get_output_ports_node(node); - - if (input_ports || output_ports) { - if (input_ports) { - *nr_inport = of_coresight_count_ports(input_ports); - of_node_put(input_ports); - } - if (output_ports) { - *nr_outport = of_coresight_count_ports(output_ports); - of_node_put(output_ports); - } - } else { - /* Fall back to legacy DT bindings parsing */ - of_coresight_get_ports_legacy(node, nr_inport, nr_outport); - } -} - -static int of_coresight_alloc_memory(struct device *dev, - struct coresight_platform_data *pdata) -{ - if (pdata->nr_outport) { - pdata->conns = devm_kzalloc(dev, pdata->nr_outport * - sizeof(*pdata->conns), - GFP_KERNEL); - if (!pdata->conns) - return -ENOMEM; - } - - return 0; -} - -int of_coresight_get_cpu(const struct device_node *node) -{ - int cpu; - struct device_node *dn; - - dn = of_parse_phandle(node, "cpu", 0); - /* Affinity defaults to CPU0 */ - if (!dn) - return 0; - cpu = of_cpu_node_to_id(dn); - of_node_put(dn); - - /* Affinity to CPU0 if no cpu nodes are found */ - return (cpu < 0) ? 0 : cpu; -} -EXPORT_SYMBOL_GPL(of_coresight_get_cpu); - -/* - * of_coresight_parse_endpoint : Parse the given output endpoint @ep - * and fill the connection information in @conn - * - * Parses the local port, remote device name and the remote port. - * - * Returns : - * 1 - If the parsing is successful and a connection record - * was created for an output connection. - * 0 - If the parsing completed without any fatal errors. - * -Errno - Fatal error, abort the scanning. - */ -static int of_coresight_parse_endpoint(struct device *dev, - struct device_node *ep, - struct coresight_connection *conn) -{ - int ret = 0; - struct of_endpoint endpoint, rendpoint; - struct device_node *rparent = NULL; - struct device_node *rep = NULL; - struct device *rdev = NULL; - - do { - /* Parse the local port details */ - if (of_graph_parse_endpoint(ep, &endpoint)) - break; - /* - * Get a handle on the remote endpoint and the device it is - * attached to. - */ - rep = of_graph_get_remote_endpoint(ep); - if (!rep) - break; - rparent = of_coresight_get_port_parent(rep); - if (!rparent) - break; - if (of_graph_parse_endpoint(rep, &rendpoint)) - break; - - /* If the remote device is not available, defer probing */ - rdev = of_coresight_get_endpoint_device(rparent); - if (!rdev) { - ret = -EPROBE_DEFER; - break; - } - - conn->outport = endpoint.port; - conn->child_name = devm_kstrdup(dev, - dev_name(rdev), - GFP_KERNEL); - conn->child_port = rendpoint.port; - /* Connection record updated */ - ret = 1; - } while (0); - - of_node_put(rparent); - of_node_put(rep); - put_device(rdev); - - return ret; -} - -struct coresight_platform_data * -of_get_coresight_platform_data(struct device *dev, - const struct device_node *node) -{ - int ret = 0; - struct coresight_platform_data *pdata; - struct coresight_connection *conn; - struct device_node *ep = NULL; - const struct device_node *parent = NULL; - bool legacy_binding = false; - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - /* Use device name as sysfs handle */ - pdata->name = dev_name(dev); - pdata->cpu = of_coresight_get_cpu(node); - - /* Get the number of input and output port for this component */ - of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport); - - /* If there are no output connections, we are done */ - if (!pdata->nr_outport) - return pdata; - - ret = of_coresight_alloc_memory(dev, pdata); - if (ret) - return ERR_PTR(ret); - - parent = of_coresight_get_output_ports_node(node); - /* - * If the DT uses obsoleted bindings, the ports are listed - * under the device and we need to filter out the input - * ports. - */ - if (!parent) { - legacy_binding = true; - parent = node; - dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n"); - } - - conn = pdata->conns; - - /* Iterate through each output port to discover topology */ - while ((ep = of_graph_get_next_endpoint(parent, ep))) { - /* - * Legacy binding mixes input/output ports under the - * same parent. So, skip the input ports if we are dealing - * with legacy binding, as they processed with their - * connected output ports. - */ - if (legacy_binding && of_coresight_legacy_ep_is_input(ep)) - continue; - - ret = of_coresight_parse_endpoint(dev, ep, conn); - switch (ret) { - case 1: - conn++; /* Fall through */ - case 0: - break; - default: - return ERR_PTR(ret); - } - } - - return pdata; -} -EXPORT_SYMBOL_GPL(of_get_coresight_platform_data);
On Mon, Apr 15, 2019 at 05:03:57PM +0100, Suzuki K Poulose wrote:
Rename the firmware handling file to a more generic name, in preparation for adding ACPI support.
I am in agreement with this patch and also understand why you're doing it. But for someone without context and with this very short changelog, it would certainly be cryptic.
Please enhance the description so that someone without background can have a better understanding of what is going on.
With that:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/Makefile | 3 +- drivers/hwtracing/coresight/coresight-platform.c | 298 +++++++++++++++++++++++ drivers/hwtracing/coresight/of_coresight.c | 297 ---------------------- 3 files changed, 299 insertions(+), 299 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-platform.c delete mode 100644 drivers/hwtracing/coresight/of_coresight.c
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 3b435aa..3c0ac42 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -2,8 +2,7 @@ # # Makefile for CoreSight drivers. # -obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o -obj-$(CONFIG_OF) += of_coresight.o +obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o coresight-platform.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o \ coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c new file mode 100644 index 0000000..514cc2b --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (c) 2012, The Linux Foundation. All rights reserved.
- */
+#include <linux/types.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_graph.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/amba/bus.h> +#include <linux/coresight.h> +#include <linux/cpumask.h> +#include <asm/smp_plat.h>
+#ifdef CONFIG_OF +static int of_dev_node_match(struct device *dev, void *data) +{
- return dev->of_node == data;
+}
+static struct device * +of_coresight_get_endpoint_device(struct device_node *endpoint) +{
- struct device *dev = NULL;
- /*
* If we have a non-configurable replicator, it will be found on the
* platform bus.
*/
- dev = bus_find_device(&platform_bus_type, NULL,
endpoint, of_dev_node_match);
- if (dev)
return dev;
- /*
* We have a configurable component - circle through the AMBA bus
* looking for the device that matches the endpoint node.
*/
- return bus_find_device(&amba_bustype, NULL,
endpoint, of_dev_node_match);
+}
+static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) +{
- return of_property_read_bool(ep, "slave-mode");
+}
+static void of_coresight_get_ports_legacy(const struct device_node *node,
int *nr_inport, int *nr_outport)
+{
- struct device_node *ep = NULL;
- int in = 0, out = 0;
- do {
ep = of_graph_get_next_endpoint(node, ep);
if (!ep)
break;
if (of_coresight_legacy_ep_is_input(ep))
in++;
else
out++;
- } while (ep);
- *nr_inport = in;
- *nr_outport = out;
+}
+static struct device_node *of_coresight_get_port_parent(struct device_node *ep) +{
- struct device_node *parent = of_graph_get_port_parent(ep);
- /*
* Skip one-level up to the real device node, if we
* are using the new bindings.
*/
- if (of_node_name_eq(parent, "in-ports") ||
of_node_name_eq(parent, "out-ports"))
parent = of_get_next_parent(parent);
- return parent;
+}
+static inline struct device_node * +of_coresight_get_input_ports_node(const struct device_node *node) +{
- return of_get_child_by_name(node, "in-ports");
+}
+static inline struct device_node * +of_coresight_get_output_ports_node(const struct device_node *node) +{
- return of_get_child_by_name(node, "out-ports");
+}
+static inline int +of_coresight_count_ports(struct device_node *port_parent) +{
- int i = 0;
- struct device_node *ep = NULL;
- while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
i++;
- return i;
+}
+static void of_coresight_get_ports(const struct device_node *node,
int *nr_inport, int *nr_outport)
+{
- struct device_node *input_ports = NULL, *output_ports = NULL;
- input_ports = of_coresight_get_input_ports_node(node);
- output_ports = of_coresight_get_output_ports_node(node);
- if (input_ports || output_ports) {
if (input_ports) {
*nr_inport = of_coresight_count_ports(input_ports);
of_node_put(input_ports);
}
if (output_ports) {
*nr_outport = of_coresight_count_ports(output_ports);
of_node_put(output_ports);
}
- } else {
/* Fall back to legacy DT bindings parsing */
of_coresight_get_ports_legacy(node, nr_inport, nr_outport);
- }
+}
+static int of_coresight_alloc_memory(struct device *dev,
struct coresight_platform_data *pdata)
+{
- if (pdata->nr_outport) {
pdata->conns = devm_kzalloc(dev, pdata->nr_outport *
sizeof(*pdata->conns),
GFP_KERNEL);
if (!pdata->conns)
return -ENOMEM;
- }
- return 0;
+}
+int of_coresight_get_cpu(const struct device_node *node) +{
- int cpu;
- struct device_node *dn;
- dn = of_parse_phandle(node, "cpu", 0);
- /* Affinity defaults to CPU0 */
- if (!dn)
return 0;
- cpu = of_cpu_node_to_id(dn);
- of_node_put(dn);
- /* Affinity to CPU0 if no cpu nodes are found */
- return (cpu < 0) ? 0 : cpu;
+} +EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
+/*
- of_coresight_parse_endpoint : Parse the given output endpoint @ep
- and fill the connection information in @conn
- Parses the local port, remote device name and the remote port.
- Returns :
1 - If the parsing is successful and a connection record
was created for an output connection.
0 - If the parsing completed without any fatal errors.
- -Errno - Fatal error, abort the scanning.
- */
+static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *ep,
struct coresight_connection *conn)
+{
- int ret = 0;
- struct of_endpoint endpoint, rendpoint;
- struct device_node *rparent = NULL;
- struct device_node *rep = NULL;
- struct device *rdev = NULL;
- do {
/* Parse the local port details */
if (of_graph_parse_endpoint(ep, &endpoint))
break;
/*
* Get a handle on the remote endpoint and the device it is
* attached to.
*/
rep = of_graph_get_remote_endpoint(ep);
if (!rep)
break;
rparent = of_coresight_get_port_parent(rep);
if (!rparent)
break;
if (of_graph_parse_endpoint(rep, &rendpoint))
break;
/* If the remote device is not available, defer probing */
rdev = of_coresight_get_endpoint_device(rparent);
if (!rdev) {
ret = -EPROBE_DEFER;
break;
}
conn->outport = endpoint.port;
conn->child_name = devm_kstrdup(dev,
dev_name(rdev),
GFP_KERNEL);
conn->child_port = rendpoint.port;
/* Connection record updated */
ret = 1;
- } while (0);
- of_node_put(rparent);
- of_node_put(rep);
- put_device(rdev);
- return ret;
+}
+struct coresight_platform_data * +of_get_coresight_platform_data(struct device *dev,
const struct device_node *node)
+{
- int ret = 0;
- struct coresight_platform_data *pdata;
- struct coresight_connection *conn;
- struct device_node *ep = NULL;
- const struct device_node *parent = NULL;
- bool legacy_binding = false;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */
- pdata->name = dev_name(dev);
- pdata->cpu = of_coresight_get_cpu(node);
- /* Get the number of input and output port for this component */
- of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
- /* If there are no output connections, we are done */
- if (!pdata->nr_outport)
return pdata;
- ret = of_coresight_alloc_memory(dev, pdata);
- if (ret)
return ERR_PTR(ret);
- parent = of_coresight_get_output_ports_node(node);
- /*
* If the DT uses obsoleted bindings, the ports are listed
* under the device and we need to filter out the input
* ports.
*/
- if (!parent) {
legacy_binding = true;
parent = node;
dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
- }
- conn = pdata->conns;
- /* Iterate through each output port to discover topology */
- while ((ep = of_graph_get_next_endpoint(parent, ep))) {
/*
* Legacy binding mixes input/output ports under the
* same parent. So, skip the input ports if we are dealing
* with legacy binding, as they processed with their
* connected output ports.
*/
if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
continue;
ret = of_coresight_parse_endpoint(dev, ep, conn);
switch (ret) {
case 1:
conn++; /* Fall through */
case 0:
break;
default:
return ERR_PTR(ret);
}
- }
- return pdata;
+} +EXPORT_SYMBOL_GPL(of_get_coresight_platform_data); +#endif diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c deleted file mode 100644 index 7045930..0000000 --- a/drivers/hwtracing/coresight/of_coresight.c +++ /dev/null @@ -1,297 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/*
- Copyright (c) 2012, The Linux Foundation. All rights reserved.
- */
-#include <linux/types.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/clk.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_graph.h> -#include <linux/of_platform.h> -#include <linux/platform_device.h> -#include <linux/amba/bus.h> -#include <linux/coresight.h> -#include <linux/cpumask.h> -#include <asm/smp_plat.h>
-static int of_dev_node_match(struct device *dev, void *data) -{
- return dev->of_node == data;
-}
-static struct device * -of_coresight_get_endpoint_device(struct device_node *endpoint) -{
- struct device *dev = NULL;
- /*
* If we have a non-configurable replicator, it will be found on the
* platform bus.
*/
- dev = bus_find_device(&platform_bus_type, NULL,
endpoint, of_dev_node_match);
- if (dev)
return dev;
- /*
* We have a configurable component - circle through the AMBA bus
* looking for the device that matches the endpoint node.
*/
- return bus_find_device(&amba_bustype, NULL,
endpoint, of_dev_node_match);
-}
-static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) -{
- return of_property_read_bool(ep, "slave-mode");
-}
-static void of_coresight_get_ports_legacy(const struct device_node *node,
int *nr_inport, int *nr_outport)
-{
- struct device_node *ep = NULL;
- int in = 0, out = 0;
- do {
ep = of_graph_get_next_endpoint(node, ep);
if (!ep)
break;
if (of_coresight_legacy_ep_is_input(ep))
in++;
else
out++;
- } while (ep);
- *nr_inport = in;
- *nr_outport = out;
-}
-static struct device_node *of_coresight_get_port_parent(struct device_node *ep) -{
- struct device_node *parent = of_graph_get_port_parent(ep);
- /*
* Skip one-level up to the real device node, if we
* are using the new bindings.
*/
- if (of_node_name_eq(parent, "in-ports") ||
of_node_name_eq(parent, "out-ports"))
parent = of_get_next_parent(parent);
- return parent;
-}
-static inline struct device_node * -of_coresight_get_input_ports_node(const struct device_node *node) -{
- return of_get_child_by_name(node, "in-ports");
-}
-static inline struct device_node * -of_coresight_get_output_ports_node(const struct device_node *node) -{
- return of_get_child_by_name(node, "out-ports");
-}
-static inline int -of_coresight_count_ports(struct device_node *port_parent) -{
- int i = 0;
- struct device_node *ep = NULL;
- while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
i++;
- return i;
-}
-static void of_coresight_get_ports(const struct device_node *node,
int *nr_inport, int *nr_outport)
-{
- struct device_node *input_ports = NULL, *output_ports = NULL;
- input_ports = of_coresight_get_input_ports_node(node);
- output_ports = of_coresight_get_output_ports_node(node);
- if (input_ports || output_ports) {
if (input_ports) {
*nr_inport = of_coresight_count_ports(input_ports);
of_node_put(input_ports);
}
if (output_ports) {
*nr_outport = of_coresight_count_ports(output_ports);
of_node_put(output_ports);
}
- } else {
/* Fall back to legacy DT bindings parsing */
of_coresight_get_ports_legacy(node, nr_inport, nr_outport);
- }
-}
-static int of_coresight_alloc_memory(struct device *dev,
struct coresight_platform_data *pdata)
-{
- if (pdata->nr_outport) {
pdata->conns = devm_kzalloc(dev, pdata->nr_outport *
sizeof(*pdata->conns),
GFP_KERNEL);
if (!pdata->conns)
return -ENOMEM;
- }
- return 0;
-}
-int of_coresight_get_cpu(const struct device_node *node) -{
- int cpu;
- struct device_node *dn;
- dn = of_parse_phandle(node, "cpu", 0);
- /* Affinity defaults to CPU0 */
- if (!dn)
return 0;
- cpu = of_cpu_node_to_id(dn);
- of_node_put(dn);
- /* Affinity to CPU0 if no cpu nodes are found */
- return (cpu < 0) ? 0 : cpu;
-} -EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
-/*
- of_coresight_parse_endpoint : Parse the given output endpoint @ep
- and fill the connection information in @conn
- Parses the local port, remote device name and the remote port.
- Returns :
1 - If the parsing is successful and a connection record
was created for an output connection.
0 - If the parsing completed without any fatal errors.
- -Errno - Fatal error, abort the scanning.
- */
-static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *ep,
struct coresight_connection *conn)
-{
- int ret = 0;
- struct of_endpoint endpoint, rendpoint;
- struct device_node *rparent = NULL;
- struct device_node *rep = NULL;
- struct device *rdev = NULL;
- do {
/* Parse the local port details */
if (of_graph_parse_endpoint(ep, &endpoint))
break;
/*
* Get a handle on the remote endpoint and the device it is
* attached to.
*/
rep = of_graph_get_remote_endpoint(ep);
if (!rep)
break;
rparent = of_coresight_get_port_parent(rep);
if (!rparent)
break;
if (of_graph_parse_endpoint(rep, &rendpoint))
break;
/* If the remote device is not available, defer probing */
rdev = of_coresight_get_endpoint_device(rparent);
if (!rdev) {
ret = -EPROBE_DEFER;
break;
}
conn->outport = endpoint.port;
conn->child_name = devm_kstrdup(dev,
dev_name(rdev),
GFP_KERNEL);
conn->child_port = rendpoint.port;
/* Connection record updated */
ret = 1;
- } while (0);
- of_node_put(rparent);
- of_node_put(rep);
- put_device(rdev);
- return ret;
-}
-struct coresight_platform_data * -of_get_coresight_platform_data(struct device *dev,
const struct device_node *node)
-{
- int ret = 0;
- struct coresight_platform_data *pdata;
- struct coresight_connection *conn;
- struct device_node *ep = NULL;
- const struct device_node *parent = NULL;
- bool legacy_binding = false;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */
- pdata->name = dev_name(dev);
- pdata->cpu = of_coresight_get_cpu(node);
- /* Get the number of input and output port for this component */
- of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
- /* If there are no output connections, we are done */
- if (!pdata->nr_outport)
return pdata;
- ret = of_coresight_alloc_memory(dev, pdata);
- if (ret)
return ERR_PTR(ret);
- parent = of_coresight_get_output_ports_node(node);
- /*
* If the DT uses obsoleted bindings, the ports are listed
* under the device and we need to filter out the input
* ports.
*/
- if (!parent) {
legacy_binding = true;
parent = node;
dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
- }
- conn = pdata->conns;
- /* Iterate through each output port to discover topology */
- while ((ep = of_graph_get_next_endpoint(parent, ep))) {
/*
* Legacy binding mixes input/output ports under the
* same parent. So, skip the input ports if we are dealing
* with legacy binding, as they processed with their
* connected output ports.
*/
if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
continue;
ret = of_coresight_parse_endpoint(dev, ep, conn);
switch (ret) {
case 1:
conn++; /* Fall through */
case 0:
break;
default:
return ERR_PTR(ret);
}
- }
- return pdata;
-}
-EXPORT_SYMBOL_GPL(of_get_coresight_platform_data);
2.7.4
As we are about to refactor the platform specific handling, move the DT property handling to generic helpers.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-etm3x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 9c92491..fa2f141 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -802,9 +802,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(pdata);
adev->dev.platform_data = pdata; - drvdata->use_cp14 = of_property_read_bool(np, "arm,cp14"); }
+ drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
As we are about to refactor the platform specific handling re-arrange some of the DT specific property handling.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-stm.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 8f50484..a0690be 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -683,14 +683,15 @@ static const struct attribute_group *coresight_stm_groups[] = { NULL, };
-static int stm_get_resource_byname(struct device_node *np, - char *ch_base, struct resource *res) +#ifdef CONFIG_OF +static int of_stm_get_stimulus_area(struct device *dev, struct resource *res) { const char *name = NULL; int index = 0, found = 0; + struct device_node *np = dev->of_node;
while (!of_property_read_string_index(np, "reg-names", index, &name)) { - if (strcmp(ch_base, name)) { + if (strcmp("stm-stimulus-base", name)) { index++; continue; } @@ -705,6 +706,20 @@ static int stm_get_resource_byname(struct device_node *np,
return of_address_to_resource(np, index, res); } +#else +static inline int of_stm_get_stimulus_area(struct device *dev, + struct resource *res) +{ + return -ENOENT; +} +#endif + +static int stm_get_stimulus_area(struct device *dev, struct resource *res) +{ + if (dev->of_node) + return of_stm_get_stimulus_area(dev, res); + return -ENOENT; +}
static u32 stm_fundamental_data_size(struct stm_drvdata *drvdata) { @@ -819,7 +834,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(base); drvdata->base = base;
- ret = stm_get_resource_byname(np, "stm-stimulus-base", &ch_res); + ret = stm_get_stimulus_area(dev, &ch_res); if (ret) return ret; drvdata->chs.phys = ch_res.start;
As we are about to refactor the platform specific handling, make the default buffer size probing generic.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-tmc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 819873a..c470b81 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -376,6 +376,15 @@ static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps) return rc; }
+static u32 tmc_etr_get_default_buffer_size(struct device *dev) +{ + u32 size; + + if (fwnode_property_read_u32(dev->fwnode, "arm,buffer-size", &size)) + size = SZ_1M; + return size; +} + static int tmc_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; @@ -419,16 +428,10 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->config_type = BMVAL(devid, 6, 7); drvdata->memwidth = tmc_get_memwidth(devid);
- if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { - if (np) - ret = of_property_read_u32(np, - "arm,buffer-size", - &drvdata->size); - if (ret) - drvdata->size = SZ_1M; - } else { + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) + drvdata->size = tmc_etr_get_default_buffer_size(dev); + else drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; - }
desc.pdata = pdata; desc.dev = dev;
Rename the of_coresight_alloc_memory() => coresight_alloc_conns() as it is independent of the underlying firmware type. This is in preparation for the ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 514cc2b..4c31299 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -17,6 +17,24 @@ #include <linux/cpumask.h> #include <asm/smp_plat.h>
+/* + * coresight_alloc_conns: Allocate connections record for each output + * port from the device. + */ +static int coresight_alloc_conns(struct device *dev, + struct coresight_platform_data *pdata) +{ + if (pdata->nr_outport) { + pdata->conns = devm_kzalloc(dev, pdata->nr_outport * + sizeof(*pdata->conns), + GFP_KERNEL); + if (!pdata->conns) + return -ENOMEM; + } + + return 0; +} + #ifdef CONFIG_OF static int of_dev_node_match(struct device *dev, void *data) { @@ -133,20 +151,6 @@ static void of_coresight_get_ports(const struct device_node *node, } }
-static int of_coresight_alloc_memory(struct device *dev, - struct coresight_platform_data *pdata) -{ - if (pdata->nr_outport) { - pdata->conns = devm_kzalloc(dev, pdata->nr_outport * - sizeof(*pdata->conns), - GFP_KERNEL); - if (!pdata->conns) - return -ENOMEM; - } - - return 0; -} - int of_coresight_get_cpu(const struct device_node *node) { int cpu; @@ -252,7 +256,7 @@ of_get_coresight_platform_data(struct device *dev, if (!pdata->nr_outport) return pdata;
- ret = of_coresight_alloc_memory(dev, pdata); + ret = coresight_alloc_conns(dev, pdata); if (ret) return ERR_PTR(ret);
So far we have hard coded the DT platform parsing code in every driver. Introduce generic helper to parse the information provided by the firmware in a platform agnostic manner, in preparation for the ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 13 +++----- drivers/hwtracing/coresight/coresight-etb10.c | 11 +++---- drivers/hwtracing/coresight/coresight-etm3x.c | 12 +++----- drivers/hwtracing/coresight/coresight-etm4x.c | 11 +++---- drivers/hwtracing/coresight/coresight-funnel.c | 11 +++---- drivers/hwtracing/coresight/coresight-platform.c | 36 ++++++++++++++++------ drivers/hwtracing/coresight/coresight-replicator.c | 12 +++----- drivers/hwtracing/coresight/coresight-stm.c | 11 +++---- drivers/hwtracing/coresight/coresight-tmc.c | 13 +++----- drivers/hwtracing/coresight/coresight-tpiu.c | 11 +++---- include/linux/coresight.h | 7 ++--- 11 files changed, 66 insertions(+), 82 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 14d1cf5..65b86ec 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -503,17 +503,14 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_desc catu_desc; struct coresight_platform_data *pdata = NULL; struct device *dev = &adev->dev; - struct device_node *np = dev->of_node; void __iomem *base;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) { - ret = PTR_ERR(pdata); - goto out; - } - dev->platform_data = pdata; + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out; } + dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 6e6e9aa..cd61b54 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -681,14 +681,11 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct etb_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index fa2f141..fa2164f 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -790,20 +790,16 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) struct etm_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - - adev->dev.platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata);
+ adev->dev.platform_data = pdata; drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 75b923f..998b9f3 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -976,18 +976,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) struct etmv4_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata;
dev_set_drvdata(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 1085f31..2590744 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -185,14 +185,11 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct funnel_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 4c31299..25a1838 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -230,23 +230,17 @@ static int of_coresight_parse_endpoint(struct device *dev, return ret; }
-struct coresight_platform_data * +static struct coresight_platform_data * of_get_coresight_platform_data(struct device *dev, - const struct device_node *node) + struct coresight_platform_data *pdata) { int ret = 0; - struct coresight_platform_data *pdata; struct coresight_connection *conn; struct device_node *ep = NULL; const struct device_node *parent = NULL; bool legacy_binding = false; + struct device_node *node = dev->of_node;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - /* Use device name as sysfs handle */ - pdata->name = dev_name(dev); pdata->cpu = of_coresight_get_cpu(node);
/* Get the number of input and output port for this component */ @@ -298,5 +292,27 @@ of_get_coresight_platform_data(struct device *dev,
return pdata; } -EXPORT_SYMBOL_GPL(of_get_coresight_platform_data); #endif + +struct coresight_platform_data * +coresight_get_platform_data(struct device *dev) +{ + struct coresight_platform_data *pdata; + struct fwnode_handle *fwnode = dev_fwnode(dev); + + if (IS_ERR_OR_NULL(fwnode)) + return NULL; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + /* Use device name as sysfs handle */ + pdata->name = dev_name(dev); + + if (is_of_node(fwnode)) + return of_get_coresight_platform_data(dev, pdata); + + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL_GPL(coresight_get_platform_data); diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 8bbb008..7eb3bf7 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -177,15 +177,12 @@ static int replicator_probe(struct device *dev, struct resource *res) struct coresight_platform_data *pdata = NULL; struct replicator_drvdata *drvdata; struct coresight_desc desc = { 0 }; - struct device_node *np = dev->of_node; void __iomem *base;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - dev->platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) @@ -213,7 +210,6 @@ static int replicator_probe(struct device *dev, struct resource *res) }
dev_set_drvdata(dev, drvdata); - desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; desc.ops = &replicator_cs_ops; diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index a0690be..eae0094 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -809,14 +809,11 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) struct resource ch_res; size_t bitmap_size; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index c470b81..7dbdf59 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -395,16 +395,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct tmc_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) { - ret = PTR_ERR(pdata); - goto out; - } - adev->dev.platform_data = pdata; + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out; } + adev->dev.platform_data = pdata;
ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 96af7d5..eea7fd1 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -120,14 +120,11 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) struct tpiu_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node;
- if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 7b87965..5b29255 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -293,14 +293,11 @@ static inline void coresight_disclaim_device_unlocked(void __iomem *base) {}
#ifdef CONFIG_OF extern int of_coresight_get_cpu(const struct device_node *node); -extern struct coresight_platform_data * -of_get_coresight_platform_data(struct device *dev, - const struct device_node *node); #else static inline int of_coresight_get_cpu(const struct device_node *node) { return 0; } -static inline struct coresight_platform_data *of_get_coresight_platform_data( - struct device *dev, const struct device_node *node) { return NULL; } #endif
+struct coresight_platform_data *coresight_get_platform_data(struct device *dev); + #endif
Hi Suzuki,
On Mon, Apr 15, 2019 at 05:04:02PM +0100, Suzuki K Poulose wrote:
So far we have hard coded the DT platform parsing code in every driver. Introduce generic helper to parse the information provided by the firmware in a platform agnostic manner, in preparation for the ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-catu.c | 13 +++----- drivers/hwtracing/coresight/coresight-etb10.c | 11 +++---- drivers/hwtracing/coresight/coresight-etm3x.c | 12 +++----- drivers/hwtracing/coresight/coresight-etm4x.c | 11 +++---- drivers/hwtracing/coresight/coresight-funnel.c | 11 +++---- drivers/hwtracing/coresight/coresight-platform.c | 36 ++++++++++++++++------ drivers/hwtracing/coresight/coresight-replicator.c | 12 +++----- drivers/hwtracing/coresight/coresight-stm.c | 11 +++---- drivers/hwtracing/coresight/coresight-tmc.c | 13 +++----- drivers/hwtracing/coresight/coresight-tpiu.c | 11 +++---- include/linux/coresight.h | 7 ++--- 11 files changed, 66 insertions(+), 82 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 14d1cf5..65b86ec 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -503,17 +503,14 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_desc catu_desc; struct coresight_platform_data *pdata = NULL; struct device *dev = &adev->dev;
- struct device_node *np = dev->of_node; void __iomem *base;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
}
dev->platform_data = pdata;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
}goto out;
- dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 6e6e9aa..cd61b54 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -681,14 +681,11 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct etb_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index fa2f141..fa2164f 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -790,20 +790,16 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) struct etm_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata; drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 75b923f..998b9f3 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -976,18 +976,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) struct etmv4_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
dev_set_drvdata(dev, drvdata); diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 1085f31..2590744 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -185,14 +185,11 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct funnel_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 4c31299..25a1838 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -230,23 +230,17 @@ static int of_coresight_parse_endpoint(struct device *dev, return ret; } -struct coresight_platform_data * +static struct coresight_platform_data * of_get_coresight_platform_data(struct device *dev,
const struct device_node *node)
struct coresight_platform_data *pdata)
{ int ret = 0;
- struct coresight_platform_data *pdata; struct coresight_connection *conn; struct device_node *ep = NULL; const struct device_node *parent = NULL; bool legacy_binding = false;
- struct device_node *node = dev->of_node;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */
- pdata->name = dev_name(dev); pdata->cpu = of_coresight_get_cpu(node);
/* Get the number of input and output port for this component */ @@ -298,5 +292,27 @@ of_get_coresight_platform_data(struct device *dev, return pdata; } -EXPORT_SYMBOL_GPL(of_get_coresight_platform_data); #endif
+struct coresight_platform_data * +coresight_get_platform_data(struct device *dev) +{
- struct coresight_platform_data *pdata;
- struct fwnode_handle *fwnode = dev_fwnode(dev);
- if (IS_ERR_OR_NULL(fwnode))
return NULL;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */
- pdata->name = dev_name(dev);
- if (is_of_node(fwnode))
return of_get_coresight_platform_data(dev, pdata);
Now that I'm looking a patch 26, returning a coresight_platform_data pointer is a little weird here. Function of_get_coresight_platform_data() simply fills in the pdata and should probably be returning an error code rather than a pointer. If of_get_coresight_platform_data() returns 0 then pdata is returned.
Mathieu
- return ERR_PTR(-ENOENT);
+} +EXPORT_SYMBOL_GPL(coresight_get_platform_data); diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 8bbb008..7eb3bf7 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -177,15 +177,12 @@ static int replicator_probe(struct device *dev, struct resource *res) struct coresight_platform_data *pdata = NULL; struct replicator_drvdata *drvdata; struct coresight_desc desc = { 0 };
- struct device_node *np = dev->of_node; void __iomem *base;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
dev->platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) @@ -213,7 +210,6 @@ static int replicator_probe(struct device *dev, struct resource *res) } dev_set_drvdata(dev, drvdata);
- desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; desc.ops = &replicator_cs_ops;
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index a0690be..eae0094 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -809,14 +809,11 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) struct resource ch_res; size_t bitmap_size; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index c470b81..7dbdf59 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -395,16 +395,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct tmc_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
}
adev->dev.platform_data = pdata;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
}goto out;
- adev->dev.platform_data = pdata;
ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 96af7d5..eea7fd1 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -120,14 +120,11 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) struct tpiu_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 7b87965..5b29255 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -293,14 +293,11 @@ static inline void coresight_disclaim_device_unlocked(void __iomem *base) {} #ifdef CONFIG_OF extern int of_coresight_get_cpu(const struct device_node *node); -extern struct coresight_platform_data * -of_get_coresight_platform_data(struct device *dev,
const struct device_node *node);
#else static inline int of_coresight_get_cpu(const struct device_node *node) { return 0; } -static inline struct coresight_platform_data *of_get_coresight_platform_data(
- struct device *dev, const struct device_node *node) { return NULL; }
#endif +struct coresight_platform_data *coresight_get_platform_data(struct device *dev);
#endif
2.7.4
On 04/22/2019 07:09 PM, Mathieu Poirier wrote:
Hi Suzuki,
On Mon, Apr 15, 2019 at 05:04:02PM +0100, Suzuki K Poulose wrote:
So far we have hard coded the DT platform parsing code in every driver. Introduce generic helper to parse the information provided by the firmware in a platform agnostic manner, in preparation for the ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-catu.c | 13 +++----- drivers/hwtracing/coresight/coresight-etb10.c | 11 +++---- drivers/hwtracing/coresight/coresight-etm3x.c | 12 +++----- drivers/hwtracing/coresight/coresight-etm4x.c | 11 +++---- drivers/hwtracing/coresight/coresight-funnel.c | 11 +++---- drivers/hwtracing/coresight/coresight-platform.c | 36 ++++++++++++++++------ drivers/hwtracing/coresight/coresight-replicator.c | 12 +++----- drivers/hwtracing/coresight/coresight-stm.c | 11 +++---- drivers/hwtracing/coresight/coresight-tmc.c | 13 +++----- drivers/hwtracing/coresight/coresight-tpiu.c | 11 +++---- include/linux/coresight.h | 7 ++--- 11 files changed, 66 insertions(+), 82 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 14d1cf5..65b86ec 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -503,17 +503,14 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_desc catu_desc; struct coresight_platform_data *pdata = NULL; struct device *dev = &adev->dev;
- struct device_node *np = dev->of_node; void __iomem *base;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
}
dev->platform_data = pdata;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
}goto out;
- dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 6e6e9aa..cd61b54 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -681,14 +681,11 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct etb_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index fa2f141..fa2164f 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -790,20 +790,16 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) struct etm_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata; drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 75b923f..998b9f3 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -976,18 +976,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) struct etmv4_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
dev_set_drvdata(dev, drvdata); diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 1085f31..2590744 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -185,14 +185,11 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct funnel_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct device_node *np = adev->dev.of_node;
- if (np) {
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
- }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 4c31299..25a1838 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -230,23 +230,17 @@ static int of_coresight_parse_endpoint(struct device *dev, return ret; } -struct coresight_platform_data * +static struct coresight_platform_data * of_get_coresight_platform_data(struct device *dev,
const struct device_node *node)
{ int ret = 0;struct coresight_platform_data *pdata)
- struct coresight_platform_data *pdata; struct coresight_connection *conn; struct device_node *ep = NULL; const struct device_node *parent = NULL; bool legacy_binding = false;
- struct device_node *node = dev->of_node;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */
- pdata->name = dev_name(dev); pdata->cpu = of_coresight_get_cpu(node);
/* Get the number of input and output port for this component */ @@ -298,5 +292,27 @@ of_get_coresight_platform_data(struct device *dev, return pdata; } -EXPORT_SYMBOL_GPL(of_get_coresight_platform_data); #endif
+struct coresight_platform_data * +coresight_get_platform_data(struct device *dev) +{
- struct coresight_platform_data *pdata;
- struct fwnode_handle *fwnode = dev_fwnode(dev);
- if (IS_ERR_OR_NULL(fwnode))
return NULL;
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */
- pdata->name = dev_name(dev);
- if (is_of_node(fwnode))
return of_get_coresight_platform_data(dev, pdata);
Now that I'm looking a patch 26, returning a coresight_platform_data pointer is a little weird here. Function of_get_coresight_platform_data() simply fills in the pdata and should probably be returning an error code rather than a pointer. If of_get_coresight_platform_data() returns 0 then pdata is returned.s,
Yes, that makes sense. I will fix it.
Cheers Suzuki
The CoreSight components ETM and CPU-Debug are always associated with CPUs. Replace the of_coresight_get_cpu() with a platform agnostic helper, in preparation to add ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-cpu-debug.c | 3 +-- drivers/hwtracing/coresight/coresight-platform.c | 18 +++++++++++++----- include/linux/coresight.h | 7 +------ 3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index e8819d7..07a1367 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -572,14 +572,13 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id) struct device *dev = &adev->dev; struct debug_drvdata *drvdata; struct resource *res = &adev->res; - struct device_node *np = adev->dev.of_node; int ret;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- drvdata->cpu = np ? of_coresight_get_cpu(np) : 0; + drvdata->cpu = coresight_get_cpu(dev); if (per_cpu(debug_drvdata, drvdata->cpu)) { dev_err(dev, "CPU%d drvdata has already been initialized\n", drvdata->cpu); diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 25a1838..8a86ba3 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -151,12 +151,14 @@ static void of_coresight_get_ports(const struct device_node *node, } }
-int of_coresight_get_cpu(const struct device_node *node) +static int of_coresight_get_cpu(struct device *dev) { int cpu; struct device_node *dn;
- dn = of_parse_phandle(node, "cpu", 0); + if (!dev->of_node) + return 0; + dn = of_parse_phandle(dev->of_node, "cpu", 0); /* Affinity defaults to CPU0 */ if (!dn) return 0; @@ -166,7 +168,6 @@ int of_coresight_get_cpu(const struct device_node *node) /* Affinity to CPU0 if no cpu nodes are found */ return (cpu < 0) ? 0 : cpu; } -EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
/* * of_coresight_parse_endpoint : Parse the given output endpoint @ep @@ -241,8 +242,6 @@ of_get_coresight_platform_data(struct device *dev, bool legacy_binding = false; struct device_node *node = dev->of_node;
- pdata->cpu = of_coresight_get_cpu(node); - /* Get the number of input and output port for this component */ of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
@@ -294,6 +293,14 @@ of_get_coresight_platform_data(struct device *dev, } #endif
+int coresight_get_cpu(struct device *dev) +{ + if (is_of_node(dev->fwnode)) + return of_coresight_get_cpu(dev); + return 0; +} +EXPORT_SYMBOL_GPL(coresight_get_cpu); + struct coresight_platform_data * coresight_get_platform_data(struct device *dev) { @@ -309,6 +316,7 @@ coresight_get_platform_data(struct device *dev)
/* Use device name as sysfs handle */ pdata->name = dev_name(dev); + pdata->cpu = coresight_get_cpu(dev);
if (is_of_node(fwnode)) return of_get_coresight_platform_data(dev, pdata); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 5b29255..a48cd9b 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -291,12 +291,7 @@ static inline void coresight_disclaim_device_unlocked(void __iomem *base) {}
#endif
-#ifdef CONFIG_OF -extern int of_coresight_get_cpu(const struct device_node *node); -#else -static inline int of_coresight_get_cpu(const struct device_node *node) -{ return 0; } -#endif +extern int coresight_get_cpu(struct device *dev);
struct coresight_platform_data *coresight_get_platform_data(struct device *dev);
On Mon, Apr 15, 2019 at 05:04:03PM +0100, Suzuki K Poulose wrote:
The CoreSight components ETM and CPU-Debug are always associated with CPUs. Replace the of_coresight_get_cpu() with a platform agnostic helper, in preparation to add ACPI support.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-cpu-debug.c | 3 +-- drivers/hwtracing/coresight/coresight-platform.c | 18 +++++++++++++----- include/linux/coresight.h | 7 +------ 3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index e8819d7..07a1367 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -572,14 +572,13 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id) struct device *dev = &adev->dev; struct debug_drvdata *drvdata; struct resource *res = &adev->res;
- struct device_node *np = adev->dev.of_node; int ret;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- drvdata->cpu = np ? of_coresight_get_cpu(np) : 0;
- drvdata->cpu = coresight_get_cpu(dev); if (per_cpu(debug_drvdata, drvdata->cpu)) { dev_err(dev, "CPU%d drvdata has already been initialized\n", drvdata->cpu);
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 25a1838..8a86ba3 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -151,12 +151,14 @@ static void of_coresight_get_ports(const struct device_node *node, } } -int of_coresight_get_cpu(const struct device_node *node) +static int of_coresight_get_cpu(struct device *dev) { int cpu; struct device_node *dn;
- dn = of_parse_phandle(node, "cpu", 0);
- if (!dev->of_node)
return 0;
- dn = of_parse_phandle(dev->of_node, "cpu", 0); /* Affinity defaults to CPU0 */ if (!dn) return 0;
@@ -166,7 +168,6 @@ int of_coresight_get_cpu(const struct device_node *node) /* Affinity to CPU0 if no cpu nodes are found */ return (cpu < 0) ? 0 : cpu; } -EXPORT_SYMBOL_GPL(of_coresight_get_cpu); /*
- of_coresight_parse_endpoint : Parse the given output endpoint @ep
@@ -241,8 +242,6 @@ of_get_coresight_platform_data(struct device *dev, bool legacy_binding = false; struct device_node *node = dev->of_node;
- pdata->cpu = of_coresight_get_cpu(node);
- /* Get the number of input and output port for this component */ of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
@@ -294,6 +293,14 @@ of_get_coresight_platform_data(struct device *dev, } #endif +int coresight_get_cpu(struct device *dev) +{
- if (is_of_node(dev->fwnode))
return of_coresight_get_cpu(dev);
- return 0;
+} +EXPORT_SYMBOL_GPL(coresight_get_cpu);
struct coresight_platform_data * coresight_get_platform_data(struct device *dev) { @@ -309,6 +316,7 @@ coresight_get_platform_data(struct device *dev) /* Use device name as sysfs handle */ pdata->name = dev_name(dev);
- pdata->cpu = coresight_get_cpu(dev);
if (is_of_node(fwnode)) return of_get_coresight_platform_data(dev, pdata); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 5b29255..a48cd9b 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -291,12 +291,7 @@ static inline void coresight_disclaim_device_unlocked(void __iomem *base) {} #endif -#ifdef CONFIG_OF -extern int of_coresight_get_cpu(const struct device_node *node); -#else -static inline int of_coresight_get_cpu(const struct device_node *node) -{ return 0; } -#endif +extern int coresight_get_cpu(struct device *dev); struct coresight_platform_data *coresight_get_platform_data(struct device *dev);
For patches 12, 13 and 15-20:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
2.7.4
CPU field is only used by ETMs and there is a separate API for fetching the same. So, let us use that instead of using the common platform probing helper. Also, remove it from the platform_data.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-etm3x.c | 2 +- drivers/hwtracing/coresight/coresight-etm4x.c | 2 +- drivers/hwtracing/coresight/coresight-platform.c | 1 - include/linux/coresight.h | 2 -- 4 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index fa2164f..722fab96 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -819,7 +819,7 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) return ret; }
- drvdata->cpu = pdata ? pdata->cpu : 0; + drvdata->cpu = coresight_get_cpu(dev);
cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 998b9f3..ced31d1 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -997,7 +997,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&drvdata->spinlock);
- drvdata->cpu = pdata ? pdata->cpu : 0; + drvdata->cpu = coresight_get_cpu(dev);
cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 8a86ba3..f1ab1b5 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -316,7 +316,6 @@ coresight_get_platform_data(struct device *dev)
/* Use device name as sysfs handle */ pdata->name = dev_name(dev); - pdata->cpu = coresight_get_cpu(dev);
if (is_of_node(fwnode)) return of_get_coresight_platform_data(dev, pdata); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index a48cd9b..bb7548f 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -91,14 +91,12 @@ union coresight_dev_subtype {
/** * struct coresight_platform_data - data harvested from the DT specification - * @cpu: the CPU a source belongs to. Only applicable for ETM/PTMs. * @name: name of the component as shown under sysfs. * @nr_inport: number of input ports for this component. * @nr_outport: number of output ports for this component. * @conns: Array of nr_outport connections from this component */ struct coresight_platform_data { - int cpu; const char *name; int nr_inport; int nr_outport;
We are about to use a name independent of the parent AMBA device name. As such, there is no need to have it in the platform description. Let us move this to coresight description instead.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 2 ++ drivers/hwtracing/coresight/coresight-etb10.c | 3 ++- drivers/hwtracing/coresight/coresight-etm3x.c | 1 + drivers/hwtracing/coresight/coresight-etm4x.c | 1 + drivers/hwtracing/coresight/coresight-funnel.c | 1 + drivers/hwtracing/coresight/coresight-platform.c | 3 --- drivers/hwtracing/coresight/coresight-replicator.c | 2 ++ drivers/hwtracing/coresight/coresight-stm.c | 1 + drivers/hwtracing/coresight/coresight-tmc.c | 5 +++-- drivers/hwtracing/coresight/coresight-tpiu.c | 1 + drivers/hwtracing/coresight/coresight.c | 2 +- include/linux/coresight.h | 8 ++++---- 12 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 65b86ec..03f5b95 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -551,6 +551,8 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) catu_desc.type = CORESIGHT_DEV_TYPE_HELPER; catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU; catu_desc.ops = &catu_ops; + catu_desc.name = dev_name(dev); + drvdata->csdev = coresight_register(&catu_desc); if (IS_ERR(drvdata->csdev)) ret = PTR_ERR(drvdata->csdev); diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index cd61b54..91a5d7a 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -723,12 +723,13 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &etb_cs_ops; desc.pdata = pdata; desc.dev = dev; + desc.name = dev_name(dev); desc.groups = coresight_etb_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev);
- drvdata->miscdev.name = pdata->name; + drvdata->miscdev.name = desc.name; drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; drvdata->miscdev.fops = &etb_fops; ret = misc_register(&drvdata->miscdev); diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 722fab96..101fb01 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -854,6 +854,7 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &etm_cs_ops; desc.pdata = pdata; desc.dev = dev; + desc.name = dev_name(dev); desc.groups = coresight_etm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index ced31d1..7ff0989 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -1034,6 +1034,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_etmv4_groups; + desc.name = dev_name(dev); drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 2590744..61a9e01 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -216,6 +216,7 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &funnel_cs_ops; desc.pdata = pdata; desc.dev = dev; + desc.name = dev_name(dev); desc.groups = coresight_funnel_groups; drvdata->csdev = coresight_register(&desc);
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index f1ab1b5..0415fff 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -314,9 +314,6 @@ coresight_get_platform_data(struct device *dev) if (!pdata) return ERR_PTR(-ENOMEM);
- /* Use device name as sysfs handle */ - pdata->name = dev_name(dev); - if (is_of_node(fwnode)) return of_get_coresight_platform_data(dev, pdata);
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 7eb3bf7..939f20d 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -215,6 +215,8 @@ static int replicator_probe(struct device *dev, struct resource *res) desc.ops = &replicator_cs_ops; desc.pdata = dev->platform_data; desc.dev = dev; + desc.name = dev_name(dev); + drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index eae0094..734227f 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -871,6 +871,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &stm_cs_ops; desc.pdata = pdata; desc.dev = dev; + desc.name = dev_name(dev); desc.groups = coresight_stm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 7dbdf59..02c5cb5 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -433,6 +433,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_tmc_groups; + desc.name = dev_name(dev);
switch (drvdata->config_type) { case TMC_CONFIG_TYPE_ETB: @@ -455,7 +456,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &tmc_etf_cs_ops; break; default: - pr_err("%s: Unsupported TMC config\n", pdata->name); + pr_err("%s: Unsupported TMC config\n", desc.name); ret = -EINVAL; goto out; } @@ -466,7 +467,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
- drvdata->miscdev.name = pdata->name; + drvdata->miscdev.name = desc.name; drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; drvdata->miscdev.fops = &tmc_fops; ret = misc_register(&drvdata->miscdev); diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index eea7fd1..792f1d6 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -154,6 +154,7 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &tpiu_cs_ops; desc.pdata = pdata; desc.dev = dev; + desc.name = dev_name(dev); drvdata->csdev = coresight_register(&desc);
if (!IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 55204dd..91c63cd 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1197,7 +1197,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) csdev->dev.parent = desc->dev; csdev->dev.release = coresight_device_release; csdev->dev.bus = &coresight_bustype; - dev_set_name(&csdev->dev, "%s", desc->pdata->name); + dev_set_name(&csdev->dev, "%s", desc->name);
ret = device_register(&csdev->dev); if (ret) { diff --git a/include/linux/coresight.h b/include/linux/coresight.h index bb7548f..84a2137 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -91,13 +91,11 @@ union coresight_dev_subtype {
/** * struct coresight_platform_data - data harvested from the DT specification - * @name: name of the component as shown under sysfs. * @nr_inport: number of input ports for this component. * @nr_outport: number of output ports for this component. * @conns: Array of nr_outport connections from this component */ struct coresight_platform_data { - const char *name; int nr_inport; int nr_outport; struct coresight_connection *conns; @@ -108,11 +106,12 @@ struct coresight_platform_data { * @type: as defined by @coresight_dev_type. * @subtype: as defined by @coresight_dev_subtype. * @ops: generic operations for this component, as defined - by @coresight_ops. + * by @coresight_ops. * @pdata: platform data collected from DT. * @dev: The device entity associated to this component. * @groups: operations specific to this component. These will end up - in the component's sysfs sub-directory. + * in the component's sysfs sub-directory. + * @name: name for the coresight device, also shown under sysfs. */ struct coresight_desc { enum coresight_dev_type type; @@ -121,6 +120,7 @@ struct coresight_desc { struct coresight_platform_data *pdata; struct device *dev; const struct attribute_group **groups; + const char *name; };
/**
When a device is unregistered, we remove all connection references to it, by searching the connection records of all devices in the coresight bus, via coresight_remove_conns. We could avoid searching if this device doesn't have an input port (e.g, a source). Also document the purpose of the function.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 91c63cd..530ad69 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1094,10 +1094,21 @@ static int coresight_remove_match(struct device *dev, void *data) return 0; }
+/* + * coresight_remove_conns - Remove references to this given devices + * from the connections of other devices. + */ static void coresight_remove_conns(struct coresight_device *csdev) { - bus_for_each_dev(&coresight_bustype, NULL, - csdev, coresight_remove_match); + /* + * Another device will point to this device only if there is + * an output port connected to this one. i.e, if the device + * doesn't have at least one input port, there is no point + * in searching all the devices. + */ + if (csdev->nr_inport) + bus_for_each_dev(&coresight_bustype, NULL, + csdev, coresight_remove_match); }
/**
The platform specific information describes the connections and the ports of a given coresigh device. This information is also recorded in the coresight device as separate fields. Let us reuse the original platform description to streamline the handling of the data.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-tmc-etr.c | 4 +-- drivers/hwtracing/coresight/coresight.c | 46 ++++++++++++------------- include/linux/coresight.h | 8 ++--- 3 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 0911f9c..d3ff2c7 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -747,8 +747,8 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) if (!IS_ENABLED(CONFIG_CORESIGHT_CATU)) return NULL;
- for (i = 0; i < etr->nr_outport; i++) { - tmp = etr->conns[i].child_dev; + for (i = 0; i < etr->pdata->nr_outport; i++) { + tmp = etr->pdata->conns[i].child_dev; if (tmp && coresight_is_catu_device(tmp)) return tmp; } diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 530ad69..f6c5244 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -100,8 +100,8 @@ static int coresight_find_link_inport(struct coresight_device *csdev, int i; struct coresight_connection *conn;
- for (i = 0; i < parent->nr_outport; i++) { - conn = &parent->conns[i]; + for (i = 0; i < parent->pdata->nr_outport; i++) { + conn = &parent->pdata->conns[i]; if (conn->child_dev == csdev) return conn->child_port; } @@ -118,8 +118,8 @@ static int coresight_find_link_outport(struct coresight_device *csdev, int i; struct coresight_connection *conn;
- for (i = 0; i < csdev->nr_outport; i++) { - conn = &csdev->conns[i]; + for (i = 0; i < csdev->pdata->nr_outport; i++) { + conn = &csdev->pdata->conns[i]; if (conn->child_dev == child) return conn->outport; } @@ -304,10 +304,10 @@ static void coresight_disable_link(struct coresight_device *csdev,
if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { refport = inport; - nr_conns = csdev->nr_inport; + nr_conns = csdev->pdata->nr_inport; } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { refport = outport; - nr_conns = csdev->nr_outport; + nr_conns = csdev->pdata->nr_outport; } else { refport = 0; nr_conns = 1; @@ -593,9 +593,10 @@ static void coresight_grab_device(struct coresight_device *csdev) { int i;
- for (i = 0; i < csdev->nr_outport; i++) { - struct coresight_device *child = csdev->conns[i].child_dev; + for (i = 0; i < csdev->pdata->nr_outport; i++) { + struct coresight_device *child;
+ child = csdev->pdata->conns[i].child_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) pm_runtime_get_sync(child->dev.parent); } @@ -611,9 +612,10 @@ static void coresight_drop_device(struct coresight_device *csdev) int i;
pm_runtime_put(csdev->dev.parent); - for (i = 0; i < csdev->nr_outport; i++) { - struct coresight_device *child = csdev->conns[i].child_dev; + for (i = 0; i < csdev->pdata->nr_outport; i++) { + struct coresight_device *child;
+ child = csdev->pdata->conns[i].child_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) pm_runtime_put(child->dev.parent); } @@ -643,9 +645,10 @@ static int _coresight_build_path(struct coresight_device *csdev, goto out;
/* Not a sink - recursively explore each port found on this element */ - for (i = 0; i < csdev->nr_outport; i++) { - struct coresight_device *child_dev = csdev->conns[i].child_dev; + for (i = 0; i < csdev->pdata->nr_outport; i++) { + struct coresight_device *child_dev;
+ child_dev = csdev->pdata->conns[i].child_dev; if (child_dev && _coresight_build_path(child_dev, sink, path) == 0) { found = true; @@ -998,8 +1001,8 @@ static int coresight_orphan_match(struct device *dev, void *data) * Circle throuch all the connection of that component. If we find * an orphan connection whose name matches @csdev, link it. */ - for (i = 0; i < i_csdev->nr_outport; i++) { - conn = &i_csdev->conns[i]; + for (i = 0; i < i_csdev->pdata->nr_outport; i++) { + conn = &i_csdev->pdata->conns[i];
/* We have found at least one orphan connection */ if (conn->child_dev == NULL) { @@ -1038,8 +1041,8 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev) { int i;
- for (i = 0; i < csdev->nr_outport; i++) { - struct coresight_connection *conn = &csdev->conns[i]; + for (i = 0; i < csdev->pdata->nr_outport; i++) { + struct coresight_connection *conn = &csdev->pdata->conns[i]; struct device *dev = NULL;
if (conn->child_name) @@ -1073,8 +1076,8 @@ static int coresight_remove_match(struct device *dev, void *data) * Circle throuch all the connection of that component. If we find * a connection whose name matches @csdev, remove it. */ - for (i = 0; i < iterator->nr_outport; i++) { - conn = &iterator->conns[i]; + for (i = 0; i < iterator->pdata->nr_outport; i++) { + conn = &iterator->pdata->conns[i];
if (conn->child_dev == NULL) continue; @@ -1106,7 +1109,7 @@ static void coresight_remove_conns(struct coresight_device *csdev) * doesn't have at least one input port, there is no point * in searching all the devices. */ - if (csdev->nr_inport) + if (csdev->pdata->nr_inport) bus_for_each_dev(&coresight_bustype, NULL, csdev, coresight_remove_match); } @@ -1193,10 +1196,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
csdev->refcnt = refcnts;
- csdev->nr_inport = desc->pdata->nr_inport; - csdev->nr_outport = desc->pdata->nr_outport; - - csdev->conns = desc->pdata->conns; + csdev->pdata = desc->pdata;
csdev->type = desc->type; csdev->subtype = desc->subtype; diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 84a2137..8c10def 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -140,9 +140,7 @@ struct coresight_connection {
/** * struct coresight_device - representation of a device as used by the framework - * @conns: array of coresight_connections associated to this component. - * @nr_inport: number of input port associated to this component. - * @nr_outport: number of output port associated to this component. + * @pdata: Platform data with device connections associated to this device. * @type: as defined by @coresight_dev_type. * @subtype: as defined by @coresight_dev_subtype. * @ops: generic operations for this component, as defined @@ -157,9 +155,7 @@ struct coresight_connection { * @ea: Device attribute for sink representation under PMU directory. */ struct coresight_device { - struct coresight_connection *conns; - int nr_inport; - int nr_outport; + struct coresight_platform_data *pdata; enum coresight_dev_type type; union coresight_dev_subtype subtype; const struct coresight_ops *ops;
On Mon, Apr 15, 2019 at 05:04:07PM +0100, Suzuki K Poulose wrote:
The platform specific information describes the connections and the ports of a given coresigh device. This information is also recorded in the coresight device as separate fields. Let us reuse the original platform description to streamline the handling of the data.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-tmc-etr.c | 4 +-- drivers/hwtracing/coresight/coresight.c | 46 ++++++++++++------------- include/linux/coresight.h | 8 ++--- 3 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 0911f9c..d3ff2c7 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -747,8 +747,8 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) if (!IS_ENABLED(CONFIG_CORESIGHT_CATU)) return NULL;
- for (i = 0; i < etr->nr_outport; i++) {
tmp = etr->conns[i].child_dev;
- for (i = 0; i < etr->pdata->nr_outport; i++) {
if (tmp && coresight_is_catu_device(tmp)) return tmp; }tmp = etr->pdata->conns[i].child_dev;
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 530ad69..f6c5244 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -100,8 +100,8 @@ static int coresight_find_link_inport(struct coresight_device *csdev, int i; struct coresight_connection *conn;
- for (i = 0; i < parent->nr_outport; i++) {
conn = &parent->conns[i];
- for (i = 0; i < parent->pdata->nr_outport; i++) {
if (conn->child_dev == csdev) return conn->child_port; }conn = &parent->pdata->conns[i];
@@ -118,8 +118,8 @@ static int coresight_find_link_outport(struct coresight_device *csdev, int i; struct coresight_connection *conn;
- for (i = 0; i < csdev->nr_outport; i++) {
conn = &csdev->conns[i];
- for (i = 0; i < csdev->pdata->nr_outport; i++) {
if (conn->child_dev == child) return conn->outport; }conn = &csdev->pdata->conns[i];
@@ -304,10 +304,10 @@ static void coresight_disable_link(struct coresight_device *csdev, if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { refport = inport;
nr_conns = csdev->nr_inport;
} else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { refport = outport;nr_conns = csdev->pdata->nr_inport;
nr_conns = csdev->nr_outport;
} else { refport = 0; nr_conns = 1;nr_conns = csdev->pdata->nr_outport;
@@ -593,9 +593,10 @@ static void coresight_grab_device(struct coresight_device *csdev) { int i;
- for (i = 0; i < csdev->nr_outport; i++) {
struct coresight_device *child = csdev->conns[i].child_dev;
- for (i = 0; i < csdev->pdata->nr_outport; i++) {
struct coresight_device *child;
if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) pm_runtime_get_sync(child->dev.parent); }child = csdev->pdata->conns[i].child_dev;
@@ -611,9 +612,10 @@ static void coresight_drop_device(struct coresight_device *csdev) int i; pm_runtime_put(csdev->dev.parent);
- for (i = 0; i < csdev->nr_outport; i++) {
struct coresight_device *child = csdev->conns[i].child_dev;
- for (i = 0; i < csdev->pdata->nr_outport; i++) {
struct coresight_device *child;
if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) pm_runtime_put(child->dev.parent); }child = csdev->pdata->conns[i].child_dev;
@@ -643,9 +645,10 @@ static int _coresight_build_path(struct coresight_device *csdev, goto out; /* Not a sink - recursively explore each port found on this element */
- for (i = 0; i < csdev->nr_outport; i++) {
struct coresight_device *child_dev = csdev->conns[i].child_dev;
- for (i = 0; i < csdev->pdata->nr_outport; i++) {
struct coresight_device *child_dev;
if (child_dev && _coresight_build_path(child_dev, sink, path) == 0) { found = true;child_dev = csdev->pdata->conns[i].child_dev;
@@ -998,8 +1001,8 @@ static int coresight_orphan_match(struct device *dev, void *data) * Circle throuch all the connection of that component. If we find * an orphan connection whose name matches @csdev, link it. */
- for (i = 0; i < i_csdev->nr_outport; i++) {
conn = &i_csdev->conns[i];
- for (i = 0; i < i_csdev->pdata->nr_outport; i++) {
conn = &i_csdev->pdata->conns[i];
/* We have found at least one orphan connection */ if (conn->child_dev == NULL) { @@ -1038,8 +1041,8 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev) { int i;
- for (i = 0; i < csdev->nr_outport; i++) {
struct coresight_connection *conn = &csdev->conns[i];
- for (i = 0; i < csdev->pdata->nr_outport; i++) {
struct device *dev = NULL;struct coresight_connection *conn = &csdev->pdata->conns[i];
if (conn->child_name) @@ -1073,8 +1076,8 @@ static int coresight_remove_match(struct device *dev, void *data) * Circle throuch all the connection of that component. If we find * a connection whose name matches @csdev, remove it. */
- for (i = 0; i < iterator->nr_outport; i++) {
conn = &iterator->conns[i];
- for (i = 0; i < iterator->pdata->nr_outport; i++) {
conn = &iterator->pdata->conns[i];
if (conn->child_dev == NULL) continue; @@ -1106,7 +1109,7 @@ static void coresight_remove_conns(struct coresight_device *csdev) * doesn't have at least one input port, there is no point * in searching all the devices. */
- if (csdev->nr_inport)
- if (csdev->pdata->nr_inport) bus_for_each_dev(&coresight_bustype, NULL, csdev, coresight_remove_match);
} @@ -1193,10 +1196,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) csdev->refcnt = refcnts;
- csdev->nr_inport = desc->pdata->nr_inport;
- csdev->nr_outport = desc->pdata->nr_outport;
- csdev->conns = desc->pdata->conns;
- csdev->pdata = desc->pdata;
csdev->type = desc->type; csdev->subtype = desc->subtype; diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 84a2137..8c10def 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -140,9 +140,7 @@ struct coresight_connection { /**
- struct coresight_device - representation of a device as used by the framework
- @conns: array of coresight_connections associated to this component.
- @nr_inport: number of input port associated to this component.
- @nr_outport: number of output port associated to this component.
- @pdata: Platform data with device connections associated to this device.
- @type: as defined by @coresight_dev_type.
- @subtype: as defined by @coresight_dev_subtype.
- @ops: generic operations for this component, as defined
@@ -157,9 +155,7 @@ struct coresight_connection {
- @ea: Device attribute for sink representation under PMU directory.
*/ struct coresight_device {
- struct coresight_connection *conns;
- int nr_inport;
- int nr_outport;
- struct coresight_platform_data *pdata; enum coresight_dev_type type; union coresight_dev_subtype subtype; const struct coresight_ops *ops;
For patches 21 to 24:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
-- 2.7.4
We are about to introduce methods to clean up the platform data as we switch to tracking the device reference from "name" to "fwnode handles" for device connections. This requires us to drop the fwnode handle references when the data is no longer required - i.e, when the device probe fails or the device gets unregistered.
In order to consolidate the invocation of the cleanup, we delay the platform probing to the very last minute, possibly before invoking the coresight_register. Then, we leave the coresight core code to do the clean up. i.e, if the coresight_register fails, it takes care of freeing the data. Otherwise, coresight_unregister will do the necessary operations.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 14 +++++++------- drivers/hwtracing/coresight/coresight-etb10.c | 10 +++++----- drivers/hwtracing/coresight/coresight-etm3x.c | 12 +++++++----- drivers/hwtracing/coresight/coresight-etm4x.c | 10 +++++----- drivers/hwtracing/coresight/coresight-funnel.c | 10 +++++----- drivers/hwtracing/coresight/coresight-replicator.c | 12 +++++++----- drivers/hwtracing/coresight/coresight-stm.c | 11 +++++++---- drivers/hwtracing/coresight/coresight-tmc.c | 16 ++++++++-------- drivers/hwtracing/coresight/coresight-tpiu.c | 9 ++++----- 9 files changed, 55 insertions(+), 49 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 03f5b95..f249be6 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -505,13 +505,6 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct device *dev = &adev->dev; void __iomem *base;
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) { - ret = PTR_ERR(pdata); - goto out; - } - dev->platform_data = pdata; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM; @@ -544,6 +537,13 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) if (ret) goto out;
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out; + } + dev->platform_data = pdata; + drvdata->base = base; catu_desc.pdata = pdata; catu_desc.dev = dev; diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 91a5d7a..e5b46c7 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -682,11 +682,6 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -718,6 +713,11 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata->buf) return -ENOMEM;
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &etb_cs_ops; diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 101fb01..f2d4616 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -795,11 +795,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - - adev->dev.platform_data = pdata; drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata);
@@ -849,6 +844,13 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) etm_init_trace_id(drvdata); etm_set_default(&drvdata->config);
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto err_arch_supported; + } + adev->dev.platform_data = pdata; + desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc.ops = &etm_cs_ops; diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 7ff0989..7c53fb2 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -981,11 +981,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -1028,6 +1023,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) etm4_init_trace_id(drvdata); etm4_set_default(&drvdata->config);
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc.ops = &etm4_cs_ops; diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 61a9e01..38af045 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -186,11 +186,6 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -211,6 +206,11 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) drvdata->base = base; pm_runtime_put(&adev->dev);
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; desc.ops = &funnel_cs_ops; diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 939f20d..8fbc028 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -179,11 +179,6 @@ static int replicator_probe(struct device *dev, struct resource *res) struct coresight_desc desc = { 0 }; void __iomem *base;
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - dev->platform_data = pdata; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -209,6 +204,13 @@ static int replicator_probe(struct device *dev, struct resource *res) desc.groups = replicator_groups; }
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out_disable_clk; + } + dev->platform_data = pdata; + dev_set_drvdata(dev, drvdata); desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 734227f..5c7fc4a 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -810,10 +810,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) size_t bitmap_size; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -866,6 +862,13 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) return -EPROBE_DEFER; }
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto stm_unregister; + } + adev->dev.platform_data = pdata; + desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE; desc.ops = &stm_cs_ops; diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 02c5cb5..94d3ebf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -396,13 +396,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) { - ret = PTR_ERR(pdata); - goto out; - } - adev->dev.platform_data = pdata; - ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) @@ -430,7 +423,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) else drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
- desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_tmc_groups; desc.name = dev_name(dev); @@ -461,6 +453,14 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out; + } + adev->dev.platform_data = pdata; + desc.pdata = pdata; + drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 792f1d6..39a509f 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -121,11 +121,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - dev->platform_data = pdata; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -148,6 +143,10 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) /* Disable tpiu to support older devices */ tpiu_disable_hw(drvdata);
+ pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + dev->platform_data = pdata;
desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PORT;
On Mon, Apr 15, 2019 at 05:04:08PM +0100, Suzuki K Poulose wrote:
We are about to introduce methods to clean up the platform data as we switch to tracking the device reference from "name" to "fwnode handles" for device connections. This requires us to drop the fwnode handle references when the data is no longer required - i.e, when the device probe fails or the device gets unregistered.
In order to consolidate the invocation of the cleanup, we delay the platform probing to the very last minute, possibly before invoking the coresight_register. Then, we leave the coresight core code to do the clean up. i.e, if the coresight_register fails, it takes care of freeing the data. Otherwise, coresight_unregister will do the necessary operations.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-catu.c | 14 +++++++------- drivers/hwtracing/coresight/coresight-etb10.c | 10 +++++----- drivers/hwtracing/coresight/coresight-etm3x.c | 12 +++++++----- drivers/hwtracing/coresight/coresight-etm4x.c | 10 +++++----- drivers/hwtracing/coresight/coresight-funnel.c | 10 +++++----- drivers/hwtracing/coresight/coresight-replicator.c | 12 +++++++----- drivers/hwtracing/coresight/coresight-stm.c | 11 +++++++---- drivers/hwtracing/coresight/coresight-tmc.c | 16 ++++++++-------- drivers/hwtracing/coresight/coresight-tpiu.c | 9 ++++----- 9 files changed, 55 insertions(+), 49 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 03f5b95..f249be6 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -505,13 +505,6 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct device *dev = &adev->dev; void __iomem *base;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
- }
- dev->platform_data = pdata;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM;
@@ -544,6 +537,13 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) if (ret) goto out;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
- }
- dev->platform_data = pdata;
- drvdata->base = base; catu_desc.pdata = pdata; catu_desc.dev = dev;
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 91a5d7a..e5b46c7 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -682,11 +682,6 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -718,6 +713,11 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata->buf) return -ENOMEM;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
- desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &etb_cs_ops;
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 101fb01..f2d4616 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -795,11 +795,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata; drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata);
@@ -849,6 +844,13 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) etm_init_trace_id(drvdata); etm_set_default(&drvdata->config);
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto err_arch_supported;
- }
- adev->dev.platform_data = pdata;
- desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc.ops = &etm_cs_ops;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 7ff0989..7c53fb2 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -981,11 +981,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
- dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -1028,6 +1023,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) etm4_init_trace_id(drvdata); etm4_set_default(&drvdata->config);
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
Here you need to "goto err_arch_supported" instead of returning.
- adev->dev.platform_data = pdata;
- desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc.ops = &etm4_cs_ops;
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 61a9e01..38af045 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -186,11 +186,6 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -211,6 +206,11 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) drvdata->base = base; pm_runtime_put(&adev->dev);
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
- desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; desc.ops = &funnel_cs_ops;
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 939f20d..8fbc028 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -179,11 +179,6 @@ static int replicator_probe(struct device *dev, struct resource *res) struct coresight_desc desc = { 0 }; void __iomem *base;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- dev->platform_data = pdata;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -209,6 +204,13 @@ static int replicator_probe(struct device *dev, struct resource *res) desc.groups = replicator_groups; }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out_disable_clk;
- }
- dev->platform_data = pdata;
- dev_set_drvdata(dev, drvdata); desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 734227f..5c7fc4a 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -810,10 +810,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) size_t bitmap_size; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -866,6 +862,13 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) return -EPROBE_DEFER; }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto stm_unregister;
- }
- adev->dev.platform_data = pdata;
- desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE; desc.ops = &stm_cs_ops;
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 02c5cb5..94d3ebf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -396,13 +396,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
- }
- adev->dev.platform_data = pdata;
- ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata)
@@ -430,7 +423,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) else drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
- desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_tmc_groups; desc.name = dev_name(dev);
@@ -461,6 +453,14 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
ret = PTR_ERR(pdata);
goto out;
- }
- adev->dev.platform_data = pdata;
- desc.pdata = pdata;
- drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev);
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 792f1d6..39a509f 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -121,11 +121,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- dev->platform_data = pdata;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -148,6 +143,10 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) /* Disable tpiu to support older devices */ tpiu_disable_hw(drvdata);
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- dev->platform_data = pdata;
desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PORT; -- 2.7.4
On 22/04/2019 18:16, Mathieu Poirier wrote:
On Mon, Apr 15, 2019 at 05:04:08PM +0100, Suzuki K Poulose wrote:
We are about to introduce methods to clean up the platform data as we switch to tracking the device reference from "name" to "fwnode handles" for device connections. This requires us to drop the fwnode handle references when the data is no longer required - i.e, when the device probe fails or the device gets unregistered.
In order to consolidate the invocation of the cleanup, we delay the platform probing to the very last minute, possibly before invoking the coresight_register. Then, we leave the coresight core code to do the clean up. i.e, if the coresight_register fails, it takes care of freeing the data. Otherwise, coresight_unregister will do the necessary operations.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
...
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 7ff0989..7c53fb2 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -981,11 +981,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM;
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
- adev->dev.platform_data = pdata;
- dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */ @@ -1028,6 +1023,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) etm4_init_trace_id(drvdata); etm4_set_default(&drvdata->config);
- pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata))
return PTR_ERR(pdata);
Here you need to "goto err_arch_supported" instead of returning.
Thanks for catching that ! Fixed.
Suzuki
Add a helper to clean up the platform specific data provided by the firmware. This will be later used for dropping the necessary references when we switch to the fwnode handles for tracking connections.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 12 +++++++++--- drivers/hwtracing/coresight/coresight-priv.h | 4 ++++ drivers/hwtracing/coresight/coresight.c | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 0415fff..a408b01 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -17,6 +17,7 @@ #include <linux/cpumask.h> #include <asm/smp_plat.h>
+#include "coresight-priv.h" /* * coresight_alloc_conns: Allocate connections record for each output * port from the device. @@ -304,7 +305,7 @@ EXPORT_SYMBOL_GPL(coresight_get_cpu); struct coresight_platform_data * coresight_get_platform_data(struct device *dev) { - struct coresight_platform_data *pdata; + struct coresight_platform_data *pdata, *ret = NULL; struct fwnode_handle *fwnode = dev_fwnode(dev);
if (IS_ERR_OR_NULL(fwnode)) @@ -315,8 +316,13 @@ coresight_get_platform_data(struct device *dev) return ERR_PTR(-ENOMEM);
if (is_of_node(fwnode)) - return of_get_coresight_platform_data(dev, pdata); + ret = of_get_coresight_platform_data(dev, pdata);
- return ERR_PTR(-ENOENT); + if (!IS_ERR_OR_NULL(ret)) + return pdata; + + /* Cleanup the connection information */ + coresight_release_platform_data(pdata); + return ret; } EXPORT_SYMBOL_GPL(coresight_get_platform_data); diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index e0684d0..c216421 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -200,4 +200,8 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) return 0; }
+static inline void +coresight_release_platform_data(struct coresight_platform_data *pdata) +{} + #endif diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index f6c5244..82fb411 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1248,6 +1248,8 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) err_free_csdev: kfree(csdev); err_out: + /* Cleanup the connection information */ + coresight_release_platform_data(desc->pdata); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(coresight_register); @@ -1257,6 +1259,7 @@ void coresight_unregister(struct coresight_device *csdev) etm_perf_del_symlink_sink(csdev); /* Remove references of that device in the topology */ coresight_remove_conns(csdev); + coresight_release_platform_data(csdev->pdata); device_unregister(&csdev->dev); } EXPORT_SYMBOL_GPL(coresight_unregister);
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/base/devcon.c | 5 ----- drivers/base/property.c | 6 ++++++ include/linux/property.h | 1 + 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index 04db9ae..f4a9e30 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -107,11 +107,6 @@ static struct bus_type *generic_match_buses[] = { NULL, };
-static int device_fwnode_match(struct device *dev, void *fwnode) -{ - return dev_fwnode(dev) == fwnode; -} - static void *device_connection_fwnode_match(struct device_connection *con) { struct bus_type *bus; diff --git a/drivers/base/property.c b/drivers/base/property.c index 8b91ab3..d10d923 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -25,6 +25,12 @@ struct fwnode_handle *dev_fwnode(struct device *dev) } EXPORT_SYMBOL_GPL(dev_fwnode);
+int device_fwnode_match(struct device *dev, void *fwnode) +{ + return dev_fwnode(dev) == fwnode; +} +EXPORT_SYMBOL_GPL(device_fwnode_match); + /** * device_property_present - check if a property of a device is present * @dev: Device whose property is being checked diff --git a/include/linux/property.h b/include/linux/property.h index 65d3420..c8fd3d42 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -34,6 +34,7 @@ enum dev_dma_attr { };
struct fwnode_handle *dev_fwnode(struct device *dev); +int device_fwnode_match(struct device *dev, void *fwnode);
bool device_property_present(struct device *dev, const char *propname); int device_property_read_u8_array(struct device *dev, const char *propname,
On Mon, Apr 15, 2019 at 6:06 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Can you resend this with a CC to linux-acpi@vger.kernel.org, please?
There's some device properties material for 5.2 collected already and it would be good to keep all that together.
drivers/base/devcon.c | 5 ----- drivers/base/property.c | 6 ++++++ include/linux/property.h | 1 + 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index 04db9ae..f4a9e30 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -107,11 +107,6 @@ static struct bus_type *generic_match_buses[] = { NULL, };
-static int device_fwnode_match(struct device *dev, void *fwnode) -{
return dev_fwnode(dev) == fwnode;
-}
static void *device_connection_fwnode_match(struct device_connection *con) { struct bus_type *bus; diff --git a/drivers/base/property.c b/drivers/base/property.c index 8b91ab3..d10d923 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -25,6 +25,12 @@ struct fwnode_handle *dev_fwnode(struct device *dev) } EXPORT_SYMBOL_GPL(dev_fwnode);
+int device_fwnode_match(struct device *dev, void *fwnode) +{
return dev_fwnode(dev) == fwnode;
+} +EXPORT_SYMBOL_GPL(device_fwnode_match);
/**
- device_property_present - check if a property of a device is present
- @dev: Device whose property is being checked
diff --git a/include/linux/property.h b/include/linux/property.h index 65d3420..c8fd3d42 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -34,6 +34,7 @@ enum dev_dma_attr { };
struct fwnode_handle *dev_fwnode(struct device *dev); +int device_fwnode_match(struct device *dev, void *fwnode);
bool device_property_present(struct device *dev, const char *propname); int device_property_read_u8_array(struct device *dev, const char *propname, -- 2.7.4
Hi Rafael
On 04/16/2019 11:20 AM, Rafael J. Wysocki wrote:
On Mon, Apr 15, 2019 at 6:06 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Can you resend this with a CC to linux-acpi@vger.kernel.org, please?
There's some device properties material for 5.2 collected already and it would be good to keep all that together.
Sure, will do. Btw, I have a question w.r.t the match function.
We have :
class_find_device(struct class *class, struct device *start, const void *data, int (*match)(struct device *, const void *)) and
bus_find_device(struct bus_type *bus, struct device *start, void *data, int (*match)(struct device *dev, void *data))
Just because the "match" has slightly different constraint for the data (i.e, const void * vs void *), we can't reuse the same match function for class_find_device. Do you think we should converge the types to reuse the same match every where (Of course in a separate patch series) ?
Cheers Suzuki
On Tue, Apr 16, 2019 at 12:31 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Hi Rafael
On 04/16/2019 11:20 AM, Rafael J. Wysocki wrote:
On Mon, Apr 15, 2019 at 6:06 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Can you resend this with a CC to linux-acpi@vger.kernel.org, please?
There's some device properties material for 5.2 collected already and it would be good to keep all that together.
Sure, will do. Btw, I have a question w.r.t the match function.
We have :
class_find_device(struct class *class, struct device *start, const void *data, int (*match)(struct device *, const void *)) and
bus_find_device(struct bus_type *bus, struct device *start, void *data, int (*match)(struct device *dev, void *data))
Just because the "match" has slightly different constraint for the data (i.e, const void * vs void *), we can't reuse the same match function for class_find_device. Do you think we should converge the types to reuse the same match every where (Of course in a separate patch series) ?
AFAICS, (void *) pointers can be passed to functions taking (const void *) arguments, so yes, it looks like that could be consolidated and it also would be a valuable cleanup IMO.
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: linux-acpi@vger.kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com ---
Resending with linux-acpi in Cc, as requested by Rafael.
drivers/base/devcon.c | 5 ----- drivers/base/property.c | 6 ++++++ include/linux/property.h | 1 + 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index 04db9ae..f4a9e30 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -107,11 +107,6 @@ static struct bus_type *generic_match_buses[] = { NULL, };
-static int device_fwnode_match(struct device *dev, void *fwnode) -{ - return dev_fwnode(dev) == fwnode; -} - static void *device_connection_fwnode_match(struct device_connection *con) { struct bus_type *bus; diff --git a/drivers/base/property.c b/drivers/base/property.c index 8b91ab3..d10d923 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -25,6 +25,12 @@ struct fwnode_handle *dev_fwnode(struct device *dev) } EXPORT_SYMBOL_GPL(dev_fwnode);
+int device_fwnode_match(struct device *dev, void *fwnode) +{ + return dev_fwnode(dev) == fwnode; +} +EXPORT_SYMBOL_GPL(device_fwnode_match); + /** * device_property_present - check if a property of a device is present * @dev: Device whose property is being checked diff --git a/include/linux/property.h b/include/linux/property.h index 65d3420..c8fd3d42 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -34,6 +34,7 @@ enum dev_dma_attr { };
struct fwnode_handle *dev_fwnode(struct device *dev); +int device_fwnode_match(struct device *dev, void *fwnode);
bool device_property_present(struct device *dev, const char *propname); int device_property_read_u8_array(struct device *dev, const char *propname,
On Tue, Apr 16, 2019 at 12:39 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: linux-acpi@vger.kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Resending with linux-acpi in Cc, as requested by Rafael.
Do any other patches in your series depend on this one?
drivers/base/devcon.c | 5 ----- drivers/base/property.c | 6 ++++++ include/linux/property.h | 1 + 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index 04db9ae..f4a9e30 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -107,11 +107,6 @@ static struct bus_type *generic_match_buses[] = { NULL, };
-static int device_fwnode_match(struct device *dev, void *fwnode) -{
return dev_fwnode(dev) == fwnode;
-}
static void *device_connection_fwnode_match(struct device_connection *con) { struct bus_type *bus; diff --git a/drivers/base/property.c b/drivers/base/property.c index 8b91ab3..d10d923 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -25,6 +25,12 @@ struct fwnode_handle *dev_fwnode(struct device *dev) } EXPORT_SYMBOL_GPL(dev_fwnode);
+int device_fwnode_match(struct device *dev, void *fwnode) +{
return dev_fwnode(dev) == fwnode;
+} +EXPORT_SYMBOL_GPL(device_fwnode_match);
/**
- device_property_present - check if a property of a device is present
- @dev: Device whose property is being checked
diff --git a/include/linux/property.h b/include/linux/property.h index 65d3420..c8fd3d42 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -34,6 +34,7 @@ enum dev_dma_attr { };
struct fwnode_handle *dev_fwnode(struct device *dev); +int device_fwnode_match(struct device *dev, void *fwnode);
bool device_property_present(struct device *dev, const char *propname); int device_property_read_u8_array(struct device *dev, const char *propname, -- 2.7.4
On 04/16/2019 11:48 AM, Rafael J. Wysocki wrote:
On Tue, Apr 16, 2019 at 12:39 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: linux-acpi@vger.kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Resending with linux-acpi in Cc, as requested by Rafael.
Do any other patches in your series depend on this one?
Yes, I do. But they are in the middle of a big series of changes and I don't expect this series to go into 5.2. So, if you plan to pull this please go ahead.
Suzuki
On Tue, Apr 16, 2019 at 12:53 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
On 04/16/2019 11:48 AM, Rafael J. Wysocki wrote:
On Tue, Apr 16, 2019 at 12:39 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: linux-acpi@vger.kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Resending with linux-acpi in Cc, as requested by Rafael.
Do any other patches in your series depend on this one?
Yes, I do. But they are in the middle of a big series of changes and I don't expect this series to go into 5.2. So, if you plan to pull this please go ahead.
I would prefer the new exported function to return bool. With that changed, I can apply the patch I think.
On 04/18/2019 03:39 PM, Rafael J. Wysocki wrote:
On Tue, Apr 16, 2019 at 12:53 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
On 04/16/2019 11:48 AM, Rafael J. Wysocki wrote:
On Tue, Apr 16, 2019 at 12:39 PM Suzuki K Poulose suzuki.poulose@arm.com wrote:
Make the device_fwnode_match() a generic helper to match device by fwnode handle for use with bus_find_device(). This will be also used by coresight.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: linux-acpi@vger.kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Resending with linux-acpi in Cc, as requested by Rafael.
Do any other patches in your series depend on this one?
Yes, I do. But they are in the middle of a big series of changes and I don't expect this series to go into 5.2. So, if you plan to pull this please go ahead.
I would prefer the new exported function to return bool. With that changed, I can apply the patch I think.
That will need changes to all the other callers of bus_find_device() to fix their match(). I guess that is a bit of an invasive change, so I would rather do it in the "consolidation" series with class_find_device().
Hope you're fine with that.
Suzuki
We match of_node while searching for a device. Make this more generic in preparation for the ACPI support by using fwnode_handle.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index a408b01..318a6ff 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -36,14 +36,8 @@ static int coresight_alloc_conns(struct device *dev, return 0; }
-#ifdef CONFIG_OF -static int of_dev_node_match(struct device *dev, void *data) -{ - return dev->of_node == data; -} - static struct device * -of_coresight_get_endpoint_device(struct device_node *endpoint) +coresight_find_device_by_fwnode(struct fwnode_handle *fwnode) { struct device *dev = NULL;
@@ -52,7 +46,7 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) * platform bus. */ dev = bus_find_device(&platform_bus_type, NULL, - endpoint, of_dev_node_match); + fwnode, device_fwnode_match); if (dev) return dev;
@@ -61,9 +55,10 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) * looking for the device that matches the endpoint node. */ return bus_find_device(&amba_bustype, NULL, - endpoint, of_dev_node_match); + fwnode, device_fwnode_match); }
+#ifdef CONFIG_OF static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) { return of_property_read_bool(ep, "slave-mode"); @@ -191,6 +186,7 @@ static int of_coresight_parse_endpoint(struct device *dev, struct device_node *rparent = NULL; struct device_node *rep = NULL; struct device *rdev = NULL; + struct fwnode_handle *rdev_fwnode;
do { /* Parse the local port details */ @@ -209,8 +205,9 @@ static int of_coresight_parse_endpoint(struct device *dev, if (of_graph_parse_endpoint(rep, &rendpoint)) break;
+ rdev_fwnode = of_fwnode_handle(rparent); /* If the remote device is not available, defer probing */ - rdev = of_coresight_get_endpoint_device(rparent); + rdev = coresight_find_device_by_fwnode(rdev_fwnode); if (!rdev) { ret = -EPROBE_DEFER; break;
On Mon, Apr 15, 2019 at 05:04:11PM +0100, Suzuki K Poulose wrote:
We match of_node while searching for a device. Make this more generic in preparation for the ACPI support by using fwnode_handle.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-platform.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index a408b01..318a6ff 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -36,14 +36,8 @@ static int coresight_alloc_conns(struct device *dev, return 0; } -#ifdef CONFIG_OF -static int of_dev_node_match(struct device *dev, void *data) -{
- return dev->of_node == data;
-}
static struct device * -of_coresight_get_endpoint_device(struct device_node *endpoint) +coresight_find_device_by_fwnode(struct fwnode_handle *fwnode) { struct device *dev = NULL; @@ -52,7 +46,7 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) * platform bus. */ dev = bus_find_device(&platform_bus_type, NULL,
endpoint, of_dev_node_match);
if (dev) return dev;fwnode, device_fwnode_match);
@@ -61,9 +55,10 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) * looking for the device that matches the endpoint node. */ return bus_find_device(&amba_bustype, NULL,
endpoint, of_dev_node_match);
fwnode, device_fwnode_match);
} +#ifdef CONFIG_OF static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) { return of_property_read_bool(ep, "slave-mode"); @@ -191,6 +186,7 @@ static int of_coresight_parse_endpoint(struct device *dev, struct device_node *rparent = NULL; struct device_node *rep = NULL; struct device *rdev = NULL;
- struct fwnode_handle *rdev_fwnode;
do { /* Parse the local port details */ @@ -209,8 +205,9 @@ static int of_coresight_parse_endpoint(struct device *dev, if (of_graph_parse_endpoint(rep, &rendpoint)) break;
/* If the remote device is not available, defer probing */rdev_fwnode = of_fwnode_handle(rparent);
rdev = of_coresight_get_endpoint_device(rparent);
if (!rdev) { ret = -EPROBE_DEFER; break;rdev = coresight_find_device_by_fwnode(rdev_fwnode);
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
-- 2.7.4
We rely on the device names to find a CoreSight device on the coresight bus. The device name however is obtained from the platform, which is bound to the real platform/amba device. As we are about to use different naming scheme for the coresight devices, we can't rely on the platform device name to find the corresponding coresight device. Instead we use the platform agnostic "fwnode handle" of the parent device to find the devices. We also reuse the same fwnode as the parent for the Coresight device we create.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 12 +++++-- drivers/hwtracing/coresight/coresight-priv.h | 4 +-- drivers/hwtracing/coresight/coresight.c | 42 +++++++++++++++++++----- include/linux/coresight.h | 4 +-- 4 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 318a6ff..c9a59fb 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -214,9 +214,15 @@ static int of_coresight_parse_endpoint(struct device *dev, }
conn->outport = endpoint.port; - conn->child_name = devm_kstrdup(dev, - dev_name(rdev), - GFP_KERNEL); + /* + * Hold the refcount to the target device. This could be + * released via: + * 1) coresight_release_platform_data() if the probe fails or + * this device is unregistered. + * 2) While removing the target device via + * coresight_remove_match() + */ + conn->child_fwnode = fwnode_handle_get(rdev_fwnode); conn->child_port = rendpoint.port; /* Connection record updated */ ret = 1; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index c216421..61d7f9f 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -200,8 +200,6 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) return 0; }
-static inline void -coresight_release_platform_data(struct coresight_platform_data *pdata) -{} +void coresight_release_platform_data(struct coresight_platform_data *pdata);
#endif diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 82fb411..5169ce1 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -976,6 +976,7 @@ static void coresight_device_release(struct device *dev) { struct coresight_device *csdev = to_coresight_device(dev);
+ fwnode_handle_put(csdev->dev.fwnode); kfree(csdev->refcnt); kfree(csdev); } @@ -1007,13 +1008,11 @@ static int coresight_orphan_match(struct device *dev, void *data) /* We have found at least one orphan connection */ if (conn->child_dev == NULL) { /* Does it match this newly added device? */ - if (conn->child_name && - !strcmp(dev_name(&csdev->dev), conn->child_name)) { + if (conn->child_fwnode == csdev->dev.fwnode) conn->child_dev = csdev; - } else { + else /* This component still has an orphan */ still_orphan = true; - } } }
@@ -1045,9 +1044,9 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev) struct coresight_connection *conn = &csdev->pdata->conns[i]; struct device *dev = NULL;
- if (conn->child_name) - dev = bus_find_device_by_name(&coresight_bustype, NULL, - conn->child_name); + dev = bus_find_device(&coresight_bustype, NULL, + (void *)conn->child_fwnode, + device_fwnode_match); if (dev) { conn->child_dev = to_coresight_device(dev); /* and put reference from 'bus_find_device()' */ @@ -1082,9 +1081,15 @@ static int coresight_remove_match(struct device *dev, void *data) if (conn->child_dev == NULL) continue;
- if (!strcmp(dev_name(&csdev->dev), conn->child_name)) { + if (csdev->dev.fwnode == conn->child_fwnode) { iterator->orphan = true; conn->child_dev = NULL; + /* + * Drop the reference to the handle for the remote + * device acquired in parsing the connections from + * platform data. + */ + fwnode_handle_put(conn->child_fwnode); /* No need to continue */ break; } @@ -1164,6 +1169,22 @@ static int __init coresight_init(void) } postcore_initcall(coresight_init);
+/* + * coresight_release_platform_data: Release references to the devices connected + * to the output port of this device. + */ +void coresight_release_platform_data(struct coresight_platform_data *pdata) +{ + int i; + + for (i = 0; i < pdata->nr_outport; i++) { + if (pdata->conns[i].child_fwnode) { + fwnode_handle_put(pdata->conns[i].child_fwnode); + pdata->conns[i].child_fwnode = 0; + } + } +} + struct coresight_device *coresight_register(struct coresight_desc *desc) { int ret; @@ -1208,6 +1229,11 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) csdev->dev.parent = desc->dev; csdev->dev.release = coresight_device_release; csdev->dev.bus = &coresight_bustype; + /* + * Hold the reference to our parent device. This will be + * dropped only in coresight_device_release(). + */ + csdev->dev.fwnode = fwnode_handle_get(dev_fwnode(desc->dev)); dev_set_name(&csdev->dev, "%s", desc->name);
ret = device_register(&csdev->dev); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 8c10def..188e759 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -126,15 +126,15 @@ struct coresight_desc { /** * struct coresight_connection - representation of a single connection * @outport: a connection's output port number. - * @chid_name: remote component's name. * @child_port: remote component's port number @output is connected to. + * @chid_fwnode: remote component's fwnode handle. * @child_dev: a @coresight_device representation of the component connected to @outport. */ struct coresight_connection { int outport; - const char *child_name; int child_port; + struct fwnode_handle *child_fwnode; struct coresight_device *child_dev; };
On Mon, Apr 15, 2019 at 05:04:12PM +0100, Suzuki K Poulose wrote:
We rely on the device names to find a CoreSight device on the coresight bus. The device name however is obtained from the platform, which is bound to the real platform/amba device. As we are about to use different naming scheme for the coresight devices, we can't rely on the platform device name to find the corresponding coresight device. Instead we use the platform agnostic "fwnode handle" of the parent device to find the devices. We also reuse the same fwnode as the parent for the Coresight device we create.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-platform.c | 12 +++++-- drivers/hwtracing/coresight/coresight-priv.h | 4 +-- drivers/hwtracing/coresight/coresight.c | 42 +++++++++++++++++++----- include/linux/coresight.h | 4 +-- 4 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 318a6ff..c9a59fb 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -214,9 +214,15 @@ static int of_coresight_parse_endpoint(struct device *dev, } conn->outport = endpoint.port;
conn->child_name = devm_kstrdup(dev,
dev_name(rdev),
GFP_KERNEL);
/*
* Hold the refcount to the target device. This could be
* released via:
* 1) coresight_release_platform_data() if the probe fails or
* this device is unregistered.
* 2) While removing the target device via
* coresight_remove_match()
*/
Many thanks for the documentation - not only does it help me but it also makes it easier for other people to contribute to the subsystem.
conn->child_port = rendpoint.port; /* Connection record updated */ ret = 1;conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index c216421..61d7f9f 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -200,8 +200,6 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) return 0; } -static inline void -coresight_release_platform_data(struct coresight_platform_data *pdata) -{} +void coresight_release_platform_data(struct coresight_platform_data *pdata);
Now that we have fixed of_get_coresight_platform_data() I think patch 26 should be rolled into this one. That way everything related to coresight_release_platform_data() is done in the same patch and the function doesn't have to be modified twice.
#endif diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 82fb411..5169ce1 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -976,6 +976,7 @@ static void coresight_device_release(struct device *dev) { struct coresight_device *csdev = to_coresight_device(dev);
- fwnode_handle_put(csdev->dev.fwnode); kfree(csdev->refcnt); kfree(csdev);
} @@ -1007,13 +1008,11 @@ static int coresight_orphan_match(struct device *dev, void *data) /* We have found at least one orphan connection */ if (conn->child_dev == NULL) { /* Does it match this newly added device? */
if (conn->child_name &&
!strcmp(dev_name(&csdev->dev), conn->child_name)) {
if (conn->child_fwnode == csdev->dev.fwnode) conn->child_dev = csdev;
} else {
else /* This component still has an orphan */ still_orphan = true;
} }}
@@ -1045,9 +1044,9 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev) struct coresight_connection *conn = &csdev->pdata->conns[i]; struct device *dev = NULL;
if (conn->child_name)
dev = bus_find_device_by_name(&coresight_bustype, NULL,
conn->child_name);
dev = bus_find_device(&coresight_bustype, NULL,
(void *)conn->child_fwnode,
if (dev) { conn->child_dev = to_coresight_device(dev); /* and put reference from 'bus_find_device()' */device_fwnode_match);
@@ -1082,9 +1081,15 @@ static int coresight_remove_match(struct device *dev, void *data) if (conn->child_dev == NULL) continue;
if (!strcmp(dev_name(&csdev->dev), conn->child_name)) {
if (csdev->dev.fwnode == conn->child_fwnode) { iterator->orphan = true; conn->child_dev = NULL;
/*
* Drop the reference to the handle for the remote
* device acquired in parsing the connections from
* platform data.
*/
}fwnode_handle_put(conn->child_fwnode); /* No need to continue */ break;
@@ -1164,6 +1169,22 @@ static int __init coresight_init(void) } postcore_initcall(coresight_init); +/*
- coresight_release_platform_data: Release references to the devices connected
- to the output port of this device.
- */
+void coresight_release_platform_data(struct coresight_platform_data *pdata) +{
- int i;
- for (i = 0; i < pdata->nr_outport; i++) {
if (pdata->conns[i].child_fwnode) {
fwnode_handle_put(pdata->conns[i].child_fwnode);
pdata->conns[i].child_fwnode = 0;
pdata->conns[i].child_fwnode = NULL;
- }
+}
struct coresight_device *coresight_register(struct coresight_desc *desc) { int ret; @@ -1208,6 +1229,11 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) csdev->dev.parent = desc->dev; csdev->dev.release = coresight_device_release; csdev->dev.bus = &coresight_bustype;
- /*
* Hold the reference to our parent device. This will be
* dropped only in coresight_device_release().
*/
- csdev->dev.fwnode = fwnode_handle_get(dev_fwnode(desc->dev)); dev_set_name(&csdev->dev, "%s", desc->name);
ret = device_register(&csdev->dev); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 8c10def..188e759 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -126,15 +126,15 @@ struct coresight_desc { /**
- struct coresight_connection - representation of a single connection
- @outport: a connection's output port number.
- @chid_name: remote component's name.
- @child_port: remote component's port number @output is connected to.
*/
- @chid_fwnode: remote component's fwnode handle.
- @child_dev: a @coresight_device representation of the component connected to @outport.
struct coresight_connection { int outport;
- const char *child_name; int child_port;
- struct fwnode_handle *child_fwnode; struct coresight_device *child_dev;
}; -- 2.7.4
So far we have reused the name of the "platform" device for the CoreSight device. But this is not very intuitive when we move to ACPI. Also, the ACPI device names have ":" in them (e.g, ARMHC97C:01), which the perf tool doesn't like very much. This patch introduces a generic naming scheme, givin more intuitive names for the devices that appear on the CoreSight bus. The names follow the pattern "prefix" followed by "index" (e.g, etm5). We maintain a list of allocated devices per "prefix" to make sure we don't allocate a new name when it is reprobed (e.g, due to unsatisifed device dependencies). So, we maintain the list of "fwnodes" of the parent devices to allocate a consistent name. All devices except the ETMs get an index allocated in the order of probing. ETMs get an index based on the CPU they are attached to.
TMC devices are named using "tmc_etf", "tmc_etb", and "tmc_etr" prefixes depending on the configuration of the device.
The replicators are not classified as dynamic/static anymore. One could easily figure that out by checking the presence of "mgmt" registers under sysfs.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-catu.c | 7 ++- drivers/hwtracing/coresight/coresight-etb10.c | 7 ++- drivers/hwtracing/coresight/coresight-etm3x.c | 4 +- drivers/hwtracing/coresight/coresight-etm4x.c | 5 +- drivers/hwtracing/coresight/coresight-funnel.c | 7 ++- drivers/hwtracing/coresight/coresight-replicator.c | 7 ++- drivers/hwtracing/coresight/coresight-stm.c | 12 +++-- drivers/hwtracing/coresight/coresight-tmc.c | 15 +++++- drivers/hwtracing/coresight/coresight-tpiu.c | 7 ++- drivers/hwtracing/coresight/coresight.c | 58 ++++++++++++++++++++++ include/linux/coresight.h | 25 +++++++++- 11 files changed, 142 insertions(+), 12 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index f249be6..e0637fc 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -28,6 +28,8 @@ #define catu_dbg(x, ...) do {} while (0) #endif
+DEFINE_CORESIGHT_DEVLIST(catu_devs, "catu"); + struct catu_etr_buf { struct tmc_sg_table *catu_table; dma_addr_t sladdr; @@ -505,6 +507,10 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct device *dev = &adev->dev; void __iomem *base;
+ catu_desc.name = coresight_alloc_device_name(&catu_devs, dev); + if (!catu_desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM; @@ -551,7 +557,6 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) catu_desc.type = CORESIGHT_DEV_TYPE_HELPER; catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU; catu_desc.ops = &catu_ops; - catu_desc.name = dev_name(dev);
drvdata->csdev = coresight_register(&catu_desc); if (IS_ERR(drvdata->csdev)) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index e5b46c7..8361b91 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -62,6 +62,8 @@ #define ETB_FFSR_BIT 1 #define ETB_FRAME_SIZE_WORDS 4
+DEFINE_CORESIGHT_DEVLIST(etb_devs, "etb"); + /** * struct etb_drvdata - specifics associated to an ETB component * @base: memory mapped base address for this component. @@ -682,6 +684,10 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
+ desc.name = coresight_alloc_device_name(&etb_devs, dev); + if (!desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -723,7 +729,6 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &etb_cs_ops; desc.pdata = pdata; desc.dev = dev; - desc.name = dev_name(dev); desc.groups = coresight_etb_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index f2d4616..bed7291 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -815,6 +815,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) }
drvdata->cpu = coresight_get_cpu(dev); + desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu); + if (!desc.name) + return -ENOMEM;
cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; @@ -856,7 +859,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &etm_cs_ops; desc.pdata = pdata; desc.dev = dev; - desc.name = dev_name(dev); desc.groups = coresight_etm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 7c53fb2..5c13a04 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -993,6 +993,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock);
drvdata->cpu = coresight_get_cpu(dev); + desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu); + if (!desc.name) + return -ENOMEM; +
cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; @@ -1034,7 +1038,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_etmv4_groups; - desc.name = dev_name(dev); drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 38af045..9b820b1 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -27,6 +27,8 @@ #define FUNNEL_HOLDTIME (0x7 << FUNNEL_HOLDTIME_SHFT) #define FUNNEL_ENSx_MASK 0xff
+DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); + /** * struct funnel_drvdata - specifics associated to a funnel component * @base: memory mapped base address for this component. @@ -186,6 +188,10 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
+ desc.name = coresight_alloc_device_name(&funnel_devs, dev); + if (!desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -216,7 +222,6 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &funnel_cs_ops; desc.pdata = pdata; desc.dev = dev; - desc.name = dev_name(dev); desc.groups = coresight_funnel_groups; drvdata->csdev = coresight_register(&desc);
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 8fbc028..2eb489c 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -22,6 +22,8 @@ #define REPLICATOR_IDFILTER0 0x000 #define REPLICATOR_IDFILTER1 0x004
+DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); + /** * struct replicator_drvdata - specifics associated to a replicator component * @base: memory mapped base address for this component. Also indicates @@ -179,6 +181,10 @@ static int replicator_probe(struct device *dev, struct resource *res) struct coresight_desc desc = { 0 }; void __iomem *base;
+ desc.name = coresight_alloc_device_name(&replicator_devs, dev); + if (!desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -217,7 +223,6 @@ static int replicator_probe(struct device *dev, struct resource *res) desc.ops = &replicator_cs_ops; desc.pdata = dev->platform_data; desc.dev = dev; - desc.name = dev_name(dev);
drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 5c7fc4a..2d6ae00 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -107,6 +107,8 @@ struct channel_space { unsigned long *guaranteed; };
+DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm"); + /** * struct stm_drvdata - specifics associated to an STM component * @base: memory mapped base address for this component. @@ -810,6 +812,10 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) size_t bitmap_size; struct coresight_desc desc = { 0 };
+ desc.name = coresight_alloc_device_name(&stm_devs, dev); + if (!desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -854,11 +860,12 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock);
stm_init_default_data(drvdata); - stm_init_generic_data(drvdata, dev_name(dev)); + stm_init_generic_data(drvdata, desc.name);
if (stm_register_device(dev, &drvdata->stm, THIS_MODULE)) { dev_info(dev, - "stm_register_device failed, probing deferred\n"); + "%s : stm_register_device failed, probing deferred\n", + desc.name); return -EPROBE_DEFER; }
@@ -874,7 +881,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &stm_cs_ops; desc.pdata = pdata; desc.dev = dev; - desc.name = dev_name(dev); desc.groups = coresight_stm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 94d3ebf..8b7b5d0 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -25,6 +25,10 @@ #include "coresight-priv.h" #include "coresight-tmc.h"
+DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb"); +DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf"); +DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr"); + void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata) { /* Ensure formatter, unformatter and hardware fifo are empty */ @@ -395,6 +399,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct tmc_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; + struct coresight_dev_list *dev_list = NULL;
ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -425,13 +430,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
desc.dev = dev; desc.groups = coresight_tmc_groups; - desc.name = dev_name(dev);
switch (drvdata->config_type) { case TMC_CONFIG_TYPE_ETB: desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etb_cs_ops; + dev_list = &etb_devs; break; case TMC_CONFIG_TYPE_ETR: desc.type = CORESIGHT_DEV_TYPE_SINK; @@ -441,11 +446,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) coresight_get_uci_data(id)); if (ret) goto out; + dev_list = &etr_devs; break; case TMC_CONFIG_TYPE_ETF: desc.type = CORESIGHT_DEV_TYPE_LINKSINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; desc.ops = &tmc_etf_cs_ops; + dev_list = &etf_devs; break; default: pr_err("%s: Unsupported TMC config\n", desc.name); @@ -453,6 +460,12 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
+ desc.name = coresight_alloc_device_name(dev_list, dev); + if (!desc.name) { + ret = -ENOMEM; + goto out; + } + pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) { ret = PTR_ERR(pdata); diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 39a509f..0404434 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -46,6 +46,8 @@ #define FFCR_FON_MAN BIT(6) #define FFCR_STOP_FI BIT(12)
+DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu"); + /** * @base: memory mapped base address for this component. * @dev: the device entity associated to this component. @@ -121,6 +123,10 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
+ desc.name = coresight_alloc_device_name(&tpiu_devs, dev); + if (!desc.name) + return -ENOMEM; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; @@ -153,7 +159,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &tpiu_cs_ops; desc.pdata = pdata; desc.dev = dev; - desc.name = dev_name(dev); drvdata->csdev = coresight_register(&desc);
if (!IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 5169ce1..e3b9321 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1289,3 +1289,61 @@ void coresight_unregister(struct coresight_device *csdev) device_unregister(&csdev->dev); } EXPORT_SYMBOL_GPL(coresight_unregister); + + +/* + * coresight_search_device_idx - Search the fwnode handle of a device + * in the given dev_idx list. Must be called with the coresight_mutex held. + * + * Returns the index of the entry, when found. Otherwise, -ENOENT. + */ +static inline int coresight_search_device_idx(struct coresight_dev_list *dict, + struct fwnode_handle *fwnode) +{ + int i; + + for (i = 0; i < dict->nr_idx; i++) + if (dict->fwnode_list[i] == fwnode) + return i; + return -ENOENT; +} + +/* + * coresight_alloc_device_name - Get an index for a given device in the + * device index list specific to a driver. An index is allocated for a + * device and is tracked with the fwnode_handle to prevent allocating + * duplicate indices for the same device (e.g, if we defer probing of + * a device due to dependencies), in case the index is requested again. + */ +char *coresight_alloc_device_name(struct coresight_dev_list *dict, + struct device *dev) +{ + int idx; + char *name = NULL; + struct fwnode_handle **list; + + mutex_lock(&coresight_mutex); + + idx = coresight_search_device_idx(dict, dev_fwnode(dev)); + if (idx < 0) { + /* Make space for the new entry */ + idx = dict->nr_idx; + list = krealloc(dict->fwnode_list, + (idx + 1) * sizeof(*dict->fwnode_list), + GFP_KERNEL); + if (ZERO_OR_NULL_PTR(list)) { + idx = -ENOMEM; + goto done; + } + + list[idx] = dev_fwnode(dev); + dict->fwnode_list = list; + dict->nr_idx = idx + 1; + } + + name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", dict->pfx, idx); +done: + mutex_unlock(&coresight_mutex); + return name; +} +EXPORT_SYMBOL_GPL(coresight_alloc_device_name); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 188e759..d6367a0 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -168,6 +168,28 @@ struct coresight_device { struct dev_ext_attribute *ea; };
+/* + * coresight_dev_list - Mapping for devices to "name" index for device + * names. + * + * @nr_idx: Number of entries already allocated. + * @pfx: Prefix pattern for device name. + * @fwnode_list: Array of fwnode_handles associated with each allocated + * index, upto nr_idx entries. + */ +struct coresight_dev_list { + int nr_idx; + const char *pfx; + struct fwnode_handle **fwnode_list; +}; + +#define DEFINE_CORESIGHT_DEVLIST(var, dev_pfx) \ +static struct coresight_dev_list (var) = { \ + .pfx = dev_pfx, \ + .nr_idx = 0, \ + .fwnode_list = NULL, \ +} + #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
#define source_ops(csdev) csdev->ops->source_ops @@ -260,7 +282,8 @@ extern int coresight_claim_device_unlocked(void __iomem *base);
extern void coresight_disclaim_device(void __iomem *base); extern void coresight_disclaim_device_unlocked(void __iomem *base); - +extern char *coresight_alloc_device_name(struct coresight_dev_list *devs, + struct device *dev); #else static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; }
On Mon, Apr 15, 2019 at 05:04:13PM +0100, Suzuki K Poulose wrote:
So far we have reused the name of the "platform" device for the CoreSight device. But this is not very intuitive when we move to ACPI. Also, the ACPI device names have ":" in them (e.g, ARMHC97C:01), which the perf tool doesn't like very much. This patch introduces a generic naming scheme, givin more intuitive
s/givin/"and gives"
names for the devices that appear on the CoreSight bus. The names follow the pattern "prefix" followed by "index" (e.g, etm5). We maintain a list of allocated devices per "prefix" to make sure we don't allocate a new name when it is reprobed (e.g, due to unsatisifed device dependencies). So, we maintain the list of "fwnodes" of the parent devices to allocate a consistent name. All devices except the ETMs get an index allocated in the order of probing. ETMs get an index based on the CPU they are attached to.
TMC devices are named using "tmc_etf", "tmc_etb", and "tmc_etr" prefixes depending on the configuration of the device.
The replicators are not classified as dynamic/static anymore. One could easily figure that out by checking the presence of "mgmt" registers under sysfs.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-catu.c | 7 ++- drivers/hwtracing/coresight/coresight-etb10.c | 7 ++- drivers/hwtracing/coresight/coresight-etm3x.c | 4 +- drivers/hwtracing/coresight/coresight-etm4x.c | 5 +- drivers/hwtracing/coresight/coresight-funnel.c | 7 ++- drivers/hwtracing/coresight/coresight-replicator.c | 7 ++- drivers/hwtracing/coresight/coresight-stm.c | 12 +++-- drivers/hwtracing/coresight/coresight-tmc.c | 15 +++++- drivers/hwtracing/coresight/coresight-tpiu.c | 7 ++- drivers/hwtracing/coresight/coresight.c | 58 ++++++++++++++++++++++ include/linux/coresight.h | 25 +++++++++- 11 files changed, 142 insertions(+), 12 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index f249be6..e0637fc 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -28,6 +28,8 @@ #define catu_dbg(x, ...) do {} while (0) #endif +DEFINE_CORESIGHT_DEVLIST(catu_devs, "catu");
struct catu_etr_buf { struct tmc_sg_table *catu_table; dma_addr_t sladdr; @@ -505,6 +507,10 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) struct device *dev = &adev->dev; void __iomem *base;
- catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
- if (!catu_desc.name)
return -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM;
@@ -551,7 +557,6 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) catu_desc.type = CORESIGHT_DEV_TYPE_HELPER; catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU; catu_desc.ops = &catu_ops;
- catu_desc.name = dev_name(dev);
drvdata->csdev = coresight_register(&catu_desc); if (IS_ERR(drvdata->csdev)) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index e5b46c7..8361b91 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -62,6 +62,8 @@ #define ETB_FFSR_BIT 1 #define ETB_FRAME_SIZE_WORDS 4 +DEFINE_CORESIGHT_DEVLIST(etb_devs, "etb");
/**
- struct etb_drvdata - specifics associated to an ETB component
- @base: memory mapped base address for this component.
@@ -682,6 +684,10 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- desc.name = coresight_alloc_device_name(&etb_devs, dev);
- if (!desc.name)
return -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -723,7 +729,6 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &etb_cs_ops; desc.pdata = pdata; desc.dev = dev;
- desc.name = dev_name(dev); desc.groups = coresight_etb_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev))
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index f2d4616..bed7291 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -815,6 +815,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) } drvdata->cpu = coresight_get_cpu(dev);
- desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu);
- if (!desc.name)
return -ENOMEM;
cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; @@ -856,7 +859,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &etm_cs_ops; desc.pdata = pdata; desc.dev = dev;
- desc.name = dev_name(dev); desc.groups = coresight_etm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 7c53fb2..5c13a04 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -993,6 +993,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock); drvdata->cpu = coresight_get_cpu(dev);
- desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu);
- if (!desc.name)
return -ENOMEM;
One newline too many.
With the above:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; @@ -1034,7 +1038,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_etmv4_groups;
- desc.name = dev_name(dev); drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev);
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 38af045..9b820b1 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -27,6 +27,8 @@ #define FUNNEL_HOLDTIME (0x7 << FUNNEL_HOLDTIME_SHFT) #define FUNNEL_ENSx_MASK 0xff +DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
/**
- struct funnel_drvdata - specifics associated to a funnel component
- @base: memory mapped base address for this component.
@@ -186,6 +188,10 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- desc.name = coresight_alloc_device_name(&funnel_devs, dev);
- if (!desc.name)
return -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -216,7 +222,6 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &funnel_cs_ops; desc.pdata = pdata; desc.dev = dev;
- desc.name = dev_name(dev); desc.groups = coresight_funnel_groups; drvdata->csdev = coresight_register(&desc);
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 8fbc028..2eb489c 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -22,6 +22,8 @@ #define REPLICATOR_IDFILTER0 0x000 #define REPLICATOR_IDFILTER1 0x004 +DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
/**
- struct replicator_drvdata - specifics associated to a replicator component
- @base: memory mapped base address for this component. Also indicates
@@ -179,6 +181,10 @@ static int replicator_probe(struct device *dev, struct resource *res) struct coresight_desc desc = { 0 }; void __iomem *base;
- desc.name = coresight_alloc_device_name(&replicator_devs, dev);
- if (!desc.name)
return -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -217,7 +223,6 @@ static int replicator_probe(struct device *dev, struct resource *res) desc.ops = &replicator_cs_ops; desc.pdata = dev->platform_data; desc.dev = dev;
- desc.name = dev_name(dev);
drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 5c7fc4a..2d6ae00 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -107,6 +107,8 @@ struct channel_space { unsigned long *guaranteed; }; +DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
/**
- struct stm_drvdata - specifics associated to an STM component
- @base: memory mapped base address for this component.
@@ -810,6 +812,10 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) size_t bitmap_size; struct coresight_desc desc = { 0 };
- desc.name = coresight_alloc_device_name(&stm_devs, dev);
- if (!desc.name)
return -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -854,11 +860,12 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock); stm_init_default_data(drvdata);
- stm_init_generic_data(drvdata, dev_name(dev));
- stm_init_generic_data(drvdata, desc.name);
if (stm_register_device(dev, &drvdata->stm, THIS_MODULE)) { dev_info(dev,
"stm_register_device failed, probing deferred\n");
"%s : stm_register_device failed, probing deferred\n",
return -EPROBE_DEFER; }desc.name);
@@ -874,7 +881,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &stm_cs_ops; desc.pdata = pdata; desc.dev = dev;
- desc.name = dev_name(dev); desc.groups = coresight_stm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) {
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 94d3ebf..8b7b5d0 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -25,6 +25,10 @@ #include "coresight-priv.h" #include "coresight-tmc.h" +DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb"); +DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf"); +DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata) { /* Ensure formatter, unformatter and hardware fifo are empty */ @@ -395,6 +399,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct tmc_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- struct coresight_dev_list *dev_list = NULL;
ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); @@ -425,13 +430,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.dev = dev; desc.groups = coresight_tmc_groups;
- desc.name = dev_name(dev);
switch (drvdata->config_type) { case TMC_CONFIG_TYPE_ETB: desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etb_cs_ops;
break; case TMC_CONFIG_TYPE_ETR: desc.type = CORESIGHT_DEV_TYPE_SINK;dev_list = &etb_devs;
@@ -441,11 +446,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) coresight_get_uci_data(id)); if (ret) goto out;
break; case TMC_CONFIG_TYPE_ETF: desc.type = CORESIGHT_DEV_TYPE_LINKSINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; desc.ops = &tmc_etf_cs_ops;dev_list = &etr_devs;
break; default: pr_err("%s: Unsupported TMC config\n", desc.name);dev_list = &etf_devs;
@@ -453,6 +460,12 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
- desc.name = coresight_alloc_device_name(dev_list, dev);
- if (!desc.name) {
ret = -ENOMEM;
goto out;
- }
- pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) { ret = PTR_ERR(pdata);
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 39a509f..0404434 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -46,6 +46,8 @@ #define FFCR_FON_MAN BIT(6) #define FFCR_STOP_FI BIT(12) +DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu");
/**
- @base: memory mapped base address for this component.
- @dev: the device entity associated to this component.
@@ -121,6 +123,10 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
- desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
- if (!desc.name)
return -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
@@ -153,7 +159,6 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &tpiu_cs_ops; desc.pdata = pdata; desc.dev = dev;
- desc.name = dev_name(dev); drvdata->csdev = coresight_register(&desc);
if (!IS_ERR(drvdata->csdev)) { diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 5169ce1..e3b9321 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1289,3 +1289,61 @@ void coresight_unregister(struct coresight_device *csdev) device_unregister(&csdev->dev); } EXPORT_SYMBOL_GPL(coresight_unregister);
+/*
- coresight_search_device_idx - Search the fwnode handle of a device
- in the given dev_idx list. Must be called with the coresight_mutex held.
- Returns the index of the entry, when found. Otherwise, -ENOENT.
- */
+static inline int coresight_search_device_idx(struct coresight_dev_list *dict,
struct fwnode_handle *fwnode)
+{
- int i;
- for (i = 0; i < dict->nr_idx; i++)
if (dict->fwnode_list[i] == fwnode)
return i;
- return -ENOENT;
+}
+/*
- coresight_alloc_device_name - Get an index for a given device in the
- device index list specific to a driver. An index is allocated for a
- device and is tracked with the fwnode_handle to prevent allocating
- duplicate indices for the same device (e.g, if we defer probing of
- a device due to dependencies), in case the index is requested again.
- */
+char *coresight_alloc_device_name(struct coresight_dev_list *dict,
struct device *dev)
+{
- int idx;
- char *name = NULL;
- struct fwnode_handle **list;
- mutex_lock(&coresight_mutex);
- idx = coresight_search_device_idx(dict, dev_fwnode(dev));
- if (idx < 0) {
/* Make space for the new entry */
idx = dict->nr_idx;
list = krealloc(dict->fwnode_list,
(idx + 1) * sizeof(*dict->fwnode_list),
GFP_KERNEL);
if (ZERO_OR_NULL_PTR(list)) {
idx = -ENOMEM;
goto done;
}
list[idx] = dev_fwnode(dev);
dict->fwnode_list = list;
dict->nr_idx = idx + 1;
- }
- name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", dict->pfx, idx);
+done:
- mutex_unlock(&coresight_mutex);
- return name;
+} +EXPORT_SYMBOL_GPL(coresight_alloc_device_name); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 188e759..d6367a0 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -168,6 +168,28 @@ struct coresight_device { struct dev_ext_attribute *ea; }; +/*
- coresight_dev_list - Mapping for devices to "name" index for device
- names.
- @nr_idx: Number of entries already allocated.
- @pfx: Prefix pattern for device name.
- @fwnode_list: Array of fwnode_handles associated with each allocated
index, upto nr_idx entries.
- */
+struct coresight_dev_list {
- int nr_idx;
- const char *pfx;
- struct fwnode_handle **fwnode_list;
+};
+#define DEFINE_CORESIGHT_DEVLIST(var, dev_pfx) \ +static struct coresight_dev_list (var) = { \
.pfx = dev_pfx, \
.nr_idx = 0, \
.fwnode_list = NULL, \
+}
#define to_coresight_device(d) container_of(d, struct coresight_device, dev) #define source_ops(csdev) csdev->ops->source_ops @@ -260,7 +282,8 @@ extern int coresight_claim_device_unlocked(void __iomem *base); extern void coresight_disclaim_device(void __iomem *base); extern void coresight_disclaim_device_unlocked(void __iomem *base);
+extern char *coresight_alloc_device_name(struct coresight_dev_list *devs,
struct device *dev);
#else static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; } -- 2.7.4
The stimulus base for STM device must be listed as the second memory resource, followed by the programming base address as described in "Section 2.3 Resources" in ACPI for CoreSightTM 1.0 Platform Design documen (DEN0067).
Add support for parsing the information for ACPI.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-stm.c | 43 +++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 2d6ae00..7cf2fe4 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -16,6 +16,7 @@ * (C) 2015-2016 Chunyan Zhang zhang.chunyan@linaro.org */ #include <asm/local.h> +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/bitmap.h> #include <linux/clk.h> @@ -716,10 +717,52 @@ static inline int of_stm_get_stimulus_area(struct device *dev, } #endif
+#ifdef CONFIG_ACPI +static int acpi_stm_get_stimulus_area(struct device *dev, struct resource *res) +{ + int rc; + bool found_base = false; + struct resource_entry *rent; + LIST_HEAD(res_list); + + struct acpi_device *adev = ACPI_COMPANION(dev); + + if (!adev) + return -ENODEV; + rc = acpi_dev_get_resources(adev, &res_list, NULL, NULL); + if (rc < 0) + return rc; + + rc = -ENOENT; + list_for_each_entry(rent, &res_list, node) { + if (resource_type(rent->res) != IORESOURCE_MEM) + continue; + if (found_base) { + *res = *rent->res; + rc = 0; + break; + } + + found_base = true; + } + + acpi_dev_free_resource_list(&res_list); + return rc; +} +#else +static inline int acpi_stm_get_stimulus_area(struct device *dev, + struct resource *res) +{ + return -ENOENT; +} +#endif + static int stm_get_stimulus_area(struct device *dev, struct resource *res) { if (dev->of_node) return of_stm_get_stimulus_area(dev, res); + else if (is_acpi_node(dev->fwnode)) + return acpi_stm_get_stimulus_area(dev, res); return -ENOENT; }
On Mon, Apr 15, 2019 at 05:04:14PM +0100, Suzuki K Poulose wrote:
The stimulus base for STM device must be listed as the second memory resource, followed by the programming base address as described in "Section 2.3 Resources" in ACPI for CoreSightTM 1.0 Platform Design documen (DEN0067).
Thank you for adding more information.
Add support for parsing the information for ACPI.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-stm.c | 43 +++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 2d6ae00..7cf2fe4 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -16,6 +16,7 @@
- (C) 2015-2016 Chunyan Zhang zhang.chunyan@linaro.org
*/ #include <asm/local.h> +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/bitmap.h> #include <linux/clk.h> @@ -716,10 +717,52 @@ static inline int of_stm_get_stimulus_area(struct device *dev, } #endif +#ifdef CONFIG_ACPI +static int acpi_stm_get_stimulus_area(struct device *dev, struct resource *res) +{
- int rc;
- bool found_base = false;
- struct resource_entry *rent;
- LIST_HEAD(res_list);
- struct acpi_device *adev = ACPI_COMPANION(dev);
- if (!adev)
return -ENODEV;
- rc = acpi_dev_get_resources(adev, &res_list, NULL, NULL);
- if (rc < 0)
return rc;
- rc = -ENOENT;
- list_for_each_entry(rent, &res_list, node) {
if (resource_type(rent->res) != IORESOURCE_MEM)
continue;
if (found_base) {
*res = *rent->res;
rc = 0;
break;
}
found_base = true;
- }
I would copy the description in the changelog just before the list_for_each_entry() loop.
- acpi_dev_free_resource_list(&res_list);
- return rc;
+} +#else +static inline int acpi_stm_get_stimulus_area(struct device *dev,
struct resource *res)
+{
- return -ENOENT;
+} +#endif
static int stm_get_stimulus_area(struct device *dev, struct resource *res) { if (dev->of_node)
I noticed the direct access of ->of_node in patch 16 and thought it was a little odd that is_of_node() wasn't used.
return of_stm_get_stimulus_area(dev, res);
- else if (is_acpi_node(dev->fwnode))
return -ENOENT;return acpi_stm_get_stimulus_area(dev, res);
With the above:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
} -- 2.7.4
On 23/04/2019 18:59, Mathieu Poirier wrote:
On Mon, Apr 15, 2019 at 05:04:14PM +0100, Suzuki K Poulose wrote:
The stimulus base for STM device must be listed as the second memory resource, followed by the programming base address as described in "Section 2.3 Resources" in ACPI for CoreSightTM 1.0 Platform Design documen (DEN0067).
Thank you for adding more information.
Add support for parsing the information for ACPI.
I would copy the description in the changelog just before the list_for_each_entry() loop.
static int stm_get_stimulus_area(struct device *dev, struct resource *res) { if (dev->of_node)
I noticed the direct access of ->of_node in patch 16 and thought it was a little odd that is_of_node() wasn't used.
return of_stm_get_stimulus_area(dev, res);
- else if (is_acpi_node(dev->fwnode))
return -ENOENT;return acpi_stm_get_stimulus_area(dev, res);
With the above:
Both addressed.
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
Thanks ! Suzuki
Add support for parsing the ACPI platform description for CoreSight. The connections are encoded in a DSD graph property with CoreSight specific variation of the property.
The ETMs are listed as the children device of the respective CPU.
Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 409 +++++++++++++++++++++++ 1 file changed, 409 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index c9a59fb..224f698 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -3,6 +3,7 @@ * Copyright (c) 2012, The Linux Foundation. All rights reserved. */
+#include <linux/acpi.h> #include <linux/types.h> #include <linux/err.h> #include <linux/slab.h> @@ -297,10 +298,414 @@ of_get_coresight_platform_data(struct device *dev, } #endif
+#ifdef CONFIG_ACPI + +#include <acpi/actypes.h> +#include <acpi/processor.h> + +/* ACPI Graph _DSD UUID : "ab02a46b-74c7-45a2-bd68-f7d344ef2153" */ +static const guid_t acpi_graph_uuid = GUID_INIT(0xab02a46b, 0x74c7, 0x45a2, + 0xbd, 0x68, 0xf7, 0xd3, + 0x44, 0xef, 0x21, 0x53); +/* Coresight ACPI Graph UUID : "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" */ +static const guid_t coresight_graph_uuid = GUID_INIT(0x3ecbc8b6, 0x1d0e, 0x4fb3, + 0x81, 0x07, 0xe6, 0x27, + 0xf8, 0x05, 0xc6, 0xcd); +#define ACPI_CORESIGHT_LINK_SLAVE 0 +#define ACPI_CORESIGHT_LINK_MASTER 1 + +static inline bool is_acpi_guid(const union acpi_object *obj) +{ + return (obj->type == ACPI_TYPE_BUFFER) && (obj->buffer.length == 16); +} + +/* + * acpi_guid_matches - Checks if the given object is a GUID object and + * that it matches the supplied the GUID. + */ +static inline bool acpi_guid_matches(const union acpi_object *obj, + const guid_t *guid) +{ + return is_acpi_guid(obj) && + guid_equal((guid_t *)obj->buffer.pointer, guid); +} + +static inline bool is_acpi_dsd_graph_guid(const union acpi_object *obj) +{ + return acpi_guid_matches(obj, &acpi_graph_uuid); +} + +static inline bool is_acpi_coresight_graph_guid(const union acpi_object *obj) +{ + return acpi_guid_matches(obj, &coresight_graph_uuid); +} + +static inline bool is_acpi_coresight_graph(const union acpi_object *obj) +{ + const union acpi_object *graphid, *guid, *links; + + if (obj->type != ACPI_TYPE_PACKAGE || + obj->package.count < 3) + return false; + + graphid = &obj->package.elements[0]; + guid = &obj->package.elements[1]; + links = &obj->package.elements[2]; + + if (graphid->type != ACPI_TYPE_INTEGER || + links->type != ACPI_TYPE_INTEGER) + return false; + + return is_acpi_coresight_graph_guid(guid); +} + +/* + * acpi_validate_dsd_graph - Make sure the given _DSD graph conforms + * to the ACPI _DSD Graph specification. + * + * ACPI Devices Graph property has the following format: + * Revision - Integer, must be 0 + * NumberOfGraphs - Integer, N indicating the following list. + * Graph[1], + * ... + * Graph[N] + * + * And each Graph entry has the following format: + * GraphID - Integer, identifying a graph the device belongs to. + * UUID - UUID identifying the specification that governs + * this graph. (e.g, see is_acpi_coresight_graph()) + * NumberOfLinks - Number "N" of connections on this node of the graph. + * Links[1] + * ... + * Links[N] + */ +static inline bool acpi_validate_dsd_graph(const union acpi_object *graph) +{ + int i, n; + const union acpi_object *rev, *nr_graphs; + + /* The graph must contain at least the Revision and Number of Graphs */ + if (graph->package.count < 2) + return false; + + rev = &graph->package.elements[0]; + nr_graphs = &graph->package.elements[1]; + + if (rev->type != ACPI_TYPE_INTEGER || + nr_graphs->type != ACPI_TYPE_INTEGER) + return false; + + /* We only support revision 0 */ + if (rev->integer.value != 0) + return false; + + n = nr_graphs->integer.value; + /* Make sure the package has right number of elements */ + if (graph->package.count != (n + 2)) + return false; + + /* Each entry must be a graph package with at least 3 members */ + for (i = 2; i < n + 2; i++) { + const union acpi_object *obj = &graph->package.elements[i]; + + if (obj->type != ACPI_TYPE_PACKAGE || + obj->package.count < 3) + return false; + } + + return true; +} + +/* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */ +const union acpi_object * +acpi_get_dsd_graph(struct acpi_device *adev) +{ + int i; + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; + acpi_status status; + const union acpi_object *dsd; + + status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, + &buf, ACPI_TYPE_PACKAGE); + if (ACPI_FAILURE(status)) + return NULL; + + dsd = buf.pointer; + for (i = 0; i + 1 < dsd->package.count; i += 2) { + const union acpi_object *guid, *package; + + guid = &dsd->package.elements[i]; + package = &dsd->package.elements[i + 1]; + + /* All _DSD elements must have a UUID and a Package */ + if (!is_acpi_guid(guid) || package->type != ACPI_TYPE_PACKAGE) + break; + /* Skip the non-Graph _DSD packages */ + if (!is_acpi_dsd_graph_guid(guid)) + continue; + if (acpi_validate_dsd_graph(package)) + return package; + /* Invalid graph format, continue */ + dev_warn(&adev->dev, "Invalid Graph _DSD property\n"); + } + + return NULL; +} + +static inline bool +acpi_validate_coresight_graph(const union acpi_object *cs_graph) +{ + int nlinks; + + nlinks = cs_graph->package.elements[2].integer.value; + if (cs_graph->package.count != (nlinks + 3)) + return false; + /* The links are validated in acpi_coresight_parse_link() */ + return true; +} + +/* + * acpi_get_coresight_graph - Parse the device _DSD tables and find + * the Graph property matching the CoreSight Graphs. + * + * Returns the pointer to the CoreSight Graph Package when found. Otherwise + * returns NULL. + */ +const union acpi_object * +acpi_get_coresight_graph(struct acpi_device *adev) +{ + const union acpi_object *graph_list, *graph; + int i, nr_graphs; + + graph_list = acpi_get_dsd_graph(adev); + if (!graph_list) + return graph_list; + + nr_graphs = graph_list->package.elements[1].integer.value; + + for (i = 2; i < nr_graphs + 2; i++) { + graph = &graph_list->package.elements[i]; + if (!is_acpi_coresight_graph(graph)) + continue; + if (acpi_validate_coresight_graph(graph)) + return graph; + /* Invalid graph format */ + break; + } + + return NULL; +} + +/* + * acpi_coresight_parse_link - Parse the given Graph connection + * of the device and populate the coresight_connection for an output + * connection. + * + * CoreSight Graph specification mandates that the direction of the data + * flow must be specified in the link. i.e, + * + * SourcePortAddress, // Integer + * DestinationPortAddress, // Integer + * DestinationDeviceName, // Reference to another device + * DirectionOfFlow, // 1 for output(master), 0 for input(slave) + * + * Returns the direction of the data flow [ Input(slave) or Output(master) ] + * upon success. + * Returns an negative error number otherwise. + */ +static int acpi_coresight_parse_link(struct acpi_device *adev, + const union acpi_object *link, + struct coresight_connection *conn) +{ + int rc, dir; + const union acpi_object *fields; + struct acpi_device *r_adev; + struct device *rdev; + + if (link->type != ACPI_TYPE_PACKAGE || + link->package.count != 4) + return -EINVAL; + + fields = link->package.elements; + + if (fields[0].type != ACPI_TYPE_INTEGER || + fields[1].type != ACPI_TYPE_INTEGER || + fields[2].type != ACPI_TYPE_LOCAL_REFERENCE || + fields[3].type != ACPI_TYPE_INTEGER) + return -EINVAL; + + rc = acpi_bus_get_device(fields[2].reference.handle, &r_adev); + if (rc) + return rc; + + dir = fields[3].integer.value; + if (dir == ACPI_CORESIGHT_LINK_MASTER) { + conn->outport = fields[0].integer.value; + conn->child_port = fields[1].integer.value; + rdev = coresight_find_device_by_fwnode(&r_adev->fwnode); + if (!rdev) + return -EPROBE_DEFER; + /* + * Hold the refcount to the target device. This could be + * released via: + * 1) coresight_release_platform_data() if the probe fails or + * this device is unregistered. + * 2) While removing the target device via + * coresight_remove_match(). + */ + conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode); + } + + return dir; +} + +/* + * acpi_coresight_parse_graph - Parse the _DSD CoreSight graph + * connection information and populate the supplied coresight_platform_data + * instance. + */ +static int acpi_coresight_parse_graph(struct acpi_device *adev, + struct coresight_platform_data *pdata) +{ + int rc, i, nlinks; + const union acpi_object *graph; + struct coresight_connection *conns, *ptr; + + pdata->nr_inport = pdata->nr_outport = 0; + graph = acpi_get_coresight_graph(adev); + if (!graph) + return -ENOENT; + + nlinks = graph->package.elements[2].integer.value; + if (!nlinks) + return 0; + + /* + * To avoid scanning the table twice (once for finding the number of + * output links and then later for parsing the output links), + * cache the links information in one go and then later copy + * it to the pdata. + */ + conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL); + if (!conns) + return -ENOMEM; + ptr = conns; + for (i = 0; i < nlinks; i++) { + const union acpi_object *link = &graph->package.elements[3 + i]; + int dir; + + dir = acpi_coresight_parse_link(adev, link, ptr); + if (dir < 0) + return dir; + + if (dir == ACPI_CORESIGHT_LINK_MASTER) { + pdata->nr_outport++; + ptr++; + } else { + pdata->nr_inport++; + } + } + + rc = coresight_alloc_conns(&adev->dev, pdata); + if (rc) + return rc; + + /* Copy the connection information to the final location */ + for (i = 0; i < pdata->nr_outport; i++) + pdata->conns[i] = conns[i]; + + devm_kfree(&adev->dev, conns); + return 0; +} + +/* + * acpi_handle_to_logical_cpuid - Map a given acpi_handle to the + * logical CPU id of the corresponding CPU device. + * + * Returns the logical CPU id when found. Otherwise returns >= nr_cpus_id. + */ +static int +acpi_handle_to_logical_cpuid(acpi_handle handle) +{ + int i; + struct acpi_processor *pr; + + for_each_possible_cpu(i) { + pr = per_cpu(processors, i); + if (pr && pr->handle == handle) + break; + } + + return i; +} + +/* + * acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated + * with this coresight device. With ACPI bindings, the CoreSight components + * are listed as child device of the associated CPU. + * + * Returns the logical CPU id when found. Otherwise returns < 0. + */ +static int acpi_coresight_get_cpu(struct device *dev) +{ + int cpu; + acpi_handle cpu_handle; + acpi_status status; + struct acpi_device *adev = ACPI_COMPANION(dev); + + if (!adev) + return 0; + status = acpi_get_parent(adev->handle, &cpu_handle); + if (ACPI_FAILURE(status)) + return 0; + + cpu = acpi_handle_to_logical_cpuid(cpu_handle); + if (cpu >= nr_cpu_ids) + return 0; + return cpu; +} + +static struct coresight_platform_data * +acpi_get_coresight_platform_data(struct device *dev, + struct coresight_platform_data *pdata) +{ + int rc = -EINVAL; + struct acpi_device *adev; + + adev = ACPI_COMPANION(dev); + if (!adev) + goto out; + + rc = acpi_coresight_parse_graph(adev, pdata); + if (rc) + goto out; +out: + if (rc) + return ERR_PTR(rc); + return pdata; +} + +#else + +static inline struct coresight_platform_data * +acpi_get_coresight_platform_data(struct device *dev, + struct coresight_platform_data *pdata) +{ + return NULL; +} + +static inline int acpi_coresight_get_cpu(struct device *dev) +{ + return 0; +} +#endif + int coresight_get_cpu(struct device *dev) { if (is_of_node(dev->fwnode)) return of_coresight_get_cpu(dev); + else if (is_acpi_device_node(dev->fwnode)) + return acpi_coresight_get_cpu(dev); return 0; } EXPORT_SYMBOL_GPL(coresight_get_cpu); @@ -320,6 +725,10 @@ coresight_get_platform_data(struct device *dev)
if (is_of_node(fwnode)) ret = of_get_coresight_platform_data(dev, pdata); + else if (is_acpi_device_node(fwnode)) + ret = acpi_get_coresight_platform_data(dev, pdata); + else + return ERR_PTR(-ENOENT);
if (!IS_ERR_OR_NULL(ret)) return pdata;
On Mon, Apr 15, 2019 at 05:04:15PM +0100, Suzuki K Poulose wrote:
Add support for parsing the ACPI platform description for CoreSight. The connections are encoded in a DSD graph property with CoreSight specific variation of the property.
The ETMs are listed as the children device of the respective CPU.
Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-platform.c | 409 +++++++++++++++++++++++ 1 file changed, 409 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index c9a59fb..224f698 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -3,6 +3,7 @@
- Copyright (c) 2012, The Linux Foundation. All rights reserved.
*/ +#include <linux/acpi.h> #include <linux/types.h> #include <linux/err.h> #include <linux/slab.h> @@ -297,10 +298,414 @@ of_get_coresight_platform_data(struct device *dev, } #endif +#ifdef CONFIG_ACPI
+#include <acpi/actypes.h> +#include <acpi/processor.h>
+/* ACPI Graph _DSD UUID : "ab02a46b-74c7-45a2-bd68-f7d344ef2153" */ +static const guid_t acpi_graph_uuid = GUID_INIT(0xab02a46b, 0x74c7, 0x45a2,
0xbd, 0x68, 0xf7, 0xd3,
0x44, 0xef, 0x21, 0x53);
+/* Coresight ACPI Graph UUID : "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" */ +static const guid_t coresight_graph_uuid = GUID_INIT(0x3ecbc8b6, 0x1d0e, 0x4fb3,
0x81, 0x07, 0xe6, 0x27,
0xf8, 0x05, 0xc6, 0xcd);
+#define ACPI_CORESIGHT_LINK_SLAVE 0 +#define ACPI_CORESIGHT_LINK_MASTER 1
+static inline bool is_acpi_guid(const union acpi_object *obj) +{
- return (obj->type == ACPI_TYPE_BUFFER) && (obj->buffer.length == 16);
+}
+/*
- acpi_guid_matches - Checks if the given object is a GUID object and
- that it matches the supplied the GUID.
- */
+static inline bool acpi_guid_matches(const union acpi_object *obj,
const guid_t *guid)
+{
- return is_acpi_guid(obj) &&
guid_equal((guid_t *)obj->buffer.pointer, guid);
+}
+static inline bool is_acpi_dsd_graph_guid(const union acpi_object *obj) +{
- return acpi_guid_matches(obj, &acpi_graph_uuid);
+}
+static inline bool is_acpi_coresight_graph_guid(const union acpi_object *obj) +{
- return acpi_guid_matches(obj, &coresight_graph_uuid);
+}
+static inline bool is_acpi_coresight_graph(const union acpi_object *obj) +{
- const union acpi_object *graphid, *guid, *links;
- if (obj->type != ACPI_TYPE_PACKAGE ||
obj->package.count < 3)
return false;
- graphid = &obj->package.elements[0];
- guid = &obj->package.elements[1];
- links = &obj->package.elements[2];
- if (graphid->type != ACPI_TYPE_INTEGER ||
links->type != ACPI_TYPE_INTEGER)
return false;
- return is_acpi_coresight_graph_guid(guid);
+}
+/*
- acpi_validate_dsd_graph - Make sure the given _DSD graph conforms
- to the ACPI _DSD Graph specification.
- ACPI Devices Graph property has the following format:
- Revision - Integer, must be 0
- NumberOfGraphs - Integer, N indicating the following list.
- Graph[1],
...
- Graph[N]
- And each Graph entry has the following format:
- GraphID - Integer, identifying a graph the device belongs to.
- UUID - UUID identifying the specification that governs
this graph. (e.g, see is_acpi_coresight_graph())
- NumberOfLinks - Number "N" of connections on this node of the graph.
- Links[1]
- ...
- Links[N]
- */
+static inline bool acpi_validate_dsd_graph(const union acpi_object *graph) +{
- int i, n;
- const union acpi_object *rev, *nr_graphs;
- /* The graph must contain at least the Revision and Number of Graphs */
- if (graph->package.count < 2)
return false;
- rev = &graph->package.elements[0];
- nr_graphs = &graph->package.elements[1];
- if (rev->type != ACPI_TYPE_INTEGER ||
nr_graphs->type != ACPI_TYPE_INTEGER)
return false;
- /* We only support revision 0 */
- if (rev->integer.value != 0)
return false;
- n = nr_graphs->integer.value;
- /* Make sure the package has right number of elements */
- if (graph->package.count != (n + 2))
return false;
- /* Each entry must be a graph package with at least 3 members */
Please mention what the 3 members must be to avoid having to go back to the specs all the time.
- for (i = 2; i < n + 2; i++) {
const union acpi_object *obj = &graph->package.elements[i];
if (obj->type != ACPI_TYPE_PACKAGE ||
obj->package.count < 3)
return false;
- }
- return true;
+}
+/* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */ +const union acpi_object * +acpi_get_dsd_graph(struct acpi_device *adev) +{
- int i;
- struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
- acpi_status status;
- const union acpi_object *dsd;
- status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
&buf, ACPI_TYPE_PACKAGE);
- if (ACPI_FAILURE(status))
return NULL;
- dsd = buf.pointer;
Please add a comment to mention that a _DSD package consists of tuples, i.e a UUID and a package to explain the += 2.
- for (i = 0; i + 1 < dsd->package.count; i += 2) {
const union acpi_object *guid, *package;
guid = &dsd->package.elements[i];
package = &dsd->package.elements[i + 1];
/* All _DSD elements must have a UUID and a Package */
if (!is_acpi_guid(guid) || package->type != ACPI_TYPE_PACKAGE)
break;
/* Skip the non-Graph _DSD packages */
if (!is_acpi_dsd_graph_guid(guid))
continue;
if (acpi_validate_dsd_graph(package))
return package;
/* Invalid graph format, continue */
dev_warn(&adev->dev, "Invalid Graph _DSD property\n");
- }
- return NULL;
+}
+static inline bool +acpi_validate_coresight_graph(const union acpi_object *cs_graph) +{
- int nlinks;
- nlinks = cs_graph->package.elements[2].integer.value;
As you did in acpi_validate_dsd_graph(), please add the rational for the + 3.
- if (cs_graph->package.count != (nlinks + 3))
return false;
- /* The links are validated in acpi_coresight_parse_link() */
- return true;
+}
+/*
- acpi_get_coresight_graph - Parse the device _DSD tables and find
- the Graph property matching the CoreSight Graphs.
- Returns the pointer to the CoreSight Graph Package when found. Otherwise
- returns NULL.
- */
+const union acpi_object * +acpi_get_coresight_graph(struct acpi_device *adev) +{
- const union acpi_object *graph_list, *graph;
- int i, nr_graphs;
- graph_list = acpi_get_dsd_graph(adev);
- if (!graph_list)
return graph_list;
- nr_graphs = graph_list->package.elements[1].integer.value;
In what kind of scenario nr_graphs would be more than 1? From what I've seen in DEN0067 and the implementation in patch 37 it shouldn't be the case. As such I would treat nr_graphs != 1 as an error.
I must admit I had a really hard time following the hard coded .element[] throughout the code. With time I was able to verify them all but it would really help if the example of an ACPI device description was given at the top of the file, just before the ACPI Graph UUID. The following taken from DEN0067 did the trick for me:
Device ( FUN1 ) { // Funnel 1 described in \SB scope Name (_HID , " ARMHC9FF ") Name (_CID , " ARMHC500 ") Name (_CRS , ResourceTemplate () { Memory32Fixed ( ReadWrite , 0 x208c0000 , 0 x1000 ) })
Name (_DSD , Package () { ToUUID (" ab02a46b -74 c7 -45a2 -bd68 - f7d344ef2153 ") , Package () { 0 , // Revision 1 , // Number of graphs Package () { 1 , // GraphID // CoreSight graphs UUID ToUUID ("3 ecbc8b6 -1 d0e -4 fb3 -8107 - e627f805c6cd ") , 3 , // Number of links Package () {0 , 0 , // output port 0 connected _SB.RPL0 ,1} , // to input port 0 on RPL0 . Package () {0 , 0 , // input port 0 connected _SB.ETF0 ,0} , // to output port 0 on ETF0 . Package () {1 , 0 , // input port 1 connected _SB.ETF1 ,0} // to output port 0 on ETF1 . } } })
- for (i = 2; i < nr_graphs + 2; i++) {
graph = &graph_list->package.elements[i];
if (!is_acpi_coresight_graph(graph))
continue;
if (acpi_validate_coresight_graph(graph))
return graph;
/* Invalid graph format */
break;
- }
- return NULL;
+}
+/*
- acpi_coresight_parse_link - Parse the given Graph connection
- of the device and populate the coresight_connection for an output
- connection.
- CoreSight Graph specification mandates that the direction of the data
- flow must be specified in the link. i.e,
- SourcePortAddress, // Integer
- DestinationPortAddress, // Integer
- DestinationDeviceName, // Reference to another device
- DirectionOfFlow, // 1 for output(master), 0 for input(slave)
- Returns the direction of the data flow [ Input(slave) or Output(master) ]
- upon success.
- Returns an negative error number otherwise.
- */
+static int acpi_coresight_parse_link(struct acpi_device *adev,
const union acpi_object *link,
struct coresight_connection *conn)
+{
- int rc, dir;
- const union acpi_object *fields;
- struct acpi_device *r_adev;
- struct device *rdev;
- if (link->type != ACPI_TYPE_PACKAGE ||
link->package.count != 4)
return -EINVAL;
- fields = link->package.elements;
- if (fields[0].type != ACPI_TYPE_INTEGER ||
fields[1].type != ACPI_TYPE_INTEGER ||
fields[2].type != ACPI_TYPE_LOCAL_REFERENCE ||
fields[3].type != ACPI_TYPE_INTEGER)
return -EINVAL;
- rc = acpi_bus_get_device(fields[2].reference.handle, &r_adev);
- if (rc)
return rc;
- dir = fields[3].integer.value;
- if (dir == ACPI_CORESIGHT_LINK_MASTER) {
conn->outport = fields[0].integer.value;
conn->child_port = fields[1].integer.value;
rdev = coresight_find_device_by_fwnode(&r_adev->fwnode);
if (!rdev)
return -EPROBE_DEFER;
/*
* Hold the refcount to the target device. This could be
* released via:
* 1) coresight_release_platform_data() if the probe fails or
* this device is unregistered.
* 2) While removing the target device via
* coresight_remove_match().
*/
conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode);
- }
- return dir;
+}
+/*
- acpi_coresight_parse_graph - Parse the _DSD CoreSight graph
- connection information and populate the supplied coresight_platform_data
- instance.
- */
+static int acpi_coresight_parse_graph(struct acpi_device *adev,
struct coresight_platform_data *pdata)
+{
- int rc, i, nlinks;
- const union acpi_object *graph;
- struct coresight_connection *conns, *ptr;
- pdata->nr_inport = pdata->nr_outport = 0;
- graph = acpi_get_coresight_graph(adev);
- if (!graph)
return -ENOENT;
- nlinks = graph->package.elements[2].integer.value;
- if (!nlinks)
return 0;
- /*
* To avoid scanning the table twice (once for finding the number of
* output links and then later for parsing the output links),
* cache the links information in one go and then later copy
* it to the pdata.
*/
- conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL);
- if (!conns)
return -ENOMEM;
- ptr = conns;
- for (i = 0; i < nlinks; i++) {
const union acpi_object *link = &graph->package.elements[3 + i];
int dir;
dir = acpi_coresight_parse_link(adev, link, ptr);
if (dir < 0)
return dir;
if (dir == ACPI_CORESIGHT_LINK_MASTER) {
pdata->nr_outport++;
ptr++;
} else {
pdata->nr_inport++;
}
- }
- rc = coresight_alloc_conns(&adev->dev, pdata);
- if (rc)
return rc;
- /* Copy the connection information to the final location */
- for (i = 0; i < pdata->nr_outport; i++)
pdata->conns[i] = conns[i];
- devm_kfree(&adev->dev, conns);
- return 0;
+}
+/*
- acpi_handle_to_logical_cpuid - Map a given acpi_handle to the
- logical CPU id of the corresponding CPU device.
- Returns the logical CPU id when found. Otherwise returns >= nr_cpus_id.
- */
+static int +acpi_handle_to_logical_cpuid(acpi_handle handle) +{
- int i;
- struct acpi_processor *pr;
- for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
if (pr && pr->handle == handle)
break;
- }
- return i;
+}
+/*
- acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated
- with this coresight device. With ACPI bindings, the CoreSight components
- are listed as child device of the associated CPU.
- Returns the logical CPU id when found. Otherwise returns < 0.
As far as I can tell this function can't return < 0.
- */
+static int acpi_coresight_get_cpu(struct device *dev) +{
- int cpu;
- acpi_handle cpu_handle;
- acpi_status status;
- struct acpi_device *adev = ACPI_COMPANION(dev);
- if (!adev)
return 0;
- status = acpi_get_parent(adev->handle, &cpu_handle);
- if (ACPI_FAILURE(status))
return 0;
- cpu = acpi_handle_to_logical_cpuid(cpu_handle);
- if (cpu >= nr_cpu_ids)
return 0;
- return cpu;
+}
+static struct coresight_platform_data * +acpi_get_coresight_platform_data(struct device *dev,
struct coresight_platform_data *pdata)
+{
- int rc = -EINVAL;
- struct acpi_device *adev;
- adev = ACPI_COMPANION(dev);
- if (!adev)
goto out;
- rc = acpi_coresight_parse_graph(adev, pdata);
- if (rc)
goto out;
The goto statement is not needed here.
+out:
- if (rc)
return ERR_PTR(rc);
- return pdata;
+}
+#else
+static inline struct coresight_platform_data * +acpi_get_coresight_platform_data(struct device *dev,
struct coresight_platform_data *pdata)
+{
- return NULL;
+}
+static inline int acpi_coresight_get_cpu(struct device *dev) +{
- return 0;
+} +#endif
Function of_coresight_get_cpu() and of_get_coresight_platform_data() will also need a stub if CONFIG_OF=n.
int coresight_get_cpu(struct device *dev) { if (is_of_node(dev->fwnode)) return of_coresight_get_cpu(dev);
- else if (is_acpi_device_node(dev->fwnode))
return 0;return acpi_coresight_get_cpu(dev);
} EXPORT_SYMBOL_GPL(coresight_get_cpu); @@ -320,6 +725,10 @@ coresight_get_platform_data(struct device *dev) if (is_of_node(fwnode)) ret = of_get_coresight_platform_data(dev, pdata);
- else if (is_acpi_device_node(fwnode))
ret = acpi_get_coresight_platform_data(dev, pdata);
- else
return ERR_PTR(-ENOENT);
if (!IS_ERR_OR_NULL(ret)) return pdata; -- 2.7.4
On 25/04/2019 17:50, Mathieu Poirier wrote:
On Mon, Apr 15, 2019 at 05:04:15PM +0100, Suzuki K Poulose wrote:
Add support for parsing the ACPI platform description for CoreSight. The connections are encoded in a DSD graph property with CoreSight specific variation of the property.
The ETMs are listed as the children device of the respective CPU.
Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
...
+/*
- acpi_validate_dsd_graph - Make sure the given _DSD graph conforms
- to the ACPI _DSD Graph specification.
- ACPI Devices Graph property has the following format:
- Revision - Integer, must be 0
- NumberOfGraphs - Integer, N indicating the following list.
- Graph[1],
...
- Graph[N]
- And each Graph entry has the following format:
- GraphID - Integer, identifying a graph the device belongs to.
- UUID - UUID identifying the specification that governs
this graph. (e.g, see is_acpi_coresight_graph())
- NumberOfLinks - Number "N" of connections on this node of the graph.
- Links[1]
- ...
- Links[N]
- */
+static inline bool acpi_validate_dsd_graph(const union acpi_object *graph) +{
- int i, n;
- const union acpi_object *rev, *nr_graphs;
- /* The graph must contain at least the Revision and Number of Graphs */
- if (graph->package.count < 2)
return false;
- rev = &graph->package.elements[0];
- nr_graphs = &graph->package.elements[1];
- if (rev->type != ACPI_TYPE_INTEGER ||
nr_graphs->type != ACPI_TYPE_INTEGER)
return false;
- /* We only support revision 0 */
- if (rev->integer.value != 0)
return false;
- n = nr_graphs->integer.value;
- /* Make sure the package has right number of elements */
- if (graph->package.count != (n + 2))
return false;
- /* Each entry must be a graph package with at least 3 members */
Please mention what the 3 members must be to avoid having to go back to the specs all the time.
Actually this is explained in the comment above. Graph entry contains : GraphID, UUID and number of links. I could add make it explicit here, just like I did it for the "Revision and Number of Graphs" above.
- for (i = 2; i < n + 2; i++) {
const union acpi_object *obj = &graph->package.elements[i];
if (obj->type != ACPI_TYPE_PACKAGE ||
obj->package.count < 3)
return false;
- }
- return true;
+}
+/* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */ +const union acpi_object * +acpi_get_dsd_graph(struct acpi_device *adev) +{
- int i;
- struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
- acpi_status status;
- const union acpi_object *dsd;
- status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
&buf, ACPI_TYPE_PACKAGE);
- if (ACPI_FAILURE(status))
return NULL;
- dsd = buf.pointer;
Please add a comment to mention that a _DSD package consists of tuples, i.e a UUID and a package to explain the += 2.
Sure, it took me a while to figure that out myself.
+static inline bool +acpi_validate_coresight_graph(const union acpi_object *cs_graph) +{
- int nlinks;
- nlinks = cs_graph->package.elements[2].integer.value;
As you did in acpi_validate_dsd_graph(), please add the rational for the + 3.
Sure.
- if (cs_graph->package.count != (nlinks + 3))
return false;
- /* The links are validated in acpi_coresight_parse_link() */
- return true;
+}
+/*
- acpi_get_coresight_graph - Parse the device _DSD tables and find
- the Graph property matching the CoreSight Graphs.
- Returns the pointer to the CoreSight Graph Package when found. Otherwise
- returns NULL.
- */
+const union acpi_object * +acpi_get_coresight_graph(struct acpi_device *adev) +{
- const union acpi_object *graph_list, *graph;
- int i, nr_graphs;
- graph_list = acpi_get_dsd_graph(adev);
- if (!graph_list)
return graph_list;
- nr_graphs = graph_list->package.elements[1].integer.value;
In what kind of scenario nr_graphs would be more than 1? From what I've seen in DEN0067 and the implementation in patch 37 it shouldn't be the case. As such I would treat nr_graphs != 1 as an error.
The device could be part of multiple graphs theoretically. However, for CoreSight we have only one graph, which shows the ATB connections. I could enforce that here.
I must admit I had a really hard time following the hard coded .element[] throughout the code. With time I was able to verify them all but it would really help if the example of an ACPI device description was given at the top of the file, just before the ACPI Graph UUID. The following taken from DEN0067 did the trick for me:
I understand the pain. It is indeed a bit tricky. I will add an example graph property.
Device ( FUN1 ) { // Funnel 1 described in \SB scope Name (_HID , " ARMHC9FF ") Name (_CID , " ARMHC500 ") Name (_CRS , ResourceTemplate () { Memory32Fixed ( ReadWrite , 0 x208c0000 , 0 x1000 ) })
Name (_DSD , Package () { ToUUID (" ab02a46b -74 c7 -45a2 -bd68 - f7d344ef2153 ") , Package () { 0 , // Revision 1 , // Number of graphs Package () { 1 , // GraphID // CoreSight graphs UUID ToUUID ("3 ecbc8b6 -1 d0e -4 fb3 -8107 - e627f805c6cd ") , 3 , // Number of links Package () {0 , 0 , // output port 0 connected _SB.RPL0 ,1} , // to input port 0 on RPL0 . Package () {0 , 0 , // input port 0 connected _SB.ETF0 ,0} , // to output port 0 on ETF0 . Package () {1 , 0 , // input port 1 connected _SB.ETF1 ,0} // to output port 0 on ETF1 . } } })
...
+/*
- acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated
- with this coresight device. With ACPI bindings, the CoreSight components
- are listed as child device of the associated CPU.
- Returns the logical CPU id when found. Otherwise returns < 0.
As far as I can tell this function can't return < 0.
You're right. I will fix the comment.
+static struct coresight_platform_data * +acpi_get_coresight_platform_data(struct device *dev,
struct coresight_platform_data *pdata)
+{
- int rc = -EINVAL;
- struct acpi_device *adev;
- adev = ACPI_COMPANION(dev);
- if (!adev)
goto out;
- rc = acpi_coresight_parse_graph(adev, pdata);
- if (rc)
goto out;
The goto statement is not needed here.
OK
+out:
- if (rc)
return ERR_PTR(rc);
- return pdata;
+}
+#else
+static inline struct coresight_platform_data * +acpi_get_coresight_platform_data(struct device *dev,
struct coresight_platform_data *pdata)
+{
- return NULL;
+}
+static inline int acpi_coresight_get_cpu(struct device *dev) +{
- return 0;
+} +#endif
Function of_coresight_get_cpu() and of_get_coresight_platform_data() will also need a stub if CONFIG_OF=n.
Yep, agreed.
Thank you so much for the review ! Suzuki
All AMBA devices are handled via ACPI AMBA scan notifier infrastructure. The platform devices get the ACPI id added to their driver.
Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/acpi/acpi_amba.c | 9 +++++++++ drivers/hwtracing/coresight/coresight-replicator.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index 7f77c07..eef5a69 100644 --- a/drivers/acpi/acpi_amba.c +++ b/drivers/acpi/acpi_amba.c @@ -24,6 +24,15 @@
static const struct acpi_device_id amba_id_list[] = { {"ARMH0061", 0}, /* PL061 GPIO Device */ + {"ARMHC500", 0}, /* ARM CoreSight ETM4x */ + {"ARMHC501", 0}, /* ARM CoreSight ETR */ + {"ARMHC502", 0}, /* ARM CoreSight STM */ + {"ARMHC503", 0}, /* ARM CoreSight Debug */ + {"ARMHC979", 0}, /* ARM CoreSight TPIU */ + {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ + {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */ + {"ARMHC9CA", 0}, /* ARM CoreSight CATU */ + {"ARMHC9FF", 0}, /* ARM CoreSight Funnel */ {"", 0}, };
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 2eb489c..a8f42df 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -5,6 +5,7 @@ * Description: CoreSight Replicator driver */
+#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/kernel.h> #include <linux/device.h> @@ -290,11 +291,17 @@ static const struct of_device_id static_replicator_match[] = { {} };
+#ifdef CONFIG_ACPI +static const struct acpi_device_id static_replicator_acpi_ids[] = { + {"ARMHC985", 0}, /* ARM CoreSight Static Replicator */ +}; +#endif static struct platform_driver static_replicator_driver = { .probe = static_replicator_probe, .driver = { .name = "coresight-replicator", - .of_match_table = static_replicator_match, + .of_match_table = of_match_ptr(static_replicator_match), + .acpi_match_table = ACPI_PTR(static_replicator_acpi_ids), .pm = &replicator_dev_pm_ops, .suppress_bind_attrs = true, },
On Mon, Apr 15, 2019 at 05:04:16PM +0100, Suzuki K Poulose wrote:
All AMBA devices are handled via ACPI AMBA scan notifier infrastructure. The platform devices get the ACPI id added to their driver.
Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/acpi/acpi_amba.c | 9 +++++++++ drivers/hwtracing/coresight/coresight-replicator.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index 7f77c07..eef5a69 100644 --- a/drivers/acpi/acpi_amba.c +++ b/drivers/acpi/acpi_amba.c @@ -24,6 +24,15 @@ static const struct acpi_device_id amba_id_list[] = { {"ARMH0061", 0}, /* PL061 GPIO Device */
- {"ARMHC500", 0}, /* ARM CoreSight ETM4x */
- {"ARMHC501", 0}, /* ARM CoreSight ETR */
- {"ARMHC502", 0}, /* ARM CoreSight STM */
- {"ARMHC503", 0}, /* ARM CoreSight Debug */
- {"ARMHC979", 0}, /* ARM CoreSight TPIU */
- {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
- {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
- {"ARMHC9CA", 0}, /* ARM CoreSight CATU */
- {"ARMHC9FF", 0}, /* ARM CoreSight Funnel */ {"", 0},
}; diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 2eb489c..a8f42df 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -5,6 +5,7 @@
- Description: CoreSight Replicator driver
*/ +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/kernel.h> #include <linux/device.h> @@ -290,11 +291,17 @@ static const struct of_device_id static_replicator_match[] = { {} }; +#ifdef CONFIG_ACPI +static const struct acpi_device_id static_replicator_acpi_ids[] = {
- {"ARMHC985", 0}, /* ARM CoreSight Static Replicator */
+}; +#endif static struct platform_driver static_replicator_driver = { .probe = static_replicator_probe, .driver = { .name = "coresight-replicator",
.of_match_table = static_replicator_match,
.of_match_table = of_match_ptr(static_replicator_match),
.pm = &replicator_dev_pm_ops, .suppress_bind_attrs = true, },.acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
For the coresight part: Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
You probably want to split this patch in half so that Rafael can pick up the the first part of it in his tree.
I am done reviewing the core part of this set and will do 33-36 next week. For the next revision I would leave them out and send a separate set in order to avoid delaying the ACPI part.
Thanks, Mathieu
-- 2.7.4
Rafael,
On 25/04/2019 18:45, Mathieu Poirier wrote:
On Mon, Apr 15, 2019 at 05:04:16PM +0100, Suzuki K Poulose wrote:
All AMBA devices are handled via ACPI AMBA scan notifier infrastructure. The platform devices get the ACPI id added to their driver.
Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/acpi/acpi_amba.c | 9 +++++++++ drivers/hwtracing/coresight/coresight-replicator.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index 7f77c07..eef5a69 100644 --- a/drivers/acpi/acpi_amba.c +++ b/drivers/acpi/acpi_amba.c @@ -24,6 +24,15 @@ static const struct acpi_device_id amba_id_list[] = { {"ARMH0061", 0}, /* PL061 GPIO Device */
- {"ARMHC500", 0}, /* ARM CoreSight ETM4x */
- {"ARMHC501", 0}, /* ARM CoreSight ETR */
- {"ARMHC502", 0}, /* ARM CoreSight STM */
- {"ARMHC503", 0}, /* ARM CoreSight Debug */
- {"ARMHC979", 0}, /* ARM CoreSight TPIU */
- {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
- {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
- {"ARMHC9CA", 0}, /* ARM CoreSight CATU */
- {"ARMHC9FF", 0}, /* ARM CoreSight Funnel */ {"", 0}, };
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 2eb489c..a8f42df 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -5,6 +5,7 @@
- Description: CoreSight Replicator driver
*/ +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/kernel.h> #include <linux/device.h> @@ -290,11 +291,17 @@ static const struct of_device_id static_replicator_match[] = { {} }; +#ifdef CONFIG_ACPI +static const struct acpi_device_id static_replicator_acpi_ids[] = {
- {"ARMHC985", 0}, /* ARM CoreSight Static Replicator */
+}; +#endif static struct platform_driver static_replicator_driver = { .probe = static_replicator_probe, .driver = { .name = "coresight-replicator",
.of_match_table = static_replicator_match,
.of_match_table = of_match_ptr(static_replicator_match),
.pm = &replicator_dev_pm_ops, .suppress_bind_attrs = true, },.acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
For the coresight part: Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
You probably want to split this patch in half so that Rafael can pick up the the first part of it in his tree.
We have the CoreSight components span over AMBA and platform devices. This series is almost getting ready, so for the next revision I would like to get your view on how to split this particular patch.
We have components in AMBA and Platform devices. Would you prefer to split the patch and pull the ACPI_AMBA changes above in to your tree ? Or are you happy with Mathieu pushing this change together with the other ACPI bindings support in the CoreSight drivers ?
FWIW, we should still be fine if we split and the patches reach at different times. Please let me know your thoughts.
Suzuki
As we prepare to expose the links between the devices in sysfs, pass the coresight_device instance to the coresight_release_platform_data in order to free up the connections when the device is removed.
No functional changes as such in this patch.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 2 +- drivers/hwtracing/coresight/coresight-priv.h | 3 ++- drivers/hwtracing/coresight/coresight.c | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 224f698..6559c49 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -734,7 +734,7 @@ coresight_get_platform_data(struct device *dev) return pdata;
/* Cleanup the connection information */ - coresight_release_platform_data(pdata); + coresight_release_platform_data(NULL, pdata); return ret; } EXPORT_SYMBOL_GPL(coresight_get_platform_data); diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 61d7f9f..bf28ca9 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -200,6 +200,7 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) return 0; }
-void coresight_release_platform_data(struct coresight_platform_data *pdata); +void coresight_release_platform_data(struct coresight_device *csdev, + struct coresight_platform_data *pdata);
#endif diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index e3b9321..010bc86 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1173,7 +1173,8 @@ postcore_initcall(coresight_init); * coresight_release_platform_data: Release references to the devices connected * to the output port of this device. */ -void coresight_release_platform_data(struct coresight_platform_data *pdata) +void coresight_release_platform_data(struct coresight_device *csdev, + struct coresight_platform_data *pdata) { int i;
@@ -1275,7 +1276,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) kfree(csdev); err_out: /* Cleanup the connection information */ - coresight_release_platform_data(desc->pdata); + coresight_release_platform_data(NULL, desc->pdata); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(coresight_register); @@ -1285,7 +1286,7 @@ void coresight_unregister(struct coresight_device *csdev) etm_perf_del_symlink_sink(csdev); /* Remove references of that device in the topology */ coresight_remove_conns(csdev); - coresight_release_platform_data(csdev->pdata); + coresight_release_platform_data(csdev, csdev->pdata); device_unregister(&csdev->dev); } EXPORT_SYMBOL_GPL(coresight_unregister);
On Mon, Apr 15, 2019 at 05:04:17PM +0100, Suzuki K Poulose wrote:
As we prepare to expose the links between the devices in sysfs, pass the coresight_device instance to the coresight_release_platform_data in order to free up the connections when the device is removed.
No functional changes as such in this patch.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight-platform.c | 2 +- drivers/hwtracing/coresight/coresight-priv.h | 3 ++- drivers/hwtracing/coresight/coresight.c | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 224f698..6559c49 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -734,7 +734,7 @@ coresight_get_platform_data(struct device *dev) return pdata; /* Cleanup the connection information */
- coresight_release_platform_data(pdata);
- coresight_release_platform_data(NULL, pdata); return ret;
} EXPORT_SYMBOL_GPL(coresight_get_platform_data); diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 61d7f9f..bf28ca9 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -200,6 +200,7 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) return 0; } -void coresight_release_platform_data(struct coresight_platform_data *pdata); +void coresight_release_platform_data(struct coresight_device *csdev,
struct coresight_platform_data *pdata);
#endif diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index e3b9321..010bc86 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1173,7 +1173,8 @@ postcore_initcall(coresight_init);
- coresight_release_platform_data: Release references to the devices connected
- to the output port of this device.
*/ -void coresight_release_platform_data(struct coresight_platform_data *pdata) +void coresight_release_platform_data(struct coresight_device *csdev,
struct coresight_platform_data *pdata)
{ int i; @@ -1275,7 +1276,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) kfree(csdev); err_out: /* Cleanup the connection information */
- coresight_release_platform_data(desc->pdata);
- coresight_release_platform_data(NULL, desc->pdata); return ERR_PTR(ret);
} EXPORT_SYMBOL_GPL(coresight_register); @@ -1285,7 +1286,7 @@ void coresight_unregister(struct coresight_device *csdev) etm_perf_del_symlink_sink(csdev); /* Remove references of that device in the topology */ coresight_remove_conns(csdev);
- coresight_release_platform_data(csdev->pdata);
- coresight_release_platform_data(csdev, csdev->pdata); device_unregister(&csdev->dev);
} EXPORT_SYMBOL_GPL(coresight_unregister);
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
-- 2.7.4
Handle failures in fixing up connections for a newly registered device. This will be useful to handle cases where we fail to expose the links via sysfs for the connections.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 010bc86..4d63063 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1025,18 +1025,18 @@ static int coresight_orphan_match(struct device *dev, void *data) return 0; }
-static void coresight_fixup_orphan_conns(struct coresight_device *csdev) +static int coresight_fixup_orphan_conns(struct coresight_device *csdev) { /* * No need to check for a return value as orphan connection(s) * are hooked-up with each newly added component. */ - bus_for_each_dev(&coresight_bustype, NULL, + return bus_for_each_dev(&coresight_bustype, NULL, csdev, coresight_orphan_match); }
-static void coresight_fixup_device_conns(struct coresight_device *csdev) +static int coresight_fixup_device_conns(struct coresight_device *csdev) { int i;
@@ -1056,6 +1056,8 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev) conn->child_dev = NULL; } } + + return 0; }
static int coresight_remove_match(struct device *dev, void *data) @@ -1265,10 +1267,15 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
mutex_lock(&coresight_mutex);
- coresight_fixup_device_conns(csdev); - coresight_fixup_orphan_conns(csdev); + ret = coresight_fixup_device_conns(csdev); + if (!ret) + ret = coresight_fixup_orphan_conns(csdev);
mutex_unlock(&coresight_mutex); + if (ret) { + coresight_unregister(csdev); + return ERR_PTR(ret); + }
return csdev;
On Mon, Apr 15, 2019 at 05:04:18PM +0100, Suzuki K Poulose wrote:
Handle failures in fixing up connections for a newly registered device. This will be useful to handle cases where we fail to expose the links via sysfs for the connections.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 010bc86..4d63063 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1025,18 +1025,18 @@ static int coresight_orphan_match(struct device *dev, void *data) return 0; } -static void coresight_fixup_orphan_conns(struct coresight_device *csdev) +static int coresight_fixup_orphan_conns(struct coresight_device *csdev) { /* * No need to check for a return value as orphan connection(s) * are hooked-up with each newly added component. */
- bus_for_each_dev(&coresight_bustype, NULL,
- return bus_for_each_dev(&coresight_bustype, NULL, csdev, coresight_orphan_match);
After this patch the comment is no longer true - please consider amending.
With the above:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
} -static void coresight_fixup_device_conns(struct coresight_device *csdev) +static int coresight_fixup_device_conns(struct coresight_device *csdev) { int i; @@ -1056,6 +1056,8 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev) conn->child_dev = NULL; } }
- return 0;
} static int coresight_remove_match(struct device *dev, void *data) @@ -1265,10 +1267,15 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) mutex_lock(&coresight_mutex);
- coresight_fixup_device_conns(csdev);
- coresight_fixup_orphan_conns(csdev);
- ret = coresight_fixup_device_conns(csdev);
- if (!ret)
ret = coresight_fixup_orphan_conns(csdev);
mutex_unlock(&coresight_mutex);
- if (ret) {
coresight_unregister(csdev);
return ERR_PTR(ret);
- }
return csdev; -- 2.7.4
Coresight device connections are a bit complicated and is not exposed currently to the user. One has to look at the platform descriptions (DT bindings or ACPI bindings) to make an understanding. Given the new naming scheme, it will be helpful to have this information to choose the appropriate devices for tracing. This patch exposes the device connections via links in the sysfs directories.
e.g, for a connection devA[OutputPort_X] -> devB[InputPort_Y] is represented as two symlinks:
/sys/bus/coresight/.../devA/out:X -> /sys/bus/coresight/.../devB /sys/bus/coresight/.../devB/in:Y -> /sys/bus/coresight/.../devA
We could have segregated the links to separate directories aka attribute_groups, for input_ports and output_ports. But the sysfs won't let you create empty attribute_groups and thus it becomes complicated to dynamically create the attribute_groups.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight.c | 120 +++++++++++++++++++++++++++++--- include/linux/coresight.h | 4 ++ 2 files changed, 113 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 4d63063..50a1f29 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -981,9 +981,92 @@ static void coresight_device_release(struct device *dev) kfree(csdev); }
+ +/* + * coresight_make_links: Make a link for a connection from a @orig + * device to @target, represented by @conn. + * + * e.g, for devOrig[output_X] -> devTarget[input_Y] is represented + * as two symbolic links : + * + * /sys/.../devOrig/out:X -> /sys/.../devTarget/ + * /sys/.../devTarget/in:Y -> /sys/.../devOrig/ + * + * The link names are allocated for a device where it appears. i.e, the + * "out" link on the master and "in" link on the slave device. + * The link names are stored in the connection record for avoiding + * the reconstruction of names for removal. + */ +static int coresight_make_links(struct coresight_device *orig, + struct coresight_connection *conn, + struct coresight_device *target) +{ + int ret = -ENOMEM; + char *outs = NULL, *ins = NULL; + + do { + outs = devm_kasprintf(&orig->dev, GFP_KERNEL, + "out:%d", conn->outport); + if (!outs) + break; + ins = devm_kasprintf(&target->dev, GFP_KERNEL, + "in:%d", conn->child_port); + if (!ins) + break; + ret = sysfs_create_link(&orig->dev.kobj, + &target->dev.kobj, outs); + if (ret) + break; + + ret = sysfs_create_link(&target->dev.kobj, + &orig->dev.kobj, ins); + if (ret) { + sysfs_remove_link(&orig->dev.kobj, outs); + break; + } + + conn->inlink_name = ins; + conn->outlink_name = outs; + /* + * Install the device connection. This also indicates that + * the links are operational on both ends. + */ + conn->child_dev = target; + return 0; + } while (0); + + if (outs) + devm_kfree(&orig->dev, outs); + if (ins) + devm_kfree(&target->dev, ins); + return ret; +} + +/* + * coresight_remove_links: Remove the sysfs links for a given connection @conn, + * from @orig device to @target device. See coresight_make_links() for more + * details. + */ +static void coresight_remove_links(struct coresight_device *orig, + struct coresight_connection *conn) +{ + struct coresight_device *target = conn->child_dev; + + if (!orig || !target) + return; + + sysfs_remove_link(&orig->dev.kobj, conn->outlink_name); + sysfs_remove_link(&target->dev.kobj, conn->inlink_name); + + devm_kfree(&target->dev, conn->inlink_name); + devm_kfree(&orig->dev, conn->outlink_name); + conn->inlink_name = conn->outlink_name = NULL; + conn->child_dev = NULL; +} + static int coresight_orphan_match(struct device *dev, void *data) { - int i; + int i, ret = 0; bool still_orphan = false; struct coresight_device *csdev, *i_csdev; struct coresight_connection *conn; @@ -1008,19 +1091,23 @@ static int coresight_orphan_match(struct device *dev, void *data) /* We have found at least one orphan connection */ if (conn->child_dev == NULL) { /* Does it match this newly added device? */ - if (conn->child_fwnode == csdev->dev.fwnode) - conn->child_dev = csdev; - else + if (conn->child_fwnode == csdev->dev.fwnode) { + ret = coresight_make_links(i_csdev, + conn, csdev); + if (ret) + return ret; + } else { /* This component still has an orphan */ still_orphan = true; + } } }
i_csdev->orphan = still_orphan;
/* - * Returning '0' ensures that all known component on the - * bus will be checked. + * Returning '0' in case we didn't encounter any error, + * ensures that all known component on the bus will be checked. */ return 0; } @@ -1038,7 +1125,7 @@ static int coresight_fixup_orphan_conns(struct coresight_device *csdev)
static int coresight_fixup_device_conns(struct coresight_device *csdev) { - int i; + int i, ret = 0;
for (i = 0; i < csdev->pdata->nr_outport; i++) { struct coresight_connection *conn = &csdev->pdata->conns[i]; @@ -1048,9 +1135,12 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) (void *)conn->child_fwnode, device_fwnode_match); if (dev) { - conn->child_dev = to_coresight_device(dev); + ret = coresight_make_links(csdev, conn, + to_coresight_device(dev)); /* and put reference from 'bus_find_device()' */ put_device(dev); + if (ret) + break; } else { csdev->orphan = true; conn->child_dev = NULL; @@ -1085,7 +1175,7 @@ static int coresight_remove_match(struct device *dev, void *data)
if (csdev->dev.fwnode == conn->child_fwnode) { iterator->orphan = true; - conn->child_dev = NULL; + coresight_remove_links(iterator, conn); /* * Drop the reference to the handle for the remote * device acquired in parsing the connections from @@ -1179,10 +1269,18 @@ void coresight_release_platform_data(struct coresight_device *csdev, struct coresight_platform_data *pdata) { int i; + struct coresight_connection *conns = pdata->conns;
for (i = 0; i < pdata->nr_outport; i++) { - if (pdata->conns[i].child_fwnode) { - fwnode_handle_put(pdata->conns[i].child_fwnode); + /* If we have made the links, remove them now */ + if (csdev && conns[i].child_dev) + coresight_remove_links(csdev, &conns[i]); + /* + * Drop the refcount and clear the handle as this device + * is going away + */ + if (conns[i].child_fwnode) { + fwnode_handle_put(conns[i].child_fwnode); pdata->conns[i].child_fwnode = 0; } } diff --git a/include/linux/coresight.h b/include/linux/coresight.h index d6367a0..284d783 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -130,12 +130,16 @@ struct coresight_desc { * @chid_fwnode: remote component's fwnode handle. * @child_dev: a @coresight_device representation of the component connected to @outport. + * @inlink_name: Name for the "input" link + * @outlink_name: Name for the "output" link */ struct coresight_connection { int outport; int child_port; struct fwnode_handle *child_fwnode; struct coresight_device *child_dev; + const char *inlink_name; + const char *outlink_name; };
/**
On Mon, Apr 15, 2019 at 05:04:19PM +0100, Suzuki K Poulose wrote:
Coresight device connections are a bit complicated and is not exposed currently to the user. One has to look at the platform descriptions (DT bindings or ACPI bindings) to make an understanding. Given the new naming scheme, it will be helpful to have this information to choose the appropriate devices for tracing. This patch exposes the device connections via links in the sysfs directories.
e.g, for a connection devA[OutputPort_X] -> devB[InputPort_Y] is represented as two symlinks:
/sys/bus/coresight/.../devA/out:X -> /sys/bus/coresight/.../devB /sys/bus/coresight/.../devB/in:Y -> /sys/bus/coresight/.../devA
We could have segregated the links to separate directories aka attribute_groups, for input_ports and output_ports. But the sysfs won't let you create empty attribute_groups and thus it becomes complicated to dynamically create the attribute_groups.
While testing this set I noticed entries in /sys/bus/event_source/sinks still advertise platform device names. To fix this etm_perf_add_symlink_sink() needs to be modified, more specifically:
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 4d5a2b9f9d6a..b6d8b8c2ceb9 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -507,7 +507,7 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev) unsigned long hash; const char *name; struct device *pmu_dev = etm_pmu.dev; - struct device *pdev = csdev->dev.parent; + struct device *dev = &csdev->dev; struct dev_ext_attribute *ea;
if (csdev->type != CORESIGHT_DEV_TYPE_SINK && @@ -520,15 +520,15 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev) if (!etm_perf_up) return -EPROBE_DEFER;
- ea = devm_kzalloc(pdev, sizeof(*ea), GFP_KERNEL); + ea = devm_kzalloc(dev, sizeof(*ea), GFP_KERNEL); if (!ea) return -ENOMEM;
- name = dev_name(pdev); + name = dev_name(dev); /* See function coresight_get_sink_by_id() to know where this is used */ hash = hashlen_hash(hashlen_string(NULL, name));
- ea->attr.attr.name = devm_kstrdup(pdev, name, GFP_KERNEL); + ea->attr.attr.name = devm_kstrdup(dev, name, GFP_KERNEL); if (!ea->attr.attr.name) return -ENOMEM;
Mike Leach was also working on a way to represent connections between CTI/CTM devices. It would be desirable to get the same kind of topology representation for both "normal" devices and CTI/CTMs. I like how this set represent the topology but I also want Mike to have his say as well.
Before moving forward I will need to get a "Reviewed-by" from him.
Thanks, Mathieu
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/coresight.c | 120 +++++++++++++++++++++++++++++--- include/linux/coresight.h | 4 ++ 2 files changed, 113 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 4d63063..50a1f29 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -981,9 +981,92 @@ static void coresight_device_release(struct device *dev) kfree(csdev); }
+/*
- coresight_make_links: Make a link for a connection from a @orig
- device to @target, represented by @conn.
- e.g, for devOrig[output_X] -> devTarget[input_Y] is represented
- as two symbolic links :
- /sys/.../devOrig/out:X -> /sys/.../devTarget/
- /sys/.../devTarget/in:Y -> /sys/.../devOrig/
- The link names are allocated for a device where it appears. i.e, the
- "out" link on the master and "in" link on the slave device.
- The link names are stored in the connection record for avoiding
- the reconstruction of names for removal.
- */
+static int coresight_make_links(struct coresight_device *orig,
struct coresight_connection *conn,
struct coresight_device *target)
+{
- int ret = -ENOMEM;
- char *outs = NULL, *ins = NULL;
- do {
outs = devm_kasprintf(&orig->dev, GFP_KERNEL,
"out:%d", conn->outport);
if (!outs)
break;
ins = devm_kasprintf(&target->dev, GFP_KERNEL,
"in:%d", conn->child_port);
if (!ins)
break;
ret = sysfs_create_link(&orig->dev.kobj,
&target->dev.kobj, outs);
if (ret)
break;
ret = sysfs_create_link(&target->dev.kobj,
&orig->dev.kobj, ins);
if (ret) {
sysfs_remove_link(&orig->dev.kobj, outs);
break;
}
conn->inlink_name = ins;
conn->outlink_name = outs;
/*
* Install the device connection. This also indicates that
* the links are operational on both ends.
*/
conn->child_dev = target;
return 0;
- } while (0);
- if (outs)
devm_kfree(&orig->dev, outs);
- if (ins)
devm_kfree(&target->dev, ins);
- return ret;
+}
+/*
- coresight_remove_links: Remove the sysfs links for a given connection @conn,
- from @orig device to @target device. See coresight_make_links() for more
- details.
- */
+static void coresight_remove_links(struct coresight_device *orig,
struct coresight_connection *conn)
+{
- struct coresight_device *target = conn->child_dev;
- if (!orig || !target)
return;
- sysfs_remove_link(&orig->dev.kobj, conn->outlink_name);
- sysfs_remove_link(&target->dev.kobj, conn->inlink_name);
- devm_kfree(&target->dev, conn->inlink_name);
- devm_kfree(&orig->dev, conn->outlink_name);
- conn->inlink_name = conn->outlink_name = NULL;
- conn->child_dev = NULL;
+}
static int coresight_orphan_match(struct device *dev, void *data) {
- int i;
- int i, ret = 0; bool still_orphan = false; struct coresight_device *csdev, *i_csdev; struct coresight_connection *conn;
@@ -1008,19 +1091,23 @@ static int coresight_orphan_match(struct device *dev, void *data) /* We have found at least one orphan connection */ if (conn->child_dev == NULL) { /* Does it match this newly added device? */
if (conn->child_fwnode == csdev->dev.fwnode)
conn->child_dev = csdev;
else
if (conn->child_fwnode == csdev->dev.fwnode) {
ret = coresight_make_links(i_csdev,
conn, csdev);
if (ret)
return ret;
} else { /* This component still has an orphan */ still_orphan = true;
} }}
i_csdev->orphan = still_orphan; /*
* Returning '0' ensures that all known component on the
* bus will be checked.
* Returning '0' in case we didn't encounter any error,
*/ return 0;* ensures that all known component on the bus will be checked.
} @@ -1038,7 +1125,7 @@ static int coresight_fixup_orphan_conns(struct coresight_device *csdev) static int coresight_fixup_device_conns(struct coresight_device *csdev) {
- int i;
- int i, ret = 0;
for (i = 0; i < csdev->pdata->nr_outport; i++) { struct coresight_connection *conn = &csdev->pdata->conns[i]; @@ -1048,9 +1135,12 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) (void *)conn->child_fwnode, device_fwnode_match); if (dev) {
conn->child_dev = to_coresight_device(dev);
ret = coresight_make_links(csdev, conn,
to_coresight_device(dev)); /* and put reference from 'bus_find_device()' */ put_device(dev);
if (ret)
} else { csdev->orphan = true; conn->child_dev = NULL;break;
@@ -1085,7 +1175,7 @@ static int coresight_remove_match(struct device *dev, void *data) if (csdev->dev.fwnode == conn->child_fwnode) { iterator->orphan = true;
conn->child_dev = NULL;
coresight_remove_links(iterator, conn); /* * Drop the reference to the handle for the remote * device acquired in parsing the connections from
@@ -1179,10 +1269,18 @@ void coresight_release_platform_data(struct coresight_device *csdev, struct coresight_platform_data *pdata) { int i;
- struct coresight_connection *conns = pdata->conns;
for (i = 0; i < pdata->nr_outport; i++) {
if (pdata->conns[i].child_fwnode) {
fwnode_handle_put(pdata->conns[i].child_fwnode);
/* If we have made the links, remove them now */
if (csdev && conns[i].child_dev)
coresight_remove_links(csdev, &conns[i]);
/*
* Drop the refcount and clear the handle as this device
* is going away
*/
if (conns[i].child_fwnode) {
} }fwnode_handle_put(conns[i].child_fwnode); pdata->conns[i].child_fwnode = 0;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h index d6367a0..284d783 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -130,12 +130,16 @@ struct coresight_desc {
- @chid_fwnode: remote component's fwnode handle.
- @child_dev: a @coresight_device representation of the component connected to @outport.
- @inlink_name: Name for the "input" link
*/
- @outlink_name: Name for the "output" link
struct coresight_connection { int outport; int child_port; struct fwnode_handle *child_fwnode; struct coresight_device *child_dev;
- const char *inlink_name;
- const char *outlink_name;
}; /** -- 2.7.4
ACPI bindings for CoreSight components on the Juno-r0 board. Please note that the bindings apply only for the juno-r0. The layout on r1 and r2 are slightly different and will need dynamic ACPI table support to be able to use a single UEFI image.
Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- Platform/ARM/JunoPkg/AcpiTables/Dsdt.asl | 241 +++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+)
diff --git a/Platform/ARM/JunoPkg/AcpiTables/Dsdt.asl b/Platform/ARM/JunoPkg/AcpiTables/Dsdt.asl index 702b057..c70e8ac 100644 --- a/Platform/ARM/JunoPkg/AcpiTables/Dsdt.asl +++ b/Platform/ARM/JunoPkg/AcpiTables/Dsdt.asl @@ -14,6 +14,51 @@
#include "ArmPlatform.h"
+#define ACPI_GRAPH_REV 0 +#define ACPI_GRAPH_UUID "ab02a46b-74c7-45a2-bd68-f7d344ef2153" + +#define CORESIGHT_GRAPH_UUID "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" + +#define CS_LINK_MASTER 1 +#define CS_LINK_SLAVE 0 + + +#define DSD_CS_GRAPH_BEGIN(_nports) \ + Package () { \ + 1, // GraphID \ + ToUUID(CORESIGHT_GRAPH_UUID), \ + _nports, + +#define DSD_CS_GRAPH_END \ + } + +#define DSD_GRAPH_BEGIN(_nports) \ + ToUUID(ACPI_GRAPH_UUID), \ + Package() { \ + ACPI_GRAPH_REV, \ + 1, \ + DSD_CS_GRAPH_BEGIN(_nports) + +#define DSD_GRAPH_END \ + DSD_CS_GRAPH_END \ + } + +#define DSD_PORTS_BEGIN(_nports) \ + Name (_DSD, Package () { \ + DSD_GRAPH_BEGIN(_nports) + +#define DSD_PORTS_END \ + DSD_GRAPH_END \ + }) + +#define CS_PORT(_port, _rport, _rphandle, _dir) \ + Package () { _port, _rport, _rphandle, _dir} + +#define CS_INPUT_PORT(_port, _rport, _rphandle) \ + CS_PORT(_port, _rport, _rphandle, CS_LINK_SLAVE) +#define CS_OUTPUT_PORT(_port, _rport, _rphandle) \ + CS_PORT(_port, _rport, _rphandle, CS_LINK_MASTER) + DefinitionBlock("DsdtTable.aml", "DSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM_REVISION) { Scope(_SB) { // @@ -122,15 +167,56 @@ DefinitionBlock("DsdtTable.aml", "DSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_O Method (_LPI, 0, NotSerialized) { return(PLPI) } + + Device(ETM0) { // ETM on Cluster0 CPU0 + Name (_HID, "ARMHC500") + Name (_CID, "ARMHC500") + Name (_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x22040000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 0, _SB_.CLU0.FUN0) + DSD_PORTS_END + + } // ETM0 } + Device(CPU1) { // A57-1: Cluster 0, Cpu 1 Name(_HID, "ACPI0007") Name(_UID, 5) Method (_LPI, 0, NotSerialized) { return(PLPI) } + Device(ETM1) { // ETM on Cluster0 CPU1 + Name (_HID, "ARMHC500") + Name (_CID, "ARMHC500") + Name (_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x22140000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 1, _SB_.CLU0.FUN0) + DSD_PORTS_END + + } // ETM1 } + + Device(FUN0) { + Name(_HID, "ARMHC9FF") + Name(_CID, "ARMHC9FF") + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x220c0000, 0x1000) + }) + + DSD_PORTS_BEGIN(3) + CS_OUTPUT_PORT(0, 0, _SB_.MFUN), + CS_INPUT_PORT(0, 0, _SB_.CLU0.CPU0.ETM0), + CS_INPUT_PORT(1, 0, _SB_.CLU0.CPU1.ETM1) + DSD_PORTS_END + } // CL0.FUN0 } + Device (CLU1) { // Cluster1 state Name(_HID, "ACPI0010") Name(_UID, 2) @@ -208,19 +294,45 @@ DefinitionBlock("DsdtTable.aml", "DSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_O "CorePwrDn" }, }) + Device(CPU2) { // A53-0: Cluster 1, Cpu 0 Name(_HID, "ACPI0007") Name(_UID, 0) Method (_LPI, 0, NotSerialized) { return(PLPI) } + Device(ETM2) { // ETM on Cluster1, CPU0 + Name (_HID, "ARMHC500") + Name (_CID, "ARMHC500") + Name (_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x23040000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 0, _SB_.CLU1.FUN1) + DSD_PORTS_END + + } // ETM2 } + Device(CPU3) { // A53-1: Cluster 1, Cpu 1 Name(_HID, "ACPI0007") Name(_UID, 1) Method (_LPI, 0, NotSerialized) { return(PLPI) } + Device(ETM3) { // ETM on Cluster1, CPU1 + Name (_HID, "ARMHC500") + Name (_CID, "ARMHC500") + Name (_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x23140000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 1, _SB_.CLU1.FUN1) + DSD_PORTS_END + + } // ETM3 } Device(CPU4) { // A53-2: Cluster 1, Cpu 2 Name(_HID, "ACPI0007") @@ -228,6 +340,18 @@ DefinitionBlock("DsdtTable.aml", "DSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_O Method (_LPI, 0, NotSerialized) { return(PLPI) } + Device(ETM4) { // ETM on Cluster1, CPU2 + Name (_HID, "ARMHC500") // ETM + Name (_CID, "ARMHC500") // ETM + Name (_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x23240000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 2, _SB_.CLU1.FUN1) + DSD_PORTS_END + + } // ETM4 } Device(CPU5) { // A53-3: Cluster 1, Cpu 3 Name(_HID, "ACPI0007") @@ -235,9 +359,126 @@ DefinitionBlock("DsdtTable.aml", "DSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_O Method (_LPI, 0, NotSerialized) { return(PLPI) } + Device(ETM5) { // ETM on Cluster1, CPU3 + Name (_HID, "ARMHC500") // ETM + Name (_CID, "ARMHC500") // ETM + Name (_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x23340000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 3, _SB_.CLU1.FUN1) + DSD_PORTS_END + } // ETM5 } + Device(FUN1) { + Name(_HID, "ARMHC9FF") + Name(_CID, "ARMHC9FF") + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x230c0000, 0x1000) + }) + + DSD_PORTS_BEGIN(5) + CS_OUTPUT_PORT(0, 1, _SB_.MFUN), + CS_INPUT_PORT(0, 0, _SB_.CLU1.CPU2.ETM2), + CS_INPUT_PORT(1, 0, _SB_.CLU1.CPU3.ETM3), + CS_INPUT_PORT(2, 0, _SB_.CLU1.CPU4.ETM4), + CS_INPUT_PORT(3, 0, _SB_.CLU1.CPU5.ETM5) + DSD_PORTS_END + } // CL1.FUN1 }
+ Device(STM0) { + Name(_HID, "ARMHC502") // STM + Name(_CID, "ARMHC502") + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x20100000, 0x1000) + Memory32Fixed(ReadWrite, 0x28000000, 0x1000000) + }) + DSD_PORTS_BEGIN(1) + CS_OUTPUT_PORT(0, 2, _SB_.MFUN) + DSD_PORTS_END + } + + Device(MFUN) { + Name(_HID, "ARMHC9FF") // Funnel + Name(_CID, "ARMHC9FF") // Funnel + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x20040000, 0x1000) + }) + + DSD_PORTS_BEGIN(4) + CS_OUTPUT_PORT(0, 0, _SB_.ETF0), + CS_INPUT_PORT(0, 0, _SB_.CLU0.FUN0), + CS_INPUT_PORT(1, 0, _SB_.CLU1.FUN1), + CS_INPUT_PORT(2, 0, _SB_.STM0) + DSD_PORTS_END + + } // MFUN-nel + + Device(ETF0) { + Name(_HID, "ARMHC97C") // TMC + Name(_CID, "ARMHC97C") // TMC + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x20010000, 0x1000) + }) + + DSD_PORTS_BEGIN(2) + CS_OUTPUT_PORT(0, 1, _SB_.RPL), + CS_INPUT_PORT(0, 0, _SB_.MFUN) + DSD_PORTS_END + + } // ETF0 + + Device(RPL) { + Name(_HID, "ARMHC98D") // Replicator + Name(_CID, "ARMHC98D") // Replicator + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x20120000, 0x1000) + }) + + DSD_PORTS_BEGIN(3) + CS_OUTPUT_PORT(0, 0, _SB_.TPIU), + CS_OUTPUT_PORT(1, 0, _SB_.ETR), + CS_INPUT_PORT(0, 0, _SB_.ETF0) + DSD_PORTS_END + + } // RPL + + Device(ETR) { + Name(_HID, "ARMHC97C") // TMC + Name(_CID, "ARMHC97C") // TMC + Name(_CCA, 0) // The ETR on this platform is not coherent + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x20070000, 0x1000) + }) + + Name(_DSD, Package() { + DSD_GRAPH_BEGIN(1) + CS_INPUT_PORT(0, 1, _SB_.RPL) + DSD_GRAPH_END, + + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package() { + Package(2) {"arm,scatter-gather", 1} + } + }) + + } // ETR + + Device(TPIU) { + Name(_HID, "ARMHC979") // TPIU + Name(_CID, "ARMHC979") // TPIU + Name(_CRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0x20030000, 0x1000) + }) + + DSD_PORTS_BEGIN(1) + CS_INPUT_PORT(0, 0, _SB_.RPL) + DSD_PORTS_END + + } // TPIU + // // Keyboard and Mouse //