* 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.
* @cpu: the cpu this component is affined to.
struct etm_drvdata {
void __iomem *base;
struct device *dev;
+ struct clk *atclk;
struct coresight_device *csdev;
spinlock_t spinlock;
int cpu;
#include <linux/amba/bus.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
+#include <linux/clk.h>
#include <asm/sections.h>
#include "coresight-etm.h"
}
pm_runtime_get_sync(drvdata->dev);
-
spin_lock_irqsave(&drvdata->spinlock, flags);
CS_UNLOCK(drvdata->base);
spin_lock_init(&drvdata->spinlock);
+ drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+ if (!IS_ERR(drvdata->atclk)) {
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ return ret;
+ }
+
drvdata->cpu = pdata ? pdata->cpu : 0;
get_online_cpus();
return 0;
}
+#ifdef CONFIG_PM
+static int etm_runtime_suspend(struct device *dev)
+{
+ struct etm_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_disable_unprepare(drvdata->atclk);
+
+ return 0;
+}
+
+static int etm_runtime_resume(struct device *dev)
+{
+ struct etm_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops etm_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(etm_runtime_suspend, etm_runtime_resume, NULL)
+};
+
static struct amba_id etm_ids[] = {
{ /* ETM 3.3 */
.id = 0x0003b921,
.drv = {
.name = "coresight-etm3x",
.owner = THIS_MODULE,
+ .pm = &etm_dev_pm_ops,
},
.probe = etm_probe,
.remove = etm_remove,