diff options
| author | Shashank Mittal <mittals@codeaurora.org> | 2016-02-24 16:44:00 -0800 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-20 15:05:34 -0700 |
| commit | 195ae4dadc6aba3decca56d4180ee7fedb891120 (patch) | |
| tree | 135fe191d16921a8bc3f313c2c3a5eff6b5c775b | |
| parent | e34081c6651914fe09cdb465411105ffe7f91e9c (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.c | 75 |
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); |
