aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/pstore/ram.c99
1 files changed, 62 insertions, 37 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 9b274b98bf3b..6b7676738493 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -202,13 +202,65 @@ static struct ramoops_context oops_cxt = {
202 }, 202 },
203}; 203};
204 204
205static void ramoops_free_przs(struct ramoops_context *cxt)
206{
207 int i;
208
209 if (!cxt->przs)
210 return;
211
212 for (i = 0; cxt->przs[i]; i++)
213 persistent_ram_free(cxt->przs[i]);
214 kfree(cxt->przs);
215}
216
217static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
218 phys_addr_t *paddr, size_t dump_mem_sz)
219{
220 int err = -ENOMEM;
221 int i;
222
223 if (!cxt->record_size)
224 return 0;
225
226 cxt->max_dump_cnt = dump_mem_sz / cxt->record_size;
227 if (!cxt->max_dump_cnt)
228 return -ENOMEM;
229
230 cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt,
231 GFP_KERNEL);
232 if (!cxt->przs) {
233 dev_err(dev, "failed to initialize a prz array for dumps\n");
234 return -ENOMEM;
235 }
236
237 for (i = 0; i < cxt->max_dump_cnt; i++) {
238 size_t sz = cxt->record_size;
239
240 cxt->przs[i] = persistent_ram_new(*paddr, sz, cxt->ecc);
241 if (IS_ERR(cxt->przs[i])) {
242 err = PTR_ERR(cxt->przs[i]);
243 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
244 sz, (unsigned long long)*paddr, err);
245 goto fail_prz;
246 }
247 *paddr += sz;
248 }
249
250 return 0;
251fail_prz:
252 ramoops_free_przs(cxt);
253 return err;
254}
255
205static int __init ramoops_probe(struct platform_device *pdev) 256static int __init ramoops_probe(struct platform_device *pdev)
206{ 257{
207 struct device *dev = &pdev->dev; 258 struct device *dev = &pdev->dev;
208 struct ramoops_platform_data *pdata = pdev->dev.platform_data; 259 struct ramoops_platform_data *pdata = pdev->dev.platform_data;
209 struct ramoops_context *cxt = &oops_cxt; 260 struct ramoops_context *cxt = &oops_cxt;
261 size_t dump_mem_sz;
262 phys_addr_t paddr;
210 int err = -EINVAL; 263 int err = -EINVAL;
211 int i;
212 264
213 /* Only a single ramoops area allowed at a time, so fail extra 265 /* Only a single ramoops area allowed at a time, so fail extra
214 * probes. 266 * probes.
@@ -225,21 +277,6 @@ static int __init ramoops_probe(struct platform_device *pdev)
225 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); 277 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
226 pdata->record_size = rounddown_pow_of_two(pdata->record_size); 278 pdata->record_size = rounddown_pow_of_two(pdata->record_size);
227 279
228 /* Check for the minimum memory size */
229 if (pdata->mem_size < MIN_MEM_SIZE &&
230 pdata->record_size < MIN_MEM_SIZE) {
231 pr_err("memory size too small, minimum is %lu\n",
232 MIN_MEM_SIZE);
233 goto fail_out;
234 }
235
236 if (pdata->mem_size < pdata->record_size) {
237 pr_err("The memory size must be larger than the "
238 "records size\n");
239 goto fail_out;
240 }
241
242 cxt->max_dump_cnt = pdata->mem_size / pdata->record_size;
243 cxt->dump_read_cnt = 0; 280 cxt->dump_read_cnt = 0;
244 cxt->size = pdata->mem_size; 281 cxt->size = pdata->mem_size;
245 cxt->phys_addr = pdata->mem_address; 282 cxt->phys_addr = pdata->mem_address;
@@ -247,24 +284,14 @@ static int __init ramoops_probe(struct platform_device *pdev)
247 cxt->dump_oops = pdata->dump_oops; 284 cxt->dump_oops = pdata->dump_oops;
248 cxt->ecc = pdata->ecc; 285 cxt->ecc = pdata->ecc;
249 286
250 cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt, GFP_KERNEL); 287 paddr = cxt->phys_addr;
251 if (!cxt->przs) {
252 err = -ENOMEM;
253 dev_err(dev, "failed to initialize a prz array\n");
254 goto fail_out;
255 }
256
257 for (i = 0; i < cxt->max_dump_cnt; i++) {
258 size_t sz = cxt->record_size;
259 phys_addr_t start = cxt->phys_addr + sz * i;
260 288
261 cxt->przs[i] = persistent_ram_new(start, sz, cxt->ecc); 289 dump_mem_sz = cxt->size;
262 if (IS_ERR(cxt->przs[i])) { 290 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
263 err = PTR_ERR(cxt->przs[i]); 291 if (err) {
264 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", 292 pr_err("memory size too small, minimum is %lu\n",
265 sz, (unsigned long long)start, err); 293 cxt->record_size);
266 goto fail_przs; 294 goto fail_count;
267 }
268 } 295 }
269 296
270 cxt->pstore.data = cxt; 297 cxt->pstore.data = cxt;
@@ -303,10 +330,8 @@ fail_buf:
303fail_clear: 330fail_clear:
304 cxt->pstore.bufsize = 0; 331 cxt->pstore.bufsize = 0;
305 cxt->max_dump_cnt = 0; 332 cxt->max_dump_cnt = 0;
306fail_przs: 333fail_count:
307 for (i = 0; cxt->przs[i]; i++) 334 ramoops_free_przs(cxt);
308 persistent_ram_free(cxt->przs[i]);
309 kfree(cxt->przs);
310fail_out: 335fail_out:
311 return err; 336 return err;
312} 337}