Loading arch/arm/mach-msm/msm_cache_dump.c +100 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/dma-mapping.h> #include <linux/slab.h> #include <soc/qcom/scm.h> #include <asm/cacheflush.h> #include <mach/msm_cache_dump.h> Loading Loading @@ -65,13 +66,17 @@ static int msm_cache_dump_probe(struct platform_device *pdev) { struct msm_cache_dump_platform_data *d = pdev->dev.platform_data; struct msm_client_dump l1_dump_entry, l2_dump_entry; int ret; struct msm_dump_entry dump_entry; struct msm_dump_data *l1_inst_data, *l1_data_data, *l2_data; int ret, cpu; struct { unsigned long buf; unsigned long size; } l1_cache_data; u32 l1_size, l2_size; unsigned long total_size; u32 l1_inst_size, l1_data_size; phys_addr_t l1_inst_start, l1_data_start, l2_start; if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, Loading Loading @@ -130,6 +135,7 @@ static int msm_cache_dump_probe(struct platform_device *pdev) __func__, ret); #endif if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { l1_dump_entry.id = MSM_L1_CACHE; l1_dump_entry.start_addr = msm_cache_dump_addr; l1_dump_entry.end_addr = l1_dump_entry.start_addr + l1_size - 1; Loading @@ -145,10 +151,91 @@ static int msm_cache_dump_probe(struct platform_device *pdev) ret = msm_dump_tbl_register(&l2_dump_entry); if (ret) pr_err("Could not register L2 dump area: %d\n", ret); } else { l1_inst_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!l1_inst_data) { pr_err("l1 inst data structure allocation failed\n"); ret = -ENOMEM; goto err0; } l1_data_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!l1_data_data) { pr_err("l1 data data structure allocation failed\n"); ret = -ENOMEM; goto err1; } l1_inst_start = msm_cache_dump_addr; l1_data_start = msm_cache_dump_addr + (l1_size / 2); l1_inst_size = l1_size / (num_present_cpus() * 2); l1_data_size = l1_inst_size; for_each_cpu(cpu, cpu_present_mask) { l1_inst_data[cpu].addr = l1_inst_start + cpu * l1_inst_size; l1_inst_data[cpu].len = l1_inst_size; dump_entry.id = MSM_DUMP_DATA_L1_INST_CACHE + cpu; dump_entry.addr = virt_to_phys(&l1_inst_data[cpu]); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffers in case of error since * registration may have succeeded for some cpus. */ if (ret) pr_err("cpu %d l1 inst dump setup failed\n", cpu); l1_data_data[cpu].addr = l1_data_start + cpu * l1_data_size; l1_data_data[cpu].len = l1_data_size; dump_entry.id = MSM_DUMP_DATA_L1_DATA_CACHE + cpu; dump_entry.addr = virt_to_phys(&l1_data_data[cpu]); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffers in case of error since * registration may have succeeded for some cpus. */ if (ret) pr_err("cpu %d l1 data dump setup failed\n", cpu); } l2_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!l2_data) { pr_err("l2 data structure allocation failed\n"); ret = -ENOMEM; goto err2; } l2_start = msm_cache_dump_addr + l1_size; l2_data->addr = l2_start; l2_data->len = l2_size; dump_entry.id = MSM_DUMP_DATA_L2_CACHE; dump_entry.addr = virt_to_phys(l2_data); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); if (ret) pr_err("l2 dump setup failed\n"); } atomic_notifier_chain_register(&panic_notifier_list, &msm_cache_dump_blk); return 0; err2: kfree(l1_data_data); err1: kfree(l1_inst_data); err0: dma_free_coherent(&pdev->dev, total_size, msm_cache_dump_vaddr, msm_cache_dump_addr); return ret; } static int msm_cache_dump_remove(struct platform_device *pdev) Loading drivers/coresight/coresight-etm.c +30 −11 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ struct etm_drvdata { bool pcsave_sticky_enable; bool pcsave_boot_enable; bool round_robin; struct msm_dump_data reg_data; }; static struct etm_drvdata *etmdrvdata[NR_CPUS]; Loading Loading @@ -2111,6 +2112,7 @@ static int etm_probe(struct platform_device *pdev) static int count; void *baddr; struct msm_client_dump dump; struct msm_dump_entry dump_entry; struct coresight_desc *desc; if (coresight_fuse_access_disabled() || Loading Loading @@ -2194,20 +2196,37 @@ static int etm_probe(struct platform_device *pdev) drvdata->round_robin = of_property_read_bool(pdev->dev.of_node, "qcom,round-robin"); if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL); if (baddr) { *(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER; dump.id = MSM_ETM0_REG + drvdata->cpu; dump.start_addr = virt_to_phys(baddr); dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size; ret = msm_dump_tbl_register(&dump); if (ret) { devm_kfree(dev, baddr); dev_err(dev, "ETM REG dump setup failed/unsupported\n"); dev_err(dev, "ETM REG dump setup failed\n"); } } else { dev_err(dev, "ETM REG dump space allocation failed\n"); } } else { baddr = devm_kzalloc(dev, reg_size, GFP_KERNEL); if (baddr) { drvdata->reg_data.addr = virt_to_phys(baddr); drvdata->reg_data.len = reg_size; dump_entry.id = MSM_DUMP_DATA_ETM_REG + drvdata->cpu; 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); dev_err(dev, "ETM REG dump setup failed\n"); } } else { dev_err(dev, "ETM REG dump space allocation failed\n"); } } desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) { Loading drivers/coresight/coresight-tmc.c +101 −37 Original line number Diff line number Diff line Loading @@ -152,7 +152,9 @@ struct tmc_drvdata { bool reading; bool aborting; char *reg_buf; struct msm_dump_data reg_data; char *buf; struct msm_dump_data buf_data; dma_addr_t paddr; void __iomem *vaddr; uint32_t size; Loading Loading @@ -647,6 +649,12 @@ static void __tmc_reg_dump(struct tmc_drvdata *drvdata) return; reg_hdr = drvdata->reg_buf - PAGE_SIZE; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(reg_hdr + TMC_REG_DUMP_VER_OFF) = TMC_REG_DUMP_VER; else drvdata->reg_data.version = TMC_REG_DUMP_VER; reg_buf = (uint32_t *)drvdata->reg_buf; reg_buf[1] = tmc_readl(drvdata, TMC_RSZ); Loading Loading @@ -688,7 +696,11 @@ static void __tmc_reg_dump(struct tmc_drvdata *drvdata) reg_buf[1022] = tmc_readl(drvdata, CORESIGHT_COMPIDR2); reg_buf[1023] = tmc_readl(drvdata, CORESIGHT_COMPIDR3); *(uint32_t *)(reg_hdr + TMC_REG_DUMP_MAGIC_OFF) = TMC_REG_DUMP_MAGIC; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(reg_hdr + TMC_REG_DUMP_MAGIC_OFF) = TMC_REG_DUMP_MAGIC; else drvdata->reg_data.magic = TMC_REG_DUMP_MAGIC; } static void __tmc_etb_dump(struct tmc_drvdata *drvdata) Loading @@ -700,6 +712,13 @@ static void __tmc_etb_dump(struct tmc_drvdata *drvdata) uint32_t read_data; int i; hdr = drvdata->buf - PAGE_SIZE; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(hdr + TMC_ETFETB_DUMP_VER_OFF) = TMC_ETFETB_DUMP_VER; else drvdata->buf_data.version = TMC_ETFETB_DUMP_VER; memwidth = BMVAL(tmc_readl(drvdata, CORESIGHT_DEVID), 8, 10); if (memwidth == TMC_MEM_INTF_WIDTH_32BITS) memwords = 1; Loading @@ -723,9 +742,11 @@ static void __tmc_etb_dump(struct tmc_drvdata *drvdata) out: if (drvdata->aborting) { hdr = drvdata->buf - PAGE_SIZE; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(hdr + TMC_ETFETB_DUMP_MAGIC_OFF) = TMC_ETFETB_DUMP_MAGIC; else drvdata->buf_data.magic = TMC_ETFETB_DUMP_MAGIC; } } Loading Loading @@ -1636,6 +1657,7 @@ static int tmc_probe(struct platform_device *pdev) static int count; void *baddr; struct msm_client_dump dump; struct msm_dump_entry dump_entry; struct coresight_cti_data *ctidata; struct coresight_desc *desc; Loading Loading @@ -1716,44 +1738,86 @@ static int tmc_probe(struct platform_device *pdev) if (ret) goto err1; } else { if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { baddr = devm_kzalloc(dev, PAGE_SIZE + drvdata->size, GFP_KERNEL); if (!baddr) return -ENOMEM; drvdata->buf = baddr + PAGE_SIZE; *(uint32_t *)(baddr + TMC_ETFETB_DUMP_VER_OFF) = TMC_ETFETB_DUMP_VER; dump.id = MSM_TMC_ETFETB + etfetb_count; dump.start_addr = virt_to_phys(baddr); dump.end_addr = dump.start_addr + PAGE_SIZE + drvdata->size; dump.end_addr = dump.start_addr + PAGE_SIZE + drvdata->size; ret = msm_dump_tbl_register(&dump); /* * Don't free the buffer in case of error since it can still * be used to provide dump collection via the device node or * as part of abort. * Don't free the buffer in case of error since it can * still be used to provide dump collection via the * device node or as part of abort. */ if (ret) dev_info(dev, "TMC ETF-ETB dump setup failed\n"); dev_err(dev, "TMC ETF-ETB dump setup failed\n"); } else { drvdata->buf = devm_kzalloc(dev, drvdata->size, GFP_KERNEL); if (!drvdata->buf) return -ENOMEM; drvdata->buf_data.addr = virt_to_phys(drvdata->buf); drvdata->buf_data.len = drvdata->size; dump_entry.id = MSM_DUMP_DATA_TMC_ETF + etfetb_count; dump_entry.addr = virt_to_phys(&drvdata->buf_data); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffer in case of error since it can * still be used to provide dump collection via the * device node or as part of abort. */ if (ret) dev_err(dev, "TMC ETF-ETB dump setup failed\n"); } etfetb_count++; } if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL); if (baddr) { drvdata->reg_buf = baddr + PAGE_SIZE; *(uint32_t *)(baddr + TMC_REG_DUMP_VER_OFF) = TMC_REG_DUMP_VER; dump.id = MSM_TMC0_REG + count; dump.start_addr = virt_to_phys(baddr); dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size; ret = msm_dump_tbl_register(&dump); /* * Don't free the buffer in case of error since it can still * be used to dump registers as part of abort to aid post crash * parsing. * Don't free the buffer in case of error since it can * still be used to dump registers as part of abort to * aid post crash parsing. */ if (ret) dev_info(dev, "TMC REG dump setup failed\n"); dev_err(dev, "TMC REG dump setup failed\n"); } else { dev_info(dev, "TMC REG dump space allocation failed\n"); dev_err(dev, "TMC REG dump allocation failed\n"); } } else { drvdata->reg_buf = devm_kzalloc(dev, reg_size, GFP_KERNEL); if (drvdata->reg_buf) { drvdata->reg_data.addr = virt_to_phys(drvdata->reg_buf); drvdata->reg_data.len = reg_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); /* * Don't free the buffer in case of error since it can * still be used to dump registers as part of abort to * aid post crash parsing. */ if (ret) dev_err(dev, "TMC REG dump setup failed\n"); } else { dev_err(dev, "TMC REG dump allocation failed\n"); } } count++; Loading drivers/soc/qcom/watchdog_v2.c +65 −21 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #define MASK_SIZE 32 #define SCM_SET_REGSAVE_CMD 0x2 #define SCM_SVC_SEC_WDOG_DIS 0x7 #define MAX_CPU_CTX_SIZE 512 static struct workqueue_struct *wdog_wq; Loading Loading @@ -359,12 +360,17 @@ static irqreturn_t wdog_ppi_bark(int irq, void *dev_id) static void configure_bark_dump(struct msm_watchdog_data *wdog_dd) { int ret; struct msm_client_dump dump_entry; struct msm_client_dump cpu_dump_entry; struct msm_dump_entry dump_entry; struct msm_dump_data *cpu_data; int cpu; void *cpu_buf; struct { unsigned addr; int len; } cmd_buf; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { wdog_dd->scm_regsave = (void *)__get_free_page(GFP_KERNEL); if (wdog_dd->scm_regsave) { cmd_buf.addr = virt_to_phys(wdog_dd->scm_regsave); Loading @@ -375,10 +381,12 @@ static void configure_bark_dump(struct msm_watchdog_data *wdog_dd) pr_err("Setting register save address failed.\n" "Registers won't be dumped on a dog " "bite\n"); dump_entry.id = MSM_CPU_CTXT; dump_entry.start_addr = virt_to_phys(wdog_dd->scm_regsave); dump_entry.end_addr = dump_entry.start_addr + PAGE_SIZE; ret = msm_dump_tbl_register(&dump_entry); cpu_dump_entry.id = MSM_CPU_CTXT; cpu_dump_entry.start_addr = virt_to_phys(wdog_dd->scm_regsave); cpu_dump_entry.end_addr = cpu_dump_entry.start_addr + PAGE_SIZE; ret = msm_dump_tbl_register(&cpu_dump_entry); if (ret) pr_err("Setting cpu dump region failed\n" "Registers wont be dumped during cpu hang\n"); Loading @@ -391,6 +399,42 @@ static void configure_bark_dump(struct msm_watchdog_data *wdog_dd) * without saving registers. */ } } else { cpu_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!cpu_data) { pr_err("cpu dump data structure allocation failed\n"); goto out0; } cpu_buf = kzalloc(MAX_CPU_CTX_SIZE * num_present_cpus(), GFP_KERNEL); if (!cpu_buf) { pr_err("cpu reg context space allocation failed\n"); goto out1; } for_each_cpu(cpu, cpu_present_mask) { cpu_data[cpu].addr = virt_to_phys(cpu_buf + cpu * MAX_CPU_CTX_SIZE); cpu_data[cpu].len = MAX_CPU_CTX_SIZE; dump_entry.id = MSM_DUMP_DATA_CPU_CTX + cpu; dump_entry.addr = virt_to_phys(&cpu_data[cpu]); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffers in case of error since * registration may have succeeded for some cpus. */ if (ret) pr_err("cpu %d reg dump setup failed\n", cpu); } } return; out1: kfree(cpu_data); out0: return; } Loading Loading
arch/arm/mach-msm/msm_cache_dump.c +100 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/dma-mapping.h> #include <linux/slab.h> #include <soc/qcom/scm.h> #include <asm/cacheflush.h> #include <mach/msm_cache_dump.h> Loading Loading @@ -65,13 +66,17 @@ static int msm_cache_dump_probe(struct platform_device *pdev) { struct msm_cache_dump_platform_data *d = pdev->dev.platform_data; struct msm_client_dump l1_dump_entry, l2_dump_entry; int ret; struct msm_dump_entry dump_entry; struct msm_dump_data *l1_inst_data, *l1_data_data, *l2_data; int ret, cpu; struct { unsigned long buf; unsigned long size; } l1_cache_data; u32 l1_size, l2_size; unsigned long total_size; u32 l1_inst_size, l1_data_size; phys_addr_t l1_inst_start, l1_data_start, l2_start; if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, Loading Loading @@ -130,6 +135,7 @@ static int msm_cache_dump_probe(struct platform_device *pdev) __func__, ret); #endif if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { l1_dump_entry.id = MSM_L1_CACHE; l1_dump_entry.start_addr = msm_cache_dump_addr; l1_dump_entry.end_addr = l1_dump_entry.start_addr + l1_size - 1; Loading @@ -145,10 +151,91 @@ static int msm_cache_dump_probe(struct platform_device *pdev) ret = msm_dump_tbl_register(&l2_dump_entry); if (ret) pr_err("Could not register L2 dump area: %d\n", ret); } else { l1_inst_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!l1_inst_data) { pr_err("l1 inst data structure allocation failed\n"); ret = -ENOMEM; goto err0; } l1_data_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!l1_data_data) { pr_err("l1 data data structure allocation failed\n"); ret = -ENOMEM; goto err1; } l1_inst_start = msm_cache_dump_addr; l1_data_start = msm_cache_dump_addr + (l1_size / 2); l1_inst_size = l1_size / (num_present_cpus() * 2); l1_data_size = l1_inst_size; for_each_cpu(cpu, cpu_present_mask) { l1_inst_data[cpu].addr = l1_inst_start + cpu * l1_inst_size; l1_inst_data[cpu].len = l1_inst_size; dump_entry.id = MSM_DUMP_DATA_L1_INST_CACHE + cpu; dump_entry.addr = virt_to_phys(&l1_inst_data[cpu]); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffers in case of error since * registration may have succeeded for some cpus. */ if (ret) pr_err("cpu %d l1 inst dump setup failed\n", cpu); l1_data_data[cpu].addr = l1_data_start + cpu * l1_data_size; l1_data_data[cpu].len = l1_data_size; dump_entry.id = MSM_DUMP_DATA_L1_DATA_CACHE + cpu; dump_entry.addr = virt_to_phys(&l1_data_data[cpu]); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffers in case of error since * registration may have succeeded for some cpus. */ if (ret) pr_err("cpu %d l1 data dump setup failed\n", cpu); } l2_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!l2_data) { pr_err("l2 data structure allocation failed\n"); ret = -ENOMEM; goto err2; } l2_start = msm_cache_dump_addr + l1_size; l2_data->addr = l2_start; l2_data->len = l2_size; dump_entry.id = MSM_DUMP_DATA_L2_CACHE; dump_entry.addr = virt_to_phys(l2_data); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); if (ret) pr_err("l2 dump setup failed\n"); } atomic_notifier_chain_register(&panic_notifier_list, &msm_cache_dump_blk); return 0; err2: kfree(l1_data_data); err1: kfree(l1_inst_data); err0: dma_free_coherent(&pdev->dev, total_size, msm_cache_dump_vaddr, msm_cache_dump_addr); return ret; } static int msm_cache_dump_remove(struct platform_device *pdev) Loading
drivers/coresight/coresight-etm.c +30 −11 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ struct etm_drvdata { bool pcsave_sticky_enable; bool pcsave_boot_enable; bool round_robin; struct msm_dump_data reg_data; }; static struct etm_drvdata *etmdrvdata[NR_CPUS]; Loading Loading @@ -2111,6 +2112,7 @@ static int etm_probe(struct platform_device *pdev) static int count; void *baddr; struct msm_client_dump dump; struct msm_dump_entry dump_entry; struct coresight_desc *desc; if (coresight_fuse_access_disabled() || Loading Loading @@ -2194,20 +2196,37 @@ static int etm_probe(struct platform_device *pdev) drvdata->round_robin = of_property_read_bool(pdev->dev.of_node, "qcom,round-robin"); if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL); if (baddr) { *(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER; dump.id = MSM_ETM0_REG + drvdata->cpu; dump.start_addr = virt_to_phys(baddr); dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size; ret = msm_dump_tbl_register(&dump); if (ret) { devm_kfree(dev, baddr); dev_err(dev, "ETM REG dump setup failed/unsupported\n"); dev_err(dev, "ETM REG dump setup failed\n"); } } else { dev_err(dev, "ETM REG dump space allocation failed\n"); } } else { baddr = devm_kzalloc(dev, reg_size, GFP_KERNEL); if (baddr) { drvdata->reg_data.addr = virt_to_phys(baddr); drvdata->reg_data.len = reg_size; dump_entry.id = MSM_DUMP_DATA_ETM_REG + drvdata->cpu; 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); dev_err(dev, "ETM REG dump setup failed\n"); } } else { dev_err(dev, "ETM REG dump space allocation failed\n"); } } desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) { Loading
drivers/coresight/coresight-tmc.c +101 −37 Original line number Diff line number Diff line Loading @@ -152,7 +152,9 @@ struct tmc_drvdata { bool reading; bool aborting; char *reg_buf; struct msm_dump_data reg_data; char *buf; struct msm_dump_data buf_data; dma_addr_t paddr; void __iomem *vaddr; uint32_t size; Loading Loading @@ -647,6 +649,12 @@ static void __tmc_reg_dump(struct tmc_drvdata *drvdata) return; reg_hdr = drvdata->reg_buf - PAGE_SIZE; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(reg_hdr + TMC_REG_DUMP_VER_OFF) = TMC_REG_DUMP_VER; else drvdata->reg_data.version = TMC_REG_DUMP_VER; reg_buf = (uint32_t *)drvdata->reg_buf; reg_buf[1] = tmc_readl(drvdata, TMC_RSZ); Loading Loading @@ -688,7 +696,11 @@ static void __tmc_reg_dump(struct tmc_drvdata *drvdata) reg_buf[1022] = tmc_readl(drvdata, CORESIGHT_COMPIDR2); reg_buf[1023] = tmc_readl(drvdata, CORESIGHT_COMPIDR3); *(uint32_t *)(reg_hdr + TMC_REG_DUMP_MAGIC_OFF) = TMC_REG_DUMP_MAGIC; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(reg_hdr + TMC_REG_DUMP_MAGIC_OFF) = TMC_REG_DUMP_MAGIC; else drvdata->reg_data.magic = TMC_REG_DUMP_MAGIC; } static void __tmc_etb_dump(struct tmc_drvdata *drvdata) Loading @@ -700,6 +712,13 @@ static void __tmc_etb_dump(struct tmc_drvdata *drvdata) uint32_t read_data; int i; hdr = drvdata->buf - PAGE_SIZE; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(hdr + TMC_ETFETB_DUMP_VER_OFF) = TMC_ETFETB_DUMP_VER; else drvdata->buf_data.version = TMC_ETFETB_DUMP_VER; memwidth = BMVAL(tmc_readl(drvdata, CORESIGHT_DEVID), 8, 10); if (memwidth == TMC_MEM_INTF_WIDTH_32BITS) memwords = 1; Loading @@ -723,9 +742,11 @@ static void __tmc_etb_dump(struct tmc_drvdata *drvdata) out: if (drvdata->aborting) { hdr = drvdata->buf - PAGE_SIZE; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) *(uint32_t *)(hdr + TMC_ETFETB_DUMP_MAGIC_OFF) = TMC_ETFETB_DUMP_MAGIC; else drvdata->buf_data.magic = TMC_ETFETB_DUMP_MAGIC; } } Loading Loading @@ -1636,6 +1657,7 @@ static int tmc_probe(struct platform_device *pdev) static int count; void *baddr; struct msm_client_dump dump; struct msm_dump_entry dump_entry; struct coresight_cti_data *ctidata; struct coresight_desc *desc; Loading Loading @@ -1716,44 +1738,86 @@ static int tmc_probe(struct platform_device *pdev) if (ret) goto err1; } else { if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { baddr = devm_kzalloc(dev, PAGE_SIZE + drvdata->size, GFP_KERNEL); if (!baddr) return -ENOMEM; drvdata->buf = baddr + PAGE_SIZE; *(uint32_t *)(baddr + TMC_ETFETB_DUMP_VER_OFF) = TMC_ETFETB_DUMP_VER; dump.id = MSM_TMC_ETFETB + etfetb_count; dump.start_addr = virt_to_phys(baddr); dump.end_addr = dump.start_addr + PAGE_SIZE + drvdata->size; dump.end_addr = dump.start_addr + PAGE_SIZE + drvdata->size; ret = msm_dump_tbl_register(&dump); /* * Don't free the buffer in case of error since it can still * be used to provide dump collection via the device node or * as part of abort. * Don't free the buffer in case of error since it can * still be used to provide dump collection via the * device node or as part of abort. */ if (ret) dev_info(dev, "TMC ETF-ETB dump setup failed\n"); dev_err(dev, "TMC ETF-ETB dump setup failed\n"); } else { drvdata->buf = devm_kzalloc(dev, drvdata->size, GFP_KERNEL); if (!drvdata->buf) return -ENOMEM; drvdata->buf_data.addr = virt_to_phys(drvdata->buf); drvdata->buf_data.len = drvdata->size; dump_entry.id = MSM_DUMP_DATA_TMC_ETF + etfetb_count; dump_entry.addr = virt_to_phys(&drvdata->buf_data); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffer in case of error since it can * still be used to provide dump collection via the * device node or as part of abort. */ if (ret) dev_err(dev, "TMC ETF-ETB dump setup failed\n"); } etfetb_count++; } if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL); if (baddr) { drvdata->reg_buf = baddr + PAGE_SIZE; *(uint32_t *)(baddr + TMC_REG_DUMP_VER_OFF) = TMC_REG_DUMP_VER; dump.id = MSM_TMC0_REG + count; dump.start_addr = virt_to_phys(baddr); dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size; ret = msm_dump_tbl_register(&dump); /* * Don't free the buffer in case of error since it can still * be used to dump registers as part of abort to aid post crash * parsing. * Don't free the buffer in case of error since it can * still be used to dump registers as part of abort to * aid post crash parsing. */ if (ret) dev_info(dev, "TMC REG dump setup failed\n"); dev_err(dev, "TMC REG dump setup failed\n"); } else { dev_info(dev, "TMC REG dump space allocation failed\n"); dev_err(dev, "TMC REG dump allocation failed\n"); } } else { drvdata->reg_buf = devm_kzalloc(dev, reg_size, GFP_KERNEL); if (drvdata->reg_buf) { drvdata->reg_data.addr = virt_to_phys(drvdata->reg_buf); drvdata->reg_data.len = reg_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); /* * Don't free the buffer in case of error since it can * still be used to dump registers as part of abort to * aid post crash parsing. */ if (ret) dev_err(dev, "TMC REG dump setup failed\n"); } else { dev_err(dev, "TMC REG dump allocation failed\n"); } } count++; Loading
drivers/soc/qcom/watchdog_v2.c +65 −21 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #define MASK_SIZE 32 #define SCM_SET_REGSAVE_CMD 0x2 #define SCM_SVC_SEC_WDOG_DIS 0x7 #define MAX_CPU_CTX_SIZE 512 static struct workqueue_struct *wdog_wq; Loading Loading @@ -359,12 +360,17 @@ static irqreturn_t wdog_ppi_bark(int irq, void *dev_id) static void configure_bark_dump(struct msm_watchdog_data *wdog_dd) { int ret; struct msm_client_dump dump_entry; struct msm_client_dump cpu_dump_entry; struct msm_dump_entry dump_entry; struct msm_dump_data *cpu_data; int cpu; void *cpu_buf; struct { unsigned addr; int len; } cmd_buf; if (MSM_DUMP_MAJOR(msm_dump_table_version()) == 1) { wdog_dd->scm_regsave = (void *)__get_free_page(GFP_KERNEL); if (wdog_dd->scm_regsave) { cmd_buf.addr = virt_to_phys(wdog_dd->scm_regsave); Loading @@ -375,10 +381,12 @@ static void configure_bark_dump(struct msm_watchdog_data *wdog_dd) pr_err("Setting register save address failed.\n" "Registers won't be dumped on a dog " "bite\n"); dump_entry.id = MSM_CPU_CTXT; dump_entry.start_addr = virt_to_phys(wdog_dd->scm_regsave); dump_entry.end_addr = dump_entry.start_addr + PAGE_SIZE; ret = msm_dump_tbl_register(&dump_entry); cpu_dump_entry.id = MSM_CPU_CTXT; cpu_dump_entry.start_addr = virt_to_phys(wdog_dd->scm_regsave); cpu_dump_entry.end_addr = cpu_dump_entry.start_addr + PAGE_SIZE; ret = msm_dump_tbl_register(&cpu_dump_entry); if (ret) pr_err("Setting cpu dump region failed\n" "Registers wont be dumped during cpu hang\n"); Loading @@ -391,6 +399,42 @@ static void configure_bark_dump(struct msm_watchdog_data *wdog_dd) * without saving registers. */ } } else { cpu_data = kzalloc(sizeof(struct msm_dump_data) * num_present_cpus(), GFP_KERNEL); if (!cpu_data) { pr_err("cpu dump data structure allocation failed\n"); goto out0; } cpu_buf = kzalloc(MAX_CPU_CTX_SIZE * num_present_cpus(), GFP_KERNEL); if (!cpu_buf) { pr_err("cpu reg context space allocation failed\n"); goto out1; } for_each_cpu(cpu, cpu_present_mask) { cpu_data[cpu].addr = virt_to_phys(cpu_buf + cpu * MAX_CPU_CTX_SIZE); cpu_data[cpu].len = MAX_CPU_CTX_SIZE; dump_entry.id = MSM_DUMP_DATA_CPU_CTX + cpu; dump_entry.addr = virt_to_phys(&cpu_data[cpu]); ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); /* * Don't free the buffers in case of error since * registration may have succeeded for some cpus. */ if (ret) pr_err("cpu %d reg dump setup failed\n", cpu); } } return; out1: kfree(cpu_data); out0: return; } Loading