Commit 22a550a3 authored by Kim Phillips's avatar Kim Phillips Committed by Greg Kroah-Hartman

coresight: etm4x: Allow etm4x to be built as a module

Allow to build coresight-etm4x as a module, for ease of development.

- Kconfig becomes a tristate, to allow =m
- append -core to source file name to allow module to
  be called coresight-etm4x by the Makefile
- add an etm4_remove function, for module unload
- add a MODULE_DEVICE_TABLE for autoloading on boot
- delay advertising the per-cpu etmdrvdata
- protect etmdrvdata[] by modifying it on relevant CPU

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Suzuki K Poulose <Suzuki.Poulose@arm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Russell King <linux@armlinux.org.uk>
Tested-by: default avatarMike Leach <mike.leach@linaro.org>
Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarKim Phillips <kim.phillips@arm.com>
Signed-off-by: default avatarTingwei Zhang <tingwei@codeaurora.org>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200928163513.70169-11-mathieu.poirier@linaro.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 97fe626c
...@@ -78,7 +78,7 @@ config CORESIGHT_SOURCE_ETM3X ...@@ -78,7 +78,7 @@ config CORESIGHT_SOURCE_ETM3X
module will be called coresight-etm3x. module will be called coresight-etm3x.
config CORESIGHT_SOURCE_ETM4X config CORESIGHT_SOURCE_ETM4X
bool "CoreSight Embedded Trace Macrocell 4.x driver" tristate "CoreSight Embedded Trace Macrocell 4.x driver"
depends on ARM64 depends on ARM64
select CORESIGHT_LINKS_AND_SINKS select CORESIGHT_LINKS_AND_SINKS
select PID_IN_CONTEXTIDR select PID_IN_CONTEXTIDR
...@@ -88,6 +88,9 @@ config CORESIGHT_SOURCE_ETM4X ...@@ -88,6 +88,9 @@ config CORESIGHT_SOURCE_ETM4X
for instruction level tracing. Depending on the implemented version for instruction level tracing. Depending on the implemented version
data tracing may also be available. data tracing may also be available.
To compile this driver as a module, choose M here: the
module will be called coresight-etm4x.
config CORESIGHT_STM config CORESIGHT_STM
tristate "CoreSight System Trace Macrocell driver" tristate "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64 depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
......
...@@ -14,8 +14,8 @@ obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \ ...@@ -14,8 +14,8 @@ obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o
coresight-etm3x-y := coresight-etm3x-core.o coresight-etm-cp14.o \ coresight-etm3x-y := coresight-etm3x-core.o coresight-etm-cp14.o \
coresight-etm3x-sysfs.o coresight-etm3x-sysfs.o
obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o
coresight-etm4x-sysfs.o coresight-etm4x-y := coresight-etm4x-core.o coresight-etm4x-sysfs.o
obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
......
...@@ -1447,7 +1447,7 @@ static int __init etm4_pm_setup(void) ...@@ -1447,7 +1447,7 @@ static int __init etm4_pm_setup(void)
return ret; return ret;
} }
static void __init etm4_pm_clear(void) static void etm4_pm_clear(void)
{ {
cpu_pm_unregister_notifier(&etm4_cpu_pm_nb); cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
...@@ -1504,25 +1504,20 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -1504,25 +1504,20 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
if (!desc.name) if (!desc.name)
return -ENOMEM; return -ENOMEM;
etmdrvdata[drvdata->cpu] = drvdata;
if (smp_call_function_single(drvdata->cpu, if (smp_call_function_single(drvdata->cpu,
etm4_init_arch_data, drvdata, 1)) etm4_init_arch_data, drvdata, 1))
dev_err(dev, "ETM arch init failed\n"); dev_err(dev, "ETM arch init failed\n");
if (etm4_arch_supported(drvdata->arch) == false) { if (etm4_arch_supported(drvdata->arch) == false)
ret = -EINVAL; return -EINVAL;
goto err_arch_supported;
}
etm4_init_trace_id(drvdata); etm4_init_trace_id(drvdata);
etm4_set_default(&drvdata->config); etm4_set_default(&drvdata->config);
pdata = coresight_get_platform_data(dev); pdata = coresight_get_platform_data(dev);
if (IS_ERR(pdata)) { if (IS_ERR(pdata))
ret = PTR_ERR(pdata); return PTR_ERR(pdata);
goto err_arch_supported;
}
adev->dev.platform_data = pdata; adev->dev.platform_data = pdata;
desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.type = CORESIGHT_DEV_TYPE_SOURCE;
...@@ -1532,17 +1527,17 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -1532,17 +1527,17 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
desc.dev = dev; desc.dev = dev;
desc.groups = coresight_etmv4_groups; desc.groups = coresight_etmv4_groups;
drvdata->csdev = coresight_register(&desc); drvdata->csdev = coresight_register(&desc);
if (IS_ERR(drvdata->csdev)) { if (IS_ERR(drvdata->csdev))
ret = PTR_ERR(drvdata->csdev); return PTR_ERR(drvdata->csdev);
goto err_arch_supported;
}
ret = etm_perf_symlink(drvdata->csdev, true); ret = etm_perf_symlink(drvdata->csdev, true);
if (ret) { if (ret) {
coresight_unregister(drvdata->csdev); coresight_unregister(drvdata->csdev);
goto err_arch_supported; return ret;
} }
etmdrvdata[drvdata->cpu] = drvdata;
pm_runtime_put(&adev->dev); pm_runtime_put(&adev->dev);
dev_info(&drvdata->csdev->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); drvdata->cpu, drvdata->arch >> 4, drvdata->arch & 0xf);
...@@ -1553,10 +1548,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -1553,10 +1548,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
} }
return 0; return 0;
err_arch_supported:
etmdrvdata[drvdata->cpu] = NULL;
return ret;
} }
static struct amba_cs_uci_id uci_id_etm4[] = { static struct amba_cs_uci_id uci_id_etm4[] = {
...@@ -1568,6 +1559,40 @@ static struct amba_cs_uci_id uci_id_etm4[] = { ...@@ -1568,6 +1559,40 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
} }
}; };
static void __exit clear_etmdrvdata(void *info)
{
int cpu = *(int *)info;
etmdrvdata[cpu] = NULL;
}
static int __exit etm4_remove(struct amba_device *adev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(&adev->dev);
etm_perf_symlink(drvdata->csdev, false);
/*
* Taking hotplug lock here to avoid racing between etm4_remove and
* CPU hotplug call backs.
*/
cpus_read_lock();
/*
* The readers for etmdrvdata[] are CPU hotplug call backs
* and PM notification call backs. Change etmdrvdata[i] on
* CPU i ensures these call backs has consistent view
* inside one call back function.
*/
if (smp_call_function_single(drvdata->cpu, clear_etmdrvdata, &drvdata->cpu, 1))
etmdrvdata[drvdata->cpu] = NULL;
cpus_read_unlock();
coresight_unregister(drvdata->csdev);
return 0;
}
static const struct amba_id etm4_ids[] = { static const struct amba_id etm4_ids[] = {
CS_AMBA_ID(0x000bb95d), /* Cortex-A53 */ CS_AMBA_ID(0x000bb95d), /* Cortex-A53 */
CS_AMBA_ID(0x000bb95e), /* Cortex-A57 */ CS_AMBA_ID(0x000bb95e), /* Cortex-A57 */
...@@ -1587,12 +1612,16 @@ static const struct amba_id etm4_ids[] = { ...@@ -1587,12 +1612,16 @@ static const struct amba_id etm4_ids[] = {
{}, {},
}; };
MODULE_DEVICE_TABLE(amba, etm4_ids);
static struct amba_driver etm4x_driver = { static struct amba_driver etm4x_driver = {
.drv = { .drv = {
.name = "coresight-etm4x", .name = "coresight-etm4x",
.owner = THIS_MODULE,
.suppress_bind_attrs = true, .suppress_bind_attrs = true,
}, },
.probe = etm4_probe, .probe = etm4_probe,
.remove = etm4_remove,
.id_table = etm4_ids, .id_table = etm4_ids,
}; };
...@@ -1614,4 +1643,17 @@ static int __init etm4x_init(void) ...@@ -1614,4 +1643,17 @@ static int __init etm4x_init(void)
return ret; return ret;
} }
device_initcall(etm4x_init);
static void __exit etm4x_exit(void)
{
amba_driver_unregister(&etm4x_driver);
etm4_pm_clear();
}
module_init(etm4x_init);
module_exit(etm4x_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace v4.x driver");
MODULE_LICENSE("GPL v2");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment