aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ramoops.txt6
-rw-r--r--fs/pstore/ram.c15
-rw-r--r--include/linux/pstore_ram.h1
3 files changed, 19 insertions, 3 deletions
diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
index 470d2c4db6ff..4ba7db231cb2 100644
--- a/Documentation/ramoops.txt
+++ b/Documentation/ramoops.txt
@@ -30,6 +30,11 @@ variable while setting 0 in that variable dumps only the panics.
30The module uses a counter to record multiple dumps but the counter gets reset 30The module uses a counter to record multiple dumps but the counter gets reset
31on restart (i.e. new dumps after the restart will overwrite old ones). 31on restart (i.e. new dumps after the restart will overwrite old ones).
32 32
33Ramoops also supports software ECC protection of persistent memory regions.
34This might be useful when a hardware reset was used to bring the machine back
35to life (i.e. a watchdog triggered). In such cases, RAM may be somewhat
36corrupt, but usually it is restorable.
37
332. Setting the parameters 382. Setting the parameters
34 39
35Setting the ramoops parameters can be done in 2 different manners: 40Setting the ramoops parameters can be done in 2 different manners:
@@ -46,6 +51,7 @@ static struct ramoops_platform_data ramoops_data = {
46 .mem_address = <...>, 51 .mem_address = <...>,
47 .record_size = <...>, 52 .record_size = <...>,
48 .dump_oops = <...>, 53 .dump_oops = <...>,
54 .ecc = <...>,
49}; 55};
50 56
51static struct platform_device ramoops_dev = { 57static struct platform_device ramoops_dev = {
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 62b13eda4691..9123cce28c1e 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -56,12 +56,18 @@ module_param(dump_oops, int, 0600);
56MODULE_PARM_DESC(dump_oops, 56MODULE_PARM_DESC(dump_oops,
57 "set to 1 to dump oopses, 0 to only dump panics (default 1)"); 57 "set to 1 to dump oopses, 0 to only dump panics (default 1)");
58 58
59static int ramoops_ecc;
60module_param_named(ecc, ramoops_ecc, int, 0600);
61MODULE_PARM_DESC(ramoops_ecc,
62 "set to 1 to enable ECC support");
63
59struct ramoops_context { 64struct ramoops_context {
60 struct persistent_ram_zone **przs; 65 struct persistent_ram_zone **przs;
61 phys_addr_t phys_addr; 66 phys_addr_t phys_addr;
62 unsigned long size; 67 unsigned long size;
63 size_t record_size; 68 size_t record_size;
64 int dump_oops; 69 int dump_oops;
70 bool ecc;
65 unsigned int count; 71 unsigned int count;
66 unsigned int max_count; 72 unsigned int max_count;
67 unsigned int read_count; 73 unsigned int read_count;
@@ -236,6 +242,7 @@ static int __init ramoops_probe(struct platform_device *pdev)
236 cxt->phys_addr = pdata->mem_address; 242 cxt->phys_addr = pdata->mem_address;
237 cxt->record_size = pdata->record_size; 243 cxt->record_size = pdata->record_size;
238 cxt->dump_oops = pdata->dump_oops; 244 cxt->dump_oops = pdata->dump_oops;
245 cxt->ecc = pdata->ecc;
239 246
240 cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_count, GFP_KERNEL); 247 cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_count, GFP_KERNEL);
241 if (!cxt->przs) { 248 if (!cxt->przs) {
@@ -248,7 +255,7 @@ static int __init ramoops_probe(struct platform_device *pdev)
248 size_t sz = cxt->record_size; 255 size_t sz = cxt->record_size;
249 phys_addr_t start = cxt->phys_addr + sz * i; 256 phys_addr_t start = cxt->phys_addr + sz * i;
250 257
251 cxt->przs[i] = persistent_ram_new(start, sz, 0); 258 cxt->przs[i] = persistent_ram_new(start, sz, cxt->ecc);
252 if (IS_ERR(cxt->przs[i])) { 259 if (IS_ERR(cxt->przs[i])) {
253 err = PTR_ERR(cxt->przs[i]); 260 err = PTR_ERR(cxt->przs[i]);
254 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", 261 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
@@ -281,9 +288,10 @@ static int __init ramoops_probe(struct platform_device *pdev)
281 record_size = pdata->record_size; 288 record_size = pdata->record_size;
282 dump_oops = pdata->dump_oops; 289 dump_oops = pdata->dump_oops;
283 290
284 pr_info("attached 0x%lx@0x%llx (%ux0x%zx)\n", 291 pr_info("attached 0x%lx@0x%llx (%ux0x%zx), ecc: %s\n",
285 cxt->size, (unsigned long long)cxt->phys_addr, 292 cxt->size, (unsigned long long)cxt->phys_addr,
286 cxt->max_count, cxt->record_size); 293 cxt->max_count, cxt->record_size,
294 ramoops_ecc ? "on" : "off");
287 295
288 return 0; 296 return 0;
289 297
@@ -347,6 +355,7 @@ static int __init ramoops_init(void)
347 dummy_data->mem_address = mem_address; 355 dummy_data->mem_address = mem_address;
348 dummy_data->record_size = record_size; 356 dummy_data->record_size = record_size;
349 dummy_data->dump_oops = dump_oops; 357 dummy_data->dump_oops = dump_oops;
358 dummy_data->ecc = ramoops_ecc;
350 dummy = platform_create_bundle(&ramoops_driver, ramoops_probe, 359 dummy = platform_create_bundle(&ramoops_driver, ramoops_probe,
351 NULL, 0, dummy_data, 360 NULL, 0, dummy_data,
352 sizeof(struct ramoops_platform_data)); 361 sizeof(struct ramoops_platform_data));
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index ffe24a52c5af..7ed7fd4dba49 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -92,6 +92,7 @@ struct ramoops_platform_data {
92 unsigned long mem_address; 92 unsigned long mem_address;
93 unsigned long record_size; 93 unsigned long record_size;
94 int dump_oops; 94 int dump_oops;
95 bool ecc;
95}; 96};
96 97
97#endif 98#endif