},
};
+static void ramoops_free_przs(struct ramoops_context *cxt)
+{
+ int i;
+
+ if (!cxt->przs)
+ return;
+
+ for (i = 0; cxt->przs[i]; i++)
+ persistent_ram_free(cxt->przs[i]);
+ kfree(cxt->przs);
+}
+
+static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
+ phys_addr_t *paddr, size_t dump_mem_sz)
+{
+ int err = -ENOMEM;
+ int i;
+
+ if (!cxt->record_size)
+ return 0;
+
+ cxt->max_dump_cnt = dump_mem_sz / cxt->record_size;
+ if (!cxt->max_dump_cnt)
+ return -ENOMEM;
+
+ cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt,
+ GFP_KERNEL);
+ if (!cxt->przs) {
+ dev_err(dev, "failed to initialize a prz array for dumps\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < cxt->max_dump_cnt; i++) {
+ size_t sz = cxt->record_size;
+
+ cxt->przs[i] = persistent_ram_new(*paddr, sz, cxt->ecc);
+ if (IS_ERR(cxt->przs[i])) {
+ err = PTR_ERR(cxt->przs[i]);
+ dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
+ sz, (unsigned long long)*paddr, err);
+ goto fail_prz;
+ }
+ *paddr += sz;
+ }
+
+ return 0;
+fail_prz:
+ ramoops_free_przs(cxt);
+ return err;
+}
+
static int __init ramoops_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ramoops_platform_data *pdata = pdev->dev.platform_data;
struct ramoops_context *cxt = &oops_cxt;
+ size_t dump_mem_sz;
+ phys_addr_t paddr;
int err = -EINVAL;
- int i;
/* Only a single ramoops area allowed at a time, so fail extra
* probes.
pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
pdata->record_size = rounddown_pow_of_two(pdata->record_size);
- /* Check for the minimum memory size */
- if (pdata->mem_size < MIN_MEM_SIZE &&
- pdata->record_size < MIN_MEM_SIZE) {
- pr_err("memory size too small, minimum is %lu\n",
- MIN_MEM_SIZE);
- goto fail_out;
- }
-
- if (pdata->mem_size < pdata->record_size) {
- pr_err("The memory size must be larger than the "
- "records size\n");
- goto fail_out;
- }
-
- cxt->max_dump_cnt = pdata->mem_size / pdata->record_size;
cxt->dump_read_cnt = 0;
cxt->size = pdata->mem_size;
cxt->phys_addr = pdata->mem_address;
cxt->dump_oops = pdata->dump_oops;
cxt->ecc = pdata->ecc;
- cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt, GFP_KERNEL);
- if (!cxt->przs) {
- err = -ENOMEM;
- dev_err(dev, "failed to initialize a prz array\n");
- goto fail_out;
- }
-
- for (i = 0; i < cxt->max_dump_cnt; i++) {
- size_t sz = cxt->record_size;
- phys_addr_t start = cxt->phys_addr + sz * i;
+ paddr = cxt->phys_addr;
- cxt->przs[i] = persistent_ram_new(start, sz, cxt->ecc);
- if (IS_ERR(cxt->przs[i])) {
- err = PTR_ERR(cxt->przs[i]);
- dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
- sz, (unsigned long long)start, err);
- goto fail_przs;
- }
+ dump_mem_sz = cxt->size;
+ err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
+ if (err) {
+ pr_err("memory size too small, minimum is %lu\n",
+ cxt->record_size);
+ goto fail_count;
}
cxt->pstore.data = cxt;
fail_clear:
cxt->pstore.bufsize = 0;
cxt->max_dump_cnt = 0;
-fail_przs:
- for (i = 0; cxt->przs[i]; i++)
- persistent_ram_free(cxt->przs[i]);
- kfree(cxt->przs);
+fail_count:
+ ramoops_free_przs(cxt);
fail_out:
return err;
}