CoreSight ETM with system register access may not have a memory mapped i/o access. Refactor the ETM specific probing into a common routine to allow reusing the code for such ETMs.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Mike Leach mike.leach@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight-etm4x.c | 64 ++++++++++++------- 1 file changed, 41 insertions(+), 23 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 831206f7f306..e91af23ac419 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -1541,27 +1541,43 @@ static bool etm4_cpu_supports_sysreg(int cpu) return sys_reg_support; }
-static int etm4_probe(struct amba_device *adev, const struct amba_id *id) +static int etm4_probe_common(struct device *dev, void __iomem *base) { int ret, cpu; bool sys_reg = false; - void __iomem *base; - struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL; struct etmv4_drvdata *drvdata; - struct resource *res = &adev->res; struct coresight_desc desc = { 0 };
+ cpu = coresight_get_cpu(dev); + if (cpu < 0) + return cpu; + cpu = coresight_get_cpu(dev); if (cpu < 0 || !cpu_online(cpu)) return -EPROBE_DEFER;
sys_reg = etm4_cpu_supports_sysreg(cpu); + if (sys_reg) { + desc.access = (struct csdev_access){ + .no_iomem = true, + .read = etm4x_sysreg_read, + .write = etm4x_sysreg_write, + }; + } else if (base) { + desc.access.base = base; + } else { + dev_crit(dev, "etm4x: Unable to detect access\n"); + return -ENODEV; + } + +
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
+ drvdata->base = base; drvdata->cpu = cpu; dev_set_drvdata(dev, drvdata);
@@ -1579,22 +1595,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) if (fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up")) drvdata->skip_power_up = true;
- if (sys_reg) { - desc.access = (struct csdev_access){ - .no_iomem = true, - .read = etm4x_sysreg_read, - .write = etm4x_sysreg_write, - }; - } else { - /* Validity for the resource is already checked by the AMBA core */ - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - drvdata->base = base; - desc.access.base = base; - } - spin_lock_init(&drvdata->spinlock);
desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu); @@ -1630,7 +1630,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) ret = PTR_ERR(pdata); goto err_arch_supported; } - adev->dev.platform_data = pdata; + dev->platform_data = pdata;
desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; @@ -1650,7 +1650,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) goto err_arch_supported; }
- pm_runtime_put(&adev->dev); dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n", drvdata->cpu, drvdata->arch >> 4, drvdata->arch & 0xf); if (sys_reg) @@ -1669,6 +1668,25 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) return ret; }
+static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id) +{ + void __iomem *base; + struct device *dev = &adev->dev; + struct resource *res = &adev->res; + int ret; + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + ret = etm4_probe_common(dev, base); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; +} + static struct amba_cs_uci_id uci_id_etm4[] = { { /* ETMv4 UCI data */ @@ -1700,7 +1718,7 @@ static struct amba_driver etm4x_driver = { .name = "coresight-etm4x", .suppress_bind_attrs = true, }, - .probe = etm4_probe, + .probe = etm4_probe_amba, .id_table = etm4_ids, }; builtin_amba_driver(etm4x_driver);