From 54cba7b8a9a81b6dd7f67e3ba36bd7ee558817d1 Mon Sep 17 00:00:00 2001 From: Hyunwoong Kim Date: Wed, 7 Mar 2018 17:34:34 +0900 Subject: [PATCH] [RAMEN9610-10167][COMMON] ASoC: abox: Save abox DRAM memory ABOX reserved memory for saving DRAM was removed. But dumped DRAM data is important for working out a problem. This patch allocates actual memory region for saving abox DRAM memory. Change-Id: Id33aa8c4ce77916e63589b29e8fd7384d07d9432 Signed-off-by: Hyunwoong Kim --- sound/soc/samsung/abox/abox_dbg.c | 69 ++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/sound/soc/samsung/abox/abox_dbg.c b/sound/soc/samsung/abox/abox_dbg.c index 0f3a09d6f727..5a292acf10ea 100644 --- a/sound/soc/samsung/abox/abox_dbg.c +++ b/sound/soc/samsung/abox/abox_dbg.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "abox_dbg.h" #include "abox_gic.h" @@ -86,6 +88,8 @@ struct abox_dbg_dump { struct abox_dbg_dump_min { char sram[SZ_512K]; char iva[IVA_FIRMWARE_SIZE]; + void *dram; + struct page **pages; u32 sfr[SZ_64K / sizeof(u32)]; u32 sfr_gic_gicd[SZ_4K / sizeof(u32)]; unsigned int gpr[17]; @@ -112,6 +116,39 @@ static int __init abox_rmem_setup(struct reserved_mem *rmem) RESERVEDMEM_OF_DECLARE(abox_rmem, "exynos,abox_rmem", abox_rmem_setup); +static void *abox_dbg_alloc_mem_atomic(struct device *dev, struct abox_dbg_dump_min *p_dump) +{ + int i, j; + int npages = DRAM_FIRMWARE_SIZE / PAGE_SIZE; + struct page **tmp; + gfp_t alloc_gfp_flag = GFP_KERNEL | GFP_ATOMIC; + + p_dump->pages = kzalloc(sizeof(struct page *) * npages, alloc_gfp_flag); + if (!p_dump->pages) { + dev_info(dev, "Failed to allocate array of struct pages\n"); + return NULL; + } + + tmp = p_dump->pages; + for (i = 0; i < npages; i++, tmp++) { + *tmp = alloc_page(alloc_gfp_flag); + if (*tmp == NULL) { + pr_err("Failed to allocate pages for abox debug\n"); + goto free_pg; + } + } + + return vm_map_ram(p_dump->pages, npages, -1, PAGE_KERNEL); + +free_pg: + tmp = p_dump->pages; + for (j = 0; j < i; j++, tmp++) + __free_pages(*tmp, 0); + kfree(p_dump->pages); + p_dump->pages = NULL; + return NULL; +} + void abox_dbg_dump_gpr_from_addr(struct device *dev, unsigned int *addr, enum abox_dbg_dump_src src, const char *reason) { @@ -206,7 +243,6 @@ void abox_dbg_dump_mem(struct device *dev, struct abox_data *data, sizeof(p_dump->sfr_gic_gicd)); } else if (p_abox_dbg_dump_min) { struct abox_dbg_dump_min *p_dump = &(*p_abox_dbg_dump_min)[src]; - p_dump->time = sched_clock(); strncpy(p_dump->reason, reason, sizeof(p_dump->reason) - 1); memcpy_fromio(p_dump->sram, data->sram_base, data->sram_size); @@ -219,6 +255,18 @@ void abox_dbg_dump_mem(struct device *dev, struct abox_data *data, memcpy_fromio(p_dump->sfr, data->sfr_base, sizeof(p_dump->sfr)); memcpy_fromio(p_dump->sfr_gic_gicd, gic_data->gicd_base, sizeof(p_dump->sfr_gic_gicd)); + if (!p_dump->dram) { + if (src == ABOX_DBG_DUMP_KERNEL) + p_dump->dram = vzalloc(DRAM_FIRMWARE_SIZE); + else if (src == ABOX_DBG_DUMP_FIRMWARE) + p_dump->dram = abox_dbg_alloc_mem_atomic(dev, p_dump); + } + if (!IS_ERR_OR_NULL(p_dump->dram)) { + memcpy(p_dump->dram, data->dram_base, DRAM_FIRMWARE_SIZE); + flush_cache_all(); + } else { + dev_info(dev, "Failed to save ABOX dram\n"); + } } } @@ -395,6 +443,7 @@ static int samsung_abox_debug_probe(struct platform_device *pdev) abox_rmem->size, 0); data->dump_base = phys_to_virt(abox_rmem->base); data->dump_base_phys = abox_rmem->base; + memset(data->dump_base, 0x0, abox_rmem->size); ret = device_create_file(dev, &dev_attr_gpr); bin_attr_calliope_sram.size = data->sram_size; bin_attr_calliope_sram.private = data->sram_base; @@ -414,8 +463,26 @@ static int samsung_abox_debug_probe(struct platform_device *pdev) static int samsung_abox_debug_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; + int i; dev_dbg(dev, "%s\n", __func__); + for (i = 0; i < ABOX_DBG_DUMP_COUNT; i++) { + if (i == ABOX_DBG_DUMP_KERNEL) { + vfree(p_abox_dbg_dump_min[i]->dram); + } else if (i == ABOX_DBG_DUMP_FIRMWARE) { + struct page **tmp = p_abox_dbg_dump_min[i]->pages; + if (p_abox_dbg_dump_min[i]->dram) + vm_unmap_ram(p_abox_dbg_dump_min[i]->dram, + DRAM_FIRMWARE_SIZE); + if (tmp) { + int j; + for (j = 0; j < DRAM_FIRMWARE_SIZE / PAGE_SIZE; j++, tmp++) + __free_pages(*tmp, 0); + kfree(p_abox_dbg_dump_min[i]->pages); + p_abox_dbg_dump_min[i]->pages = NULL; + } + } + } return 0; } -- 2.20.1