summaryrefslogtreecommitdiff
path: root/drivers/hwtracing/coresight/coresight-tmc-etf.c
diff options
context:
space:
mode:
authorMathieu Poirier <mathieu.poirier@linaro.org>2016-05-03 11:33:51 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-05-03 14:59:30 -0700
commit4525412a5046692abb7a0588589d8ed2c20585e0 (patch)
tree51bdb6bd7d2ef617e6dbcc60a0fae2f0e8483a33 /drivers/hwtracing/coresight/coresight-tmc-etf.c
parent6c6ed1e244c0530fb76a8b52024f199f398ef100 (diff)
coresight: tmc: making prepare/unprepare functions generic
Dealing with HW related matters in tmc_read_prepare/unprepare becomes convoluted when many cases need to be handled distinctively. As such moving processing related to HW setup to individual driver files and keep the core driver generic. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing/coresight/coresight-tmc-etf.c')
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etf.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 467d19221f7b..91e43572ce9f 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -71,7 +71,7 @@ static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata)
}
}
-void tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
+static void tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
{
CS_UNLOCK(drvdata->base);
@@ -202,3 +202,63 @@ const struct coresight_ops tmc_etf_cs_ops = {
.sink_ops = &tmc_etf_sink_ops,
.link_ops = &tmc_etf_link_ops,
};
+
+int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
+{
+ enum tmc_mode mode;
+ int ret = 0;
+ unsigned long flags;
+
+ /* config types are set a boot time and never change */
+ if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
+ drvdata->config_type != TMC_CONFIG_TYPE_ETF))
+ return -EINVAL;
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+
+ /* There is no point in reading a TMC in HW FIFO mode */
+ mode = readl_relaxed(drvdata->base + TMC_MODE);
+ if (mode != TMC_MODE_CIRCULAR_BUFFER) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Disable the TMC if need be */
+ if (drvdata->enable)
+ tmc_etb_disable_hw(drvdata);
+
+ drvdata->reading = true;
+out:
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+ return ret;
+}
+
+int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
+{
+ enum tmc_mode mode;
+ unsigned long flags;
+
+ /* config types are set a boot time and never change */
+ if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
+ drvdata->config_type != TMC_CONFIG_TYPE_ETF))
+ return -EINVAL;
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+
+ /* There is no point in reading a TMC in HW FIFO mode */
+ mode = readl_relaxed(drvdata->base + TMC_MODE);
+ if (mode != TMC_MODE_CIRCULAR_BUFFER) {
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ return -EINVAL;
+ }
+
+ /* Re-enable the TMC if need be */
+ if (drvdata->enable)
+ tmc_etb_enable_hw(drvdata);
+
+ drvdata->reading = false;
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+ return 0;
+}