summaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing/coresight
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwtracing/coresight')
-rw-r--r--drivers/hwtracing/coresight/coresight-catu.c138
-rw-r--r--drivers/hwtracing/coresight/coresight-catu.h1
-rw-r--r--drivers/hwtracing/coresight/coresight-core.c29
-rw-r--r--drivers/hwtracing/coresight/coresight-cpu-debug.c137
-rw-r--r--drivers/hwtracing/coresight/coresight-cti-core.c1
-rw-r--r--drivers/hwtracing/coresight/coresight-etb10.c1
-rw-r--r--drivers/hwtracing/coresight/coresight-etm3x-core.c1
-rw-r--r--drivers/hwtracing/coresight/coresight-etm4x-core.c1
-rw-r--r--drivers/hwtracing/coresight/coresight-funnel.c88
-rw-r--r--drivers/hwtracing/coresight/coresight-platform.c4
-rw-r--r--drivers/hwtracing/coresight/coresight-priv.h10
-rw-r--r--drivers/hwtracing/coresight/coresight-replicator.c83
-rw-r--r--drivers/hwtracing/coresight/coresight-stm.c115
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-core.c182
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc.h2
-rw-r--r--drivers/hwtracing/coresight/coresight-tpda.c1
-rw-r--r--drivers/hwtracing/coresight/coresight-tpdm.c1
-rw-r--r--drivers/hwtracing/coresight/coresight-tpiu.c117
-rw-r--r--drivers/hwtracing/coresight/coresight-trbe.c1
19 files changed, 741 insertions, 172 deletions
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 3949ded0d4..bfea880d6d 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -7,11 +7,13 @@
* Author: Suzuki K Poulose <suzuki.poulose@arm.com>
*/
+#include <linux/acpi.h>
#include <linux/amba/bus.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include "coresight-catu.h"
@@ -502,28 +504,20 @@ static const struct coresight_ops catu_ops = {
.helper_ops = &catu_helper_ops,
};
-static int catu_probe(struct amba_device *adev, const struct amba_id *id)
+static int __catu_probe(struct device *dev, struct resource *res)
{
int ret = 0;
u32 dma_mask;
- struct catu_drvdata *drvdata;
+ struct catu_drvdata *drvdata = dev_get_drvdata(dev);
struct coresight_desc catu_desc;
struct coresight_platform_data *pdata = NULL;
- 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;
- goto out;
- }
-
- dev_set_drvdata(dev, drvdata);
- base = devm_ioremap_resource(dev, &adev->res);
+ base = devm_ioremap_resource(dev, res);
if (IS_ERR(base)) {
ret = PTR_ERR(base);
goto out;
@@ -567,19 +561,39 @@ 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:
return ret;
}
-static void catu_remove(struct amba_device *adev)
+static int catu_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct catu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+ struct catu_drvdata *drvdata;
+ int ret;
+
+ drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ amba_set_drvdata(adev, drvdata);
+ ret = __catu_probe(&adev->dev, &adev->res);
+ if (!ret)
+ pm_runtime_put(&adev->dev);
+
+ return ret;
+}
+
+static void __catu_remove(struct device *dev)
+{
+ struct catu_drvdata *drvdata = dev_get_drvdata(dev);
coresight_unregister(drvdata->csdev);
}
+static void catu_remove(struct amba_device *adev)
+{
+ __catu_remove(&adev->dev);
+}
+
static struct amba_id catu_ids[] = {
CS_AMBA_ID(0x000bb9ee),
{},
@@ -590,7 +604,6 @@ MODULE_DEVICE_TABLE(amba, catu_ids);
static struct amba_driver catu_driver = {
.drv = {
.name = "coresight-catu",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = catu_probe,
@@ -598,13 +611,98 @@ static struct amba_driver catu_driver = {
.id_table = catu_ids,
};
+static int catu_platform_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct catu_drvdata *drvdata;
+ int ret = 0;
+
+ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
+
+ pm_runtime_get_noresume(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ dev_set_drvdata(&pdev->dev, drvdata);
+ ret = __catu_probe(&pdev->dev, res);
+ pm_runtime_put(&pdev->dev);
+ if (ret) {
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+ }
+
+ return ret;
+}
+
+static void catu_platform_remove(struct platform_device *pdev)
+{
+ struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
+ __catu_remove(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+}
+
+#ifdef CONFIG_PM
+static int catu_runtime_suspend(struct device *dev)
+{
+ struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
+ return 0;
+}
+
+static int catu_runtime_resume(struct device *dev)
+{
+ struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops catu_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(catu_runtime_suspend, catu_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id catu_acpi_ids[] = {
+ {"ARMHC9CA", 0, 0, 0}, /* ARM CoreSight CATU */
+ {},
+};
+
+MODULE_DEVICE_TABLE(acpi, catu_acpi_ids);
+#endif
+
+static struct platform_driver catu_platform_driver = {
+ .probe = catu_platform_probe,
+ .remove_new = catu_platform_remove,
+ .driver = {
+ .name = "coresight-catu-platform",
+ .acpi_match_table = ACPI_PTR(catu_acpi_ids),
+ .suppress_bind_attrs = true,
+ .pm = &catu_dev_pm_ops,
+ },
+};
+
static int __init catu_init(void)
{
int ret;
- ret = amba_driver_register(&catu_driver);
- if (ret)
- pr_info("Error registering catu driver\n");
+ ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver);
tmc_etr_set_catu_ops(&etr_catu_buf_ops);
return ret;
}
@@ -612,7 +710,7 @@ static int __init catu_init(void)
static void __exit catu_exit(void)
{
tmc_etr_remove_catu_ops();
- amba_driver_unregister(&catu_driver);
+ coresight_remove_driver(&catu_driver, &catu_platform_driver);
}
module_init(catu_init);
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
index 442e034bbf..141feac1c1 100644
--- a/drivers/hwtracing/coresight/coresight-catu.h
+++ b/drivers/hwtracing/coresight/coresight-catu.h
@@ -61,6 +61,7 @@
#define CATU_IRQEN_OFF 0x0
struct catu_drvdata {
+ struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
int irq;
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index b83613e342..9fc6f6b863 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1398,6 +1398,35 @@ static void __exit coresight_exit(void)
module_init(coresight_init);
module_exit(coresight_exit);
+int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
+ struct platform_driver *pdev_drv)
+{
+ int ret;
+
+ ret = amba_driver_register(amba_drv);
+ if (ret) {
+ pr_err("%s: error registering AMBA driver\n", drv);
+ return ret;
+ }
+
+ ret = platform_driver_register(pdev_drv);
+ if (!ret)
+ return 0;
+
+ pr_err("%s: error registering platform driver\n", drv);
+ amba_driver_unregister(amba_drv);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(coresight_init_driver);
+
+void coresight_remove_driver(struct amba_driver *amba_drv,
+ struct platform_driver *pdev_drv)
+{
+ amba_driver_unregister(amba_drv);
+ platform_driver_unregister(pdev_drv);
+}
+EXPORT_SYMBOL_GPL(coresight_remove_driver);
+
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 1874df7c6a..75962dae9a 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -4,6 +4,7 @@
*
* Author: Leo Yan <leo.yan@linaro.org>
*/
+#include <linux/acpi.h>
#include <linux/amba/bus.h>
#include <linux/coresight.h>
#include <linux/cpu.h>
@@ -18,6 +19,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/panic_notifier.h>
+#include <linux/platform_device.h>
#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/smp.h>
@@ -84,6 +86,7 @@
#define DEBUG_WAIT_TIMEOUT 32000
struct debug_drvdata {
+ struct clk *pclk;
void __iomem *base;
struct device *dev;
int cpu;
@@ -557,18 +560,12 @@ static void debug_func_exit(void)
debugfs_remove_recursive(debug_debugfs_dir);
}
-static int debug_probe(struct amba_device *adev, const struct amba_id *id)
+static int __debug_probe(struct device *dev, struct resource *res)
{
+ struct debug_drvdata *drvdata = dev_get_drvdata(dev);
void __iomem *base;
- struct device *dev = &adev->dev;
- struct debug_drvdata *drvdata;
- struct resource *res = &adev->res;
int ret;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
drvdata->cpu = coresight_get_cpu(dev);
if (drvdata->cpu < 0)
return drvdata->cpu;
@@ -579,10 +576,7 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
return -EBUSY;
}
- drvdata->dev = &adev->dev;
- amba_set_drvdata(adev, drvdata);
-
- /* Validity for the resource is already checked by the AMBA core */
+ drvdata->dev = dev;
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -629,10 +623,21 @@ err:
return ret;
}
-static void debug_remove(struct amba_device *adev)
+static int debug_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct device *dev = &adev->dev;
- struct debug_drvdata *drvdata = amba_get_drvdata(adev);
+ struct debug_drvdata *drvdata;
+
+ drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ amba_set_drvdata(adev, drvdata);
+ return __debug_probe(&adev->dev, &adev->res);
+}
+
+static void __debug_remove(struct device *dev)
+{
+ struct debug_drvdata *drvdata = dev_get_drvdata(dev);
per_cpu(debug_drvdata, drvdata->cpu) = NULL;
@@ -646,6 +651,11 @@ static void debug_remove(struct amba_device *adev)
debug_func_exit();
}
+static void debug_remove(struct amba_device *adev)
+{
+ __debug_remove(&adev->dev);
+}
+
static const struct amba_cs_uci_id uci_id_debug[] = {
{
/* CPU Debug UCI data */
@@ -677,7 +687,102 @@ static struct amba_driver debug_driver = {
.id_table = debug_ids,
};
-module_amba_driver(debug_driver);
+static int debug_platform_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct debug_drvdata *drvdata;
+ int ret = 0;
+
+ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
+
+ dev_set_drvdata(&pdev->dev, drvdata);
+ pm_runtime_get_noresume(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = __debug_probe(&pdev->dev, res);
+ if (ret) {
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+ }
+ return ret;
+}
+
+static void debug_platform_remove(struct platform_device *pdev)
+{
+ struct debug_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
+ __debug_remove(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id debug_platform_ids[] = {
+ {"ARMHC503", 0, 0, 0}, /* ARM CoreSight Debug */
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, debug_platform_ids);
+#endif
+
+#ifdef CONFIG_PM
+static int debug_runtime_suspend(struct device *dev)
+{
+ struct debug_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
+ return 0;
+}
+
+static int debug_runtime_resume(struct device *dev)
+{
+ struct debug_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops debug_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(debug_runtime_suspend, debug_runtime_resume, NULL)
+};
+
+static struct platform_driver debug_platform_driver = {
+ .probe = debug_platform_probe,
+ .remove_new = debug_platform_remove,
+ .driver = {
+ .name = "coresight-debug-platform",
+ .acpi_match_table = ACPI_PTR(debug_platform_ids),
+ .suppress_bind_attrs = true,
+ .pm = &debug_dev_pm_ops,
+ },
+};
+
+static int __init debug_init(void)
+{
+ return coresight_init_driver("debug", &debug_driver, &debug_platform_driver);
+}
+
+static void __exit debug_exit(void)
+{
+ coresight_remove_driver(&debug_driver, &debug_platform_driver);
+}
+module_init(debug_init);
+module_exit(debug_exit);
MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
MODULE_DESCRIPTION("ARM Coresight CPU Debug Driver");
diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index e805617020..d2b5a5718c 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -982,7 +982,6 @@ MODULE_DEVICE_TABLE(amba, cti_ids);
static struct amba_driver cti_driver = {
.drv = {
.name = "coresight-cti",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = cti_probe,
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 3aab182b56..7edd3f1d0d 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -844,7 +844,6 @@ MODULE_DEVICE_TABLE(amba, etb_ids);
static struct amba_driver etb_driver = {
.drv = {
.name = "coresight-etb10",
- .owner = THIS_MODULE,
.pm = &etb_dev_pm_ops,
.suppress_bind_attrs = true,
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 9d5c1391ff..8b362605d2 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -1008,7 +1008,6 @@ MODULE_DEVICE_TABLE(amba, etm_ids);
static struct amba_driver etm_driver = {
.drv = {
.name = "coresight-etm3x",
- .owner = THIS_MODULE,
.pm = &etm_dev_pm_ops,
.suppress_bind_attrs = true,
},
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index a0bdfabddb..bf01f01964 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2349,7 +2349,6 @@ MODULE_DEVICE_TABLE(amba, etm4_ids);
static struct amba_driver etm4x_amba_driver = {
.drv = {
.name = "coresight-etm4x",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = etm4_probe_amba,
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index ef1a0abfee..5a819c8970 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -36,6 +36,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
* struct funnel_drvdata - specifics associated to a funnel component
* @base: memory mapped base address for this component.
* @atclk: optional clock for the core parts of the funnel.
+ * @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework.
* @priority: port selection order.
* @spinlock: serialize enable/disable operations.
@@ -43,6 +44,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
struct funnel_drvdata {
void __iomem *base;
struct clk *atclk;
+ struct clk *pclk;
struct coresight_device *csdev;
unsigned long priority;
spinlock_t spinlock;
@@ -236,6 +238,10 @@ static int funnel_probe(struct device *dev, struct resource *res)
return ret;
}
+ drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
+
/*
* Map the device base for dynamic-funnel, which has been
* validated by AMBA core.
@@ -272,12 +278,13 @@ static int funnel_probe(struct device *dev, struct resource *res)
goto out_disable_clk;
}
- pm_runtime_put(dev);
ret = 0;
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
+ if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
return ret;
}
@@ -298,6 +305,9 @@ static int funnel_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
+
return 0;
}
@@ -308,6 +318,8 @@ static int funnel_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@@ -316,55 +328,61 @@ static const struct dev_pm_ops funnel_dev_pm_ops = {
SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL)
};
-static int static_funnel_probe(struct platform_device *pdev)
+static int funnel_platform_probe(struct platform_device *pdev)
{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- /* Static funnel do not have programming base */
- ret = funnel_probe(&pdev->dev, NULL);
-
- if (ret) {
- pm_runtime_put_noidle(&pdev->dev);
+ ret = funnel_probe(&pdev->dev, res);
+ pm_runtime_put(&pdev->dev);
+ if (ret)
pm_runtime_disable(&pdev->dev);
- }
return ret;
}
-static void static_funnel_remove(struct platform_device *pdev)
+static void funnel_platform_remove(struct platform_device *pdev)
{
+ struct funnel_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
funnel_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
}
-static const struct of_device_id static_funnel_match[] = {
+static const struct of_device_id funnel_match[] = {
{.compatible = "arm,coresight-static-funnel"},
{}
};
-MODULE_DEVICE_TABLE(of, static_funnel_match);
+MODULE_DEVICE_TABLE(of, funnel_match);
#ifdef CONFIG_ACPI
-static const struct acpi_device_id static_funnel_ids[] = {
- {"ARMHC9FE", 0, 0, 0},
+static const struct acpi_device_id funnel_acpi_ids[] = {
+ {"ARMHC9FE", 0, 0, 0}, /* ARM Coresight Static Funnel */
+ {"ARMHC9FF", 0, 0, 0}, /* ARM CoreSight Dynamic Funnel */
{},
};
-MODULE_DEVICE_TABLE(acpi, static_funnel_ids);
+MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids);
#endif
-static struct platform_driver static_funnel_driver = {
- .probe = static_funnel_probe,
- .remove_new = static_funnel_remove,
- .driver = {
- .name = "coresight-static-funnel",
+static struct platform_driver funnel_driver = {
+ .probe = funnel_platform_probe,
+ .remove_new = funnel_platform_remove,
+ .driver = {
+ .name = "coresight-funnel",
/* THIS_MODULE is taken care of by platform_driver_register() */
- .of_match_table = static_funnel_match,
- .acpi_match_table = ACPI_PTR(static_funnel_ids),
+ .of_match_table = funnel_match,
+ .acpi_match_table = ACPI_PTR(funnel_acpi_ids),
.pm = &funnel_dev_pm_ops,
.suppress_bind_attrs = true,
},
@@ -373,7 +391,13 @@ static struct platform_driver static_funnel_driver = {
static int dynamic_funnel_probe(struct amba_device *adev,
const struct amba_id *id)
{
- return funnel_probe(&adev->dev, &adev->res);
+ int ret;
+
+ ret = funnel_probe(&adev->dev, &adev->res);
+ if (!ret)
+ pm_runtime_put(&adev->dev);
+
+ return ret;
}
static void dynamic_funnel_remove(struct amba_device *adev)
@@ -399,7 +423,6 @@ MODULE_DEVICE_TABLE(amba, dynamic_funnel_ids);
static struct amba_driver dynamic_funnel_driver = {
.drv = {
.name = "coresight-dynamic-funnel",
- .owner = THIS_MODULE,
.pm = &funnel_dev_pm_ops,
.suppress_bind_attrs = true,
},
@@ -410,27 +433,12 @@ static struct amba_driver dynamic_funnel_driver = {
static int __init funnel_init(void)
{
- int ret;
-
- ret = platform_driver_register(&static_funnel_driver);
- if (ret) {
- pr_info("Error registering platform driver\n");
- return ret;
- }
-
- ret = amba_driver_register(&dynamic_funnel_driver);
- if (ret) {
- pr_info("Error registering amba driver\n");
- platform_driver_unregister(&static_funnel_driver);
- }
-
- return ret;
+ return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver);
}
static void __exit funnel_exit(void)
{
- platform_driver_unregister(&static_funnel_driver);
- amba_driver_unregister(&dynamic_funnel_driver);
+ coresight_remove_driver(&dynamic_funnel_driver, &funnel_driver);
}
module_init(funnel_init);
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index 9d550f5697..57a009552c 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -297,8 +297,10 @@ static int of_get_coresight_platform_data(struct device *dev,
continue;
ret = of_coresight_parse_endpoint(dev, ep, pdata);
- if (ret)
+ if (ret) {
+ of_node_put(ep);
return ret;
+ }
}
return 0;
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index eb365236f9..fc3617642b 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -222,6 +222,16 @@ static inline void *coresight_get_uci_data(const struct amba_id *id)
return uci_id->data;
}
+static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid)
+{
+ while (table->mask) {
+ if ((pid & table->mask) == table->id)
+ return coresight_get_uci_data(table);
+ table++;
+ };
+ return NULL;
+}
+
void coresight_release_platform_data(struct coresight_device *csdev,
struct device *dev,
struct coresight_platform_data *pdata);
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 73452d9dc1..3e55be9c84 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -31,6 +31,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
* @base: memory mapped base address for this component. Also indicates
* whether this one is programmable or not.
* @atclk: optional clock for the core parts of the replicator.
+ * @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework
* @spinlock: serialize enable/disable operations.
* @check_idfilter_val: check if the context is lost upon clock removal.
@@ -38,6 +39,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
struct replicator_drvdata {
void __iomem *base;
struct clk *atclk;
+ struct clk *pclk;
struct coresight_device *csdev;
spinlock_t spinlock;
bool check_idfilter_val;
@@ -243,6 +245,10 @@ static int replicator_probe(struct device *dev, struct resource *res)
return ret;
}
+ drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
+
/*
* Map the device base for dynamic-replicator, which has been
* validated by AMBA core
@@ -285,11 +291,12 @@ static int replicator_probe(struct device *dev, struct resource *res)
}
replicator_reset(drvdata);
- pm_runtime_put(dev);
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
+ if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
return ret;
}
@@ -301,29 +308,34 @@ static int replicator_remove(struct device *dev)
return 0;
}
-static int static_replicator_probe(struct platform_device *pdev)
+static int replicator_platform_probe(struct platform_device *pdev)
{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- /* Static replicators do not have programming base */
- ret = replicator_probe(&pdev->dev, NULL);
-
- if (ret) {
- pm_runtime_put_noidle(&pdev->dev);
+ ret = replicator_probe(&pdev->dev, res);
+ pm_runtime_put(&pdev->dev);
+ if (ret)
pm_runtime_disable(&pdev->dev);
- }
return ret;
}
-static void static_replicator_remove(struct platform_device *pdev)
+static void replicator_platform_remove(struct platform_device *pdev)
{
+ struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
replicator_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
@@ -334,6 +346,8 @@ static int replicator_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
return 0;
}
@@ -344,6 +358,8 @@ static int replicator_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@@ -353,31 +369,32 @@ static const struct dev_pm_ops replicator_dev_pm_ops = {
replicator_runtime_resume, NULL)
};
-static const struct of_device_id static_replicator_match[] = {
+static const struct of_device_id replicator_match[] = {
{.compatible = "arm,coresight-replicator"},
{.compatible = "arm,coresight-static-replicator"},
{}
};
-MODULE_DEVICE_TABLE(of, static_replicator_match);
+MODULE_DEVICE_TABLE(of, replicator_match);
#ifdef CONFIG_ACPI
-static const struct acpi_device_id static_replicator_acpi_ids[] = {
+static const struct acpi_device_id replicator_acpi_ids[] = {
{"ARMHC985", 0, 0, 0}, /* ARM CoreSight Static Replicator */
+ {"ARMHC98D", 0, 0, 0}, /* ARM CoreSight Dynamic Replicator */
{}
};
-MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids);
+MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids);
#endif
-static struct platform_driver static_replicator_driver = {
- .probe = static_replicator_probe,
- .remove_new = static_replicator_remove,
+static struct platform_driver replicator_driver = {
+ .probe = replicator_platform_probe,
+ .remove_new = replicator_platform_remove,
.driver = {
- .name = "coresight-static-replicator",
+ .name = "coresight-replicator",
/* THIS_MODULE is taken care of by platform_driver_register() */
- .of_match_table = of_match_ptr(static_replicator_match),
- .acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
+ .of_match_table = of_match_ptr(replicator_match),
+ .acpi_match_table = ACPI_PTR(replicator_acpi_ids),
.pm = &replicator_dev_pm_ops,
.suppress_bind_attrs = true,
},
@@ -386,7 +403,13 @@ static struct platform_driver static_replicator_driver = {
static int dynamic_replicator_probe(struct amba_device *adev,
const struct amba_id *id)
{
- return replicator_probe(&adev->dev, &adev->res);
+ int ret;
+
+ ret = replicator_probe(&adev->dev, &adev->res);
+ if (!ret)
+ pm_runtime_put(&adev->dev);
+
+ return ret;
}
static void dynamic_replicator_remove(struct amba_device *adev)
@@ -406,7 +429,6 @@ static struct amba_driver dynamic_replicator_driver = {
.drv = {
.name = "coresight-dynamic-replicator",
.pm = &replicator_dev_pm_ops,
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = dynamic_replicator_probe,
@@ -416,27 +438,12 @@ static struct amba_driver dynamic_replicator_driver = {
static int __init replicator_init(void)
{
- int ret;
-
- ret = platform_driver_register(&static_replicator_driver);
- if (ret) {
- pr_info("Error registering platform driver\n");
- return ret;
- }
-
- ret = amba_driver_register(&dynamic_replicator_driver);
- if (ret) {
- pr_info("Error registering amba driver\n");
- platform_driver_unregister(&static_replicator_driver);
- }
-
- return ret;
+ return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
}
static void __exit replicator_exit(void)
{
- platform_driver_unregister(&static_replicator_driver);
- amba_driver_unregister(&dynamic_replicator_driver);
+ coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver);
}
module_init(replicator_init);
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 974d37e5f9..117dbb4845 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -29,6 +29,7 @@
#include <linux/perf_event.h>
#include <linux/pm_runtime.h>
#include <linux/stm.h>
+#include <linux/platform_device.h>
#include "coresight-priv.h"
#include "coresight-trace-id.h"
@@ -115,6 +116,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
* struct stm_drvdata - specifics associated to an STM component
* @base: memory mapped base address for this component.
* @atclk: optional clock for the core parts of the STM.
+ * @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework.
* @spinlock: only one at a time pls.
* @chs: the channels accociated to this STM.
@@ -131,6 +133,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
struct stm_drvdata {
void __iomem *base;
struct clk *atclk;
+ struct clk *pclk;
struct coresight_device *csdev;
spinlock_t spinlock;
struct channel_space chs;
@@ -800,14 +803,22 @@ static void stm_init_generic_data(struct stm_drvdata *drvdata,
drvdata->stm.set_options = stm_generic_set_options;
}
-static int stm_probe(struct amba_device *adev, const struct amba_id *id)
+static const struct amba_id stm_ids[];
+
+static char *stm_csdev_name(struct coresight_device *csdev)
+{
+ u32 stm_pid = coresight_get_pid(&csdev->access);
+ void *uci_data = coresight_get_uci_data_from_amba(stm_ids, stm_pid);
+
+ return uci_data ? (char *)uci_data : "STM";
+}
+
+static int __stm_probe(struct device *dev, struct resource *res)
{
int ret, trace_id;
void __iomem *base;
- struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
struct stm_drvdata *drvdata;
- struct resource *res = &adev->res;
struct resource ch_res;
struct coresight_desc desc = { 0 };
@@ -819,12 +830,16 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+ drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
if (!IS_ERR(drvdata->atclk)) {
ret = clk_prepare_enable(drvdata->atclk);
if (ret)
return ret;
}
+
+ drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, res);
@@ -872,7 +887,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
ret = PTR_ERR(pdata);
goto stm_unregister;
}
- adev->dev.platform_data = pdata;
+ dev->platform_data = pdata;
desc.type = CORESIGHT_DEV_TYPE_SOURCE;
desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
@@ -893,10 +908,8 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
}
drvdata->traceid = (u8)trace_id;
- pm_runtime_put(&adev->dev);
-
dev_info(&drvdata->csdev->dev, "%s initialized\n",
- (char *)coresight_get_uci_data(id));
+ stm_csdev_name(drvdata->csdev));
return 0;
cs_unregister:
@@ -907,9 +920,20 @@ stm_unregister:
return ret;
}
-static void stm_remove(struct amba_device *adev)
+static int stm_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ int ret;
+
+ ret = __stm_probe(&adev->dev, &adev->res);
+ if (!ret)
+ pm_runtime_put(&adev->dev);
+
+ return ret;
+}
+
+static void __stm_remove(struct device *dev)
{
- struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+ struct stm_drvdata *drvdata = dev_get_drvdata(dev);
coresight_trace_id_put_system_id(drvdata->traceid);
coresight_unregister(drvdata->csdev);
@@ -917,6 +941,11 @@ static void stm_remove(struct amba_device *adev)
stm_unregister_device(&drvdata->stm);
}
+static void stm_remove(struct amba_device *adev)
+{
+ __stm_remove(&adev->dev);
+}
+
#ifdef CONFIG_PM
static int stm_runtime_suspend(struct device *dev)
{
@@ -925,6 +954,8 @@ static int stm_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
return 0;
}
@@ -935,6 +966,8 @@ static int stm_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@@ -954,7 +987,6 @@ MODULE_DEVICE_TABLE(amba, stm_ids);
static struct amba_driver stm_driver = {
.drv = {
.name = "coresight-stm",
- .owner = THIS_MODULE,
.pm = &stm_dev_pm_ops,
.suppress_bind_attrs = true,
},
@@ -963,7 +995,66 @@ static struct amba_driver stm_driver = {
.id_table = stm_ids,
};
-module_amba_driver(stm_driver);
+static int stm_platform_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ int ret = 0;
+
+ pm_runtime_get_noresume(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = __stm_probe(&pdev->dev, res);
+ pm_runtime_put(&pdev->dev);
+ if (ret)
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static void stm_platform_remove(struct platform_device *pdev)
+{
+ struct stm_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
+ __stm_remove(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id stm_acpi_ids[] = {
+ {"ARMHC502", 0, 0, 0}, /* ARM CoreSight STM */
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, stm_acpi_ids);
+#endif
+
+static struct platform_driver stm_platform_driver = {
+ .probe = stm_platform_probe,
+ .remove_new = stm_platform_remove,
+ .driver = {
+ .name = "coresight-stm-platform",
+ .acpi_match_table = ACPI_PTR(stm_acpi_ids),
+ .suppress_bind_attrs = true,
+ .pm = &stm_dev_pm_ops,
+ },
+};
+
+static int __init stm_init(void)
+{
+ return coresight_init_driver("stm", &stm_driver, &stm_platform_driver);
+}
+
+static void __exit stm_exit(void)
+{
+ coresight_remove_driver(&stm_driver, &stm_platform_driver);
+}
+module_init(stm_init);
+module_exit(stm_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 72005b0c63..4f11a739ae 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -4,6 +4,7 @@
* Description: CoreSight Trace Memory Controller driver
*/
+#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -24,6 +25,8 @@
#include <linux/of.h>
#include <linux/coresight.h>
#include <linux/amba/bus.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
#include "coresight-priv.h"
#include "coresight-tmc.h"
@@ -360,7 +363,32 @@ static const struct attribute_group *coresight_etr_groups[] = {
static inline bool tmc_etr_can_use_sg(struct device *dev)
{
- return fwnode_property_present(dev->fwnode, "arm,scatter-gather");
+ int ret;
+ u8 val_u8;
+
+ /*
+ * Presence of the property 'arm,scatter-gather' is checked
+ * on the platform for the feature support, rather than its
+ * value.
+ */
+ if (is_of_node(dev->fwnode)) {
+ return fwnode_property_present(dev->fwnode, "arm,scatter-gather");
+ } else if (is_acpi_device_node(dev->fwnode)) {
+ /*
+ * TMC_DEVID_NOSCAT test in tmc_etr_setup_caps(), has already ensured
+ * this property is only checked for Coresight SoC 400 TMC configured
+ * as ETR.
+ */
+ ret = fwnode_property_read_u8(dev->fwnode, "arm-armhc97c-sg-enable", &val_u8);
+ if (!ret)
+ return !!val_u8;
+
+ if (fwnode_property_present(dev->fwnode, "arm,scatter-gather")) {
+ pr_warn_once("Deprecated ACPI property - arm,scatter-gather\n");
+ return true;
+ }
+ }
+ return false;
}
static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
@@ -370,16 +398,23 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
return (auth & TMC_AUTH_NSID_MASK) == 0x3;
}
+static const struct amba_id tmc_ids[];
+
/* Detect and initialise the capabilities of a TMC ETR */
-static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
+static int tmc_etr_setup_caps(struct device *parent, u32 devid,
+ struct csdev_access *access)
{
int rc;
- u32 dma_mask = 0;
+ u32 tmc_pid, dma_mask = 0;
struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
+ void *dev_caps;
if (!tmc_etr_has_non_secure_access(drvdata))
return -EACCES;
+ tmc_pid = coresight_get_pid(access);
+ dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
+
/* Set the unadvertised capabilities */
tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
@@ -437,24 +472,17 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev)
return burst_size;
}
-static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
+static int __tmc_probe(struct device *dev, struct resource *res)
{
int ret = 0;
u32 devid;
void __iomem *base;
- struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
- struct tmc_drvdata *drvdata;
- struct resource *res = &adev->res;
+ struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
struct coresight_desc desc = { 0 };
struct coresight_dev_list *dev_list = NULL;
ret = -ENOMEM;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- goto out;
-
- dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
base = devm_ioremap_resource(dev, res);
@@ -497,8 +525,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_SYSMEM;
desc.ops = &tmc_etr_cs_ops;
- ret = tmc_etr_setup_caps(dev, devid,
- coresight_get_uci_data(id));
+ ret = tmc_etr_setup_caps(dev, devid, &desc.access);
if (ret)
goto out;
idr_init(&drvdata->idr);
@@ -530,7 +557,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
ret = PTR_ERR(pdata);
goto out;
}
- adev->dev.platform_data = pdata;
+ dev->platform_data = pdata;
desc.pdata = pdata;
drvdata->csdev = coresight_register(&desc);
@@ -545,12 +572,27 @@ 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;
}
+static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ struct tmc_drvdata *drvdata;
+ int ret;
+
+ drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ amba_set_drvdata(adev, drvdata);
+ ret = __tmc_probe(&adev->dev, &adev->res);
+ if (!ret)
+ pm_runtime_put(&adev->dev);
+
+ return ret;
+}
+
static void tmc_shutdown(struct amba_device *adev)
{
unsigned long flags;
@@ -573,9 +615,9 @@ out:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
}
-static void tmc_remove(struct amba_device *adev)
+static void __tmc_remove(struct device *dev)
{
- struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+ struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
/*
* Since misc_open() holds a refcount on the f_ops, which is
@@ -586,6 +628,11 @@ static void tmc_remove(struct amba_device *adev)
coresight_unregister(drvdata->csdev);
}
+static void tmc_remove(struct amba_device *adev)
+{
+ __tmc_remove(&adev->dev);
+}
+
static const struct amba_id tmc_ids[] = {
CS_AMBA_ID(0x000bb961),
/* Coresight SoC 600 TMC-ETR/ETS */
@@ -602,7 +649,6 @@ MODULE_DEVICE_TABLE(amba, tmc_ids);
static struct amba_driver tmc_driver = {
.drv = {
.name = "coresight-tmc",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = tmc_probe,
@@ -611,7 +657,101 @@ static struct amba_driver tmc_driver = {
.id_table = tmc_ids,
};
-module_amba_driver(tmc_driver);
+static int tmc_platform_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct tmc_drvdata *drvdata;
+ int ret = 0;
+
+ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
+
+ dev_set_drvdata(&pdev->dev, drvdata);
+ pm_runtime_get_noresume(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = __tmc_probe(&pdev->dev, res);
+ pm_runtime_put(&pdev->dev);
+ if (ret)
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static void tmc_platform_remove(struct platform_device *pdev)
+{
+ struct tmc_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
+ __tmc_remove(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+}
+
+#ifdef CONFIG_PM
+static int tmc_runtime_suspend(struct device *dev)
+{
+ struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
+ return 0;
+}
+
+static int tmc_runtime_resume(struct device *dev)
+{
+ struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops tmc_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(tmc_runtime_suspend, tmc_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id tmc_acpi_ids[] = {
+ {"ARMHC501", 0, 0, 0}, /* ARM CoreSight ETR */
+ {"ARMHC97C", 0, 0, 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, tmc_acpi_ids);
+#endif
+
+static struct platform_driver tmc_platform_driver = {
+ .probe = tmc_platform_probe,
+ .remove_new = tmc_platform_remove,
+ .driver = {
+ .name = "coresight-tmc-platform",
+ .acpi_match_table = ACPI_PTR(tmc_acpi_ids),
+ .suppress_bind_attrs = true,
+ .pm = &tmc_dev_pm_ops,
+ },
+};
+
+static int __init tmc_init(void)
+{
+ return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver);
+}
+
+static void __exit tmc_exit(void)
+{
+ coresight_remove_driver(&tmc_driver, &tmc_platform_driver);
+}
+module_init(tmc_init);
+module_exit(tmc_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index cef979c897..c77763b49d 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -166,6 +166,7 @@ struct etr_buf {
/**
* struct tmc_drvdata - specifics associated to an TMC component
+ * @pclk: APB clock if present, otherwise NULL
* @base: memory mapped base address for this component.
* @csdev: component vitals needed by the framework.
* @miscdev: specifics to handle "/dev/xyz.tmc" entry.
@@ -189,6 +190,7 @@ struct etr_buf {
* @perf_buf: PERF buffer for ETR.
*/
struct tmc_drvdata {
+ struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
struct miscdevice miscdev;
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 7739bc7adc..bfca103f9f 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -333,7 +333,6 @@ static struct amba_id tpda_ids[] = {
static struct amba_driver tpda_driver = {
.drv = {
.name = "coresight-tpda",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = tpda_probe,
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index a9708ab0d4..0726f88425 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -1310,7 +1310,6 @@ static struct amba_id tpdm_ids[] = {
static struct amba_driver tpdm_driver = {
.drv = {
.name = "coresight-tpdm",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = tpdm_probe,
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 29024f880f..b048e146fb 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -5,17 +5,19 @@
* Description: CoreSight Trace Port Interface Unit driver
*/
+#include <linux/acpi.h>
+#include <linux/amba/bus.h>
#include <linux/atomic.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
#include <linux/device.h>
-#include <linux/io.h>
#include <linux/err.h>
-#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <linux/coresight.h>
-#include <linux/amba/bus.h>
-#include <linux/clk.h>
+#include <linux/slab.h>
#include "coresight-priv.h"
@@ -52,11 +54,13 @@ DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu");
/*
* @base: memory mapped base address for this component.
* @atclk: optional clock for the core parts of the TPIU.
+ * @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework.
*/
struct tpiu_drvdata {
void __iomem *base;
struct clk *atclk;
+ struct clk *pclk;
struct coresight_device *csdev;
spinlock_t spinlock;
};
@@ -122,14 +126,12 @@ static const struct coresight_ops tpiu_cs_ops = {
.sink_ops = &tpiu_sink_ops,
};
-static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
+static int __tpiu_probe(struct device *dev, struct resource *res)
{
int ret;
void __iomem *base;
- struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
struct tpiu_drvdata *drvdata;
- struct resource *res = &adev->res;
struct coresight_desc desc = { 0 };
desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
@@ -142,12 +144,16 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+ drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
if (!IS_ERR(drvdata->atclk)) {
ret = clk_prepare_enable(drvdata->atclk);
if (ret)
return ret;
}
+
+ drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
@@ -173,21 +179,34 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
desc.dev = dev;
drvdata->csdev = coresight_register(&desc);
- if (!IS_ERR(drvdata->csdev)) {
- pm_runtime_put(&adev->dev);
+ if (!IS_ERR(drvdata->csdev))
return 0;
- }
return PTR_ERR(drvdata->csdev);
}
-static void tpiu_remove(struct amba_device *adev)
+static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+ int ret;
+
+ ret = __tpiu_probe(&adev->dev, &adev->res);
+ if (!ret)
+ pm_runtime_put(&adev->dev);
+ return ret;
+}
+
+static void __tpiu_remove(struct device *dev)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
coresight_unregister(drvdata->csdev);
}
+static void tpiu_remove(struct amba_device *adev)
+{
+ __tpiu_remove(&adev->dev);
+}
+
#ifdef CONFIG_PM
static int tpiu_runtime_suspend(struct device *dev)
{
@@ -196,6 +215,8 @@ static int tpiu_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
return 0;
}
@@ -206,6 +227,8 @@ static int tpiu_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
+ if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@@ -236,7 +259,6 @@ MODULE_DEVICE_TABLE(amba, tpiu_ids);
static struct amba_driver tpiu_driver = {
.drv = {
.name = "coresight-tpiu",
- .owner = THIS_MODULE,
.pm = &tpiu_dev_pm_ops,
.suppress_bind_attrs = true,
},
@@ -245,7 +267,66 @@ static struct amba_driver tpiu_driver = {
.id_table = tpiu_ids,
};
-module_amba_driver(tpiu_driver);
+static int tpiu_platform_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ int ret;
+
+ pm_runtime_get_noresume(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = __tpiu_probe(&pdev->dev, res);
+ pm_runtime_put(&pdev->dev);
+ if (ret)
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static void tpiu_platform_remove(struct platform_device *pdev)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ if (WARN_ON(!drvdata))
+ return;
+
+ __tpiu_remove(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (!IS_ERR_OR_NULL(drvdata->pclk))
+ clk_put(drvdata->pclk);
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id tpiu_acpi_ids[] = {
+ {"ARMHC979", 0, 0, 0}, /* ARM CoreSight TPIU */
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids);
+#endif
+
+static struct platform_driver tpiu_platform_driver = {
+ .probe = tpiu_platform_probe,
+ .remove_new = tpiu_platform_remove,
+ .driver = {
+ .name = "coresight-tpiu-platform",
+ .acpi_match_table = ACPI_PTR(tpiu_acpi_ids),
+ .suppress_bind_attrs = true,
+ .pm = &tpiu_dev_pm_ops,
+ },
+};
+
+static int __init tpiu_init(void)
+{
+ return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver);
+}
+
+static void __exit tpiu_exit(void)
+{
+ coresight_remove_driver(&tpiu_driver, &tpiu_platform_driver);
+}
+module_init(tpiu_init);
+module_exit(tpiu_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 6136776482..96a32b2136 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -17,6 +17,7 @@
#include <asm/barrier.h>
#include <asm/cpufeature.h>
+#include <linux/vmalloc.h>
#include "coresight-self-hosted-trace.h"
#include "coresight-trbe.h"