soc: qcom: pil: Make provision for collecting complete subsystem dump

Subsystem ramdump collection as of now happen segmentwise, but sometime
there are hole in between segment where dynamic image is loaded and
which need to be captured during subsystem ramdump collection.

This change will dump complete subsystem memory rather than only segments
based on the configuration of subsystem who desire it.

Change-Id: I5075a90817d1a4d00d69ad39d892dbbc40b0b0dc
Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
This commit is contained in:
Avaneesh Kumar Dwivedi 2016-03-14 18:07:48 +05:30 committed by David Keitel
parent 75fa84afc5
commit a8904ad594
2 changed files with 24 additions and 3 deletions

View file

@ -64,6 +64,9 @@ Optional properties:
- qcom,pil-generic-irq-handler: generic interrupt handler used for communication with subsytem
based on bit values in scsr registers.
- qcom,spss-scsr-bits: array of bit positions into the scsr registers used in generic handler.
- qcom,complete-ramdump: Boolean. If set, complete ramdump i.e. region between start address of
first segment to end address of last segment will be collected without
leaving any hole in between.
Example:
qcom,venus@fdce0000 {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -26,6 +26,7 @@
#include <linux/wait.h>
#include <soc/qcom/ramdump.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>
#define RAMDUMP_WAIT_MSECS 120000
@ -45,6 +46,7 @@ struct ramdump_device {
size_t elfcore_size;
char *elfcore_buf;
struct dma_attrs attrs;
bool complete_ramdump;
};
static int ramdump_open(struct inode *inode, struct file *filep)
@ -273,6 +275,13 @@ void *create_ramdump_device(const char *dev_name, struct device *parent)
rd_dev->device.name = rd_dev->name;
rd_dev->device.fops = &ramdump_file_ops;
rd_dev->device.parent = parent;
if (parent) {
rd_dev->complete_ramdump = of_property_read_bool(
parent->of_node, "qcom,complete-ramdump");
if (!rd_dev->complete_ramdump)
dev_info(parent,
"for %s segments only will be dumped.", dev_name);
}
init_waitqueue_head(&rd_dev->dump_wait_q);
@ -315,8 +324,17 @@ static int _do_ramdump(void *handle, struct ramdump_segment *segments,
return -EPIPE;
}
for (i = 0; i < nsegments; i++)
segments[i].size = PAGE_ALIGN(segments[i].size);
if (rd_dev->complete_ramdump) {
for (i = 0; i < nsegments-1; i++)
segments[i].size =
PAGE_ALIGN(segments[i+1].address - segments[i].address);
segments[nsegments-1].size =
PAGE_ALIGN(segments[nsegments-1].size);
} else {
for (i = 0; i < nsegments; i++)
segments[i].size = PAGE_ALIGN(segments[i].size);
}
rd_dev->segments = segments;
rd_dev->nsegments = nsegments;