summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShashank Mittal <mittals@codeaurora.org>2016-02-24 16:44:00 -0800
committerKyle Yan <kyan@codeaurora.org>2016-06-20 15:05:34 -0700
commit195ae4dadc6aba3decca56d4180ee7fedb891120 (patch)
tree135fe191d16921a8bc3f313c2c3a5eff6b5c775b
parente34081c6651914fe09cdb465411105ffe7f91e9c (diff)
coresight-tmc: allocate memory for register and buffer dump
Add code to allocate memory for dumping TMC register and buffer data. These memory locations can be used to store TMC registers and buffer information after a crash. Change-Id: I8e98178110efa8e455a329e358c471757e87f2d1 Signed-off-by: Shashank Mittal <mittals@codeaurora.org>
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 27b6f1820223..08743533c568 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -32,6 +32,7 @@
#include <linux/msm-sps.h>
#include <linux/usb_bam.h>
#include <linux/usb/usb_qdss.h>
+#include <soc/qcom/memory_dump.h>
#include "coresight-priv.h"
@@ -162,6 +163,8 @@ struct tmc_etr_bam_data {
* @enable: this TMC is being used.
* @config_type: TMC variant, must be of type @tmc_config_type.
* @trigger_cntr: amount of words to store after a trigger.
+ * @reg_data: MSM memory dump data to store TMC registers.
+ * @buf_data: MSM memory dump data to store ETF/ETB buffer.
*/
struct tmc_drvdata {
void __iomem *base;
@@ -188,6 +191,8 @@ struct tmc_drvdata {
struct usb_qdss_ch *usbch;
struct tmc_etr_bam_data *bamdata;
bool enable_to_bam;
+ struct msm_dump_data reg_data;
+ struct msm_dump_data buf_data;
};
static void tmc_wait_for_ready(struct tmc_drvdata *drvdata)
@@ -1606,6 +1611,67 @@ static struct attribute *coresight_etf_attrs[] = {
};
ATTRIBUTE_GROUPS(coresight_etf);
+static int tmc_etf_set_buf_dump(struct tmc_drvdata *drvdata)
+{
+ int ret;
+ struct msm_dump_entry dump_entry;
+ static int count;
+
+ drvdata->buf_data.addr = virt_to_phys(drvdata->buf);
+ drvdata->buf_data.len = drvdata->size;
+ dump_entry.id = MSM_DUMP_DATA_TMC_ETF + count;
+ dump_entry.addr = virt_to_phys(&drvdata->buf_data);
+
+ ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS,
+ &dump_entry);
+ if (ret)
+ return ret;
+
+ count++;
+
+ return 0;
+}
+
+static int tmc_set_reg_dump(struct tmc_drvdata *drvdata)
+{
+ int ret;
+ void *baddr;
+ struct amba_device *adev;
+ struct resource *res;
+ struct device *dev = drvdata->dev;
+ struct msm_dump_entry dump_entry;
+ uint32_t size;
+ static int count;
+
+ adev = to_amba_device(dev);
+ if (!adev)
+ return -EINVAL;
+
+ res = &adev->res;
+ size = resource_size(res);
+
+ baddr = devm_kzalloc(dev, size, GFP_KERNEL);
+ if (!baddr)
+ return -ENOMEM;
+
+ drvdata->reg_data.addr = virt_to_phys(baddr);
+ drvdata->reg_data.len = size;
+
+ dump_entry.id = MSM_DUMP_DATA_TMC_REG + count;
+ dump_entry.addr = virt_to_phys(&drvdata->reg_data);
+
+ ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS,
+ &dump_entry);
+ if (ret) {
+ devm_kfree(dev, baddr);
+ return ret;
+ }
+
+ count++;
+
+ return 0;
+}
+
static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
@@ -1671,8 +1737,17 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
drvdata->buf = devm_kzalloc(dev, drvdata->size, GFP_KERNEL);
if (!drvdata->buf)
return -ENOMEM;
+
+ ret = tmc_etf_set_buf_dump(drvdata);
+ if (ret)
+ dev_err(dev, "TMC ETF-ETB dump setup failed. ret: %d\n",
+ ret);
}
+ ret = tmc_set_reg_dump(drvdata);
+ if (ret)
+ dev_err(dev, "TMC REG dump setup failed. ret: %d\n", ret);
+
pdata->default_sink = of_property_read_bool(np, "arm,default-sink");
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);