diff options
author | Miguel Vadillo <vadillo@ti.com> | 2011-09-07 21:14:18 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-09-09 12:12:29 -0700 |
commit | 8a8569a0561cba735355a46c52bb155232c8fbf4 (patch) | |
tree | db487d2f663c048edfebae7a2d36c5e466036132 /drivers/remoteproc | |
parent | 4be6fc8085f231a37772a9732819dbffd534629a (diff) | |
download | kernel_samsung_tuna-8a8569a0561cba735355a46c52bb155232c8fbf4.zip kernel_samsung_tuna-8a8569a0561cba735355a46c52bb155232c8fbf4.tar.gz kernel_samsung_tuna-8a8569a0561cba735355a46c52bb155232c8fbf4.tar.bz2 |
drivers: remoteproc: save last traces in sysfs in case of crash
When an error is detected copy the last trace buffer content
of each core to an entry in sysfs, this is to provide a way
to see the last ducati traces after a crash.
After a recovery the last buffer traces can be cat'ed reading
trace0_last and trace1_last.
Signed-off-by: Miguel Vadillo <vadillo@ti.com>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r-- | drivers/remoteproc/remoteproc.c | 78 |
1 files changed, 58 insertions, 20 deletions
diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c index 4124011..05c0c98 100644 --- a/drivers/remoteproc/remoteproc.c +++ b/drivers/remoteproc/remoteproc.c @@ -55,8 +55,8 @@ static ssize_t rproc_format_trace_buf(char __user *userbuf, size_t count, int i, w_pos; /* Assume write_idx is the penultimate byte in the buffer trace*/ - w_idx = (int *)(buf + (size - (sizeof(u32) * 2))); size = size - (sizeof(u32) * 2); + w_idx = (int *)(buf + size); w_pos = *w_idx; if (from_beg) @@ -127,6 +127,10 @@ static const struct file_operations rproc_name_ops = { DEBUGFS_READONLY_FILE(trace0, rproc->trace_buf0, rproc->trace_len0); DEBUGFS_READONLY_FILE(trace1, rproc->trace_buf1, rproc->trace_len1); +DEBUGFS_READONLY_FILE(trace0_last, rproc->last_trace_buf0, + rproc->last_trace_len0); +DEBUGFS_READONLY_FILE(trace1_last, rproc->last_trace_buf1, + rproc->last_trace_len1); #define DEBUGFS_ADD(name) \ debugfs_create_file(#name, 0400, rproc->dbg_dir, \ @@ -211,6 +215,12 @@ static int _event_notify(struct rproc *rproc, int type, void *data) init_completion(&rproc->error_comp); rproc->state = RPROC_CRASHED; mutex_unlock(&rproc->lock); + if (rproc->trace_buf0 && rproc->last_trace_buf0) + memcpy(rproc->last_trace_buf0, rproc->trace_buf0, + rproc->last_trace_len0); + if (rproc->trace_buf1 && rproc->last_trace_buf1) + memcpy(rproc->last_trace_buf1, rproc->trace_buf1, + rproc->last_trace_len1); #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND pm_runtime_dont_use_autosuspend(rproc->dev); #endif @@ -393,9 +403,11 @@ static int rproc_handle_resources(struct rproc *rproc, struct fw_resource *rsc, /* store the da for processing at the end */ if (!trace_da0) { rproc->trace_len0 = rsc->len; + rproc->last_trace_len0 = rsc->len; trace_da0 = da; } else { rproc->trace_len1 = rsc->len; + rproc->last_trace_len1 = rsc->len; trace_da1 = da; } break; @@ -446,6 +458,9 @@ static int rproc_handle_resources(struct rproc *rproc, struct fw_resource *rsc, len -= sizeof(*rsc); } + if (ret) + goto error; + /* * post-process trace buffers, as we cannot rely on the order of the * trace section and the carveout sections. @@ -453,33 +468,54 @@ static int rproc_handle_resources(struct rproc *rproc, struct fw_resource *rsc, * trace buffer memory _is_ normal memory, so we cast away the * __iomem to make sparse happy */ - if (!ret && trace_da0) { + if (trace_da0) { ret = rproc_da_to_pa(rproc->memory_maps, trace_da0, &pa); - if (!ret) { - rproc->trace_buf0 = (__force void *) - ioremap_nocache(pa, rproc->trace_len0); - if (rproc->trace_buf0) - DEBUGFS_ADD(trace0); - else { - dev_err(dev, "can't ioremap trace buffer0\n"); - ret = -EIO; + if (ret) + goto error; + rproc->trace_buf0 = (__force void *) + ioremap_nocache(pa, rproc->trace_len0); + if (rproc->trace_buf0) { + DEBUGFS_ADD(trace0); + if (!rproc->last_trace_buf0) { + rproc->last_trace_buf0 = kzalloc(sizeof(u32) * + rproc->last_trace_len0, + GFP_KERNEL); + if (!rproc->last_trace_buf0) { + ret = -ENOMEM; + goto error; + } + DEBUGFS_ADD(trace0_last); } + } else { + dev_err(dev, "can't ioremap trace buffer0\n"); + ret = -EIO; + goto error; } } - if (!ret && trace_da1) { + if (trace_da1) { ret = rproc_da_to_pa(rproc->memory_maps, trace_da1, &pa); - if (!ret) { - rproc->trace_buf1 = (__force void *) - ioremap_nocache(pa, rproc->trace_len1); - if (rproc->trace_buf1) - DEBUGFS_ADD(trace1); - else { - dev_err(dev, "can't ioremap trace buffer1\n"); - ret = -EIO; + if (ret) + goto error; + rproc->trace_buf1 = (__force void *) + ioremap_nocache(pa, rproc->trace_len1); + if (rproc->trace_buf1) { + DEBUGFS_ADD(trace1); + if (!rproc->last_trace_buf1) { + rproc->last_trace_buf1 = kzalloc(sizeof(u32) * + rproc->last_trace_len1, + GFP_KERNEL); + if (!rproc->last_trace_buf1) { + ret = -ENOMEM; + goto error; + } + DEBUGFS_ADD(trace1_last); } + } else { + dev_err(dev, "can't ioremap trace buffer1\n"); + ret = -EIO; } } - +error: return ret; } @@ -1160,6 +1196,8 @@ int rproc_unregister(const char *name) pm_qos_remove_request(rproc->qos_request); kfree(rproc->qos_request); + kfree(rproc->last_trace_buf0); + kfree(rproc->last_trace_buf1); kfree(rproc); return 0; |