Hi Vladimir,

On 01/22/2016 12:02 AM, Vladimir Zapolskiy wrote:
Hi Thor,

On 21.01.2016 19:34, ttha...@opensource.altera.com wrote:
From: Thor Thayer <ttha...@opensource.altera.com>

Adding L2 Cache and On-Chip RAM EDAC support for the
Altera SoCs using the EDAC device  model. The SDRAM
controller is using the Memory Controller model.

Each type of ECC is individually configurable.

Signed-off-by: Thor Thayer <ttha...@opensource.altera.com>
Signed-off-by: Dinh Nguyen <dingu...@opensource.altera.com>

You are sending a change authored by yourself for review, but you add Dinh's
SoB, what's his role here?

See Documentation/SubmittingPatches "Sign your work".

[snip]

While I was working in a different group at Altera last year, Dinh submitted the previous patch revision so I kept his signed off by for continuity. I'll just use myself in the future. Thank you for clarifying.


+/*
+ * altr_edac_device_probe()
+ *     This is a generic EDAC device driver that will support
+ *     various Altera memory devices such as the L2 cache ECC and
+ *     OCRAM ECC as well as the memories for other peripherals.
+ *     Module specific initialization is done by passing the
+ *     function index in the device tree.
+ */
+static int altr_edac_device_probe(struct platform_device *pdev)
+{
+       struct edac_device_ctl_info *dci;
+       struct altr_edac_device_dev *drvdata;
+       struct resource *r;
+       int res = 0;
+       struct device_node *np = pdev->dev.of_node;
+       char *ecc_name = (char *)np->name;
+       static int dev_instance;
+       struct dentry *debugfs;
+
+       if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
+               edac_printk(KERN_ERR, EDAC_DEVICE,
+                           "Unable to open devm\n");
+               return -ENOMEM;
+       }
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               edac_printk(KERN_ERR, EDAC_DEVICE,
+                           "Unable to get mem resource\n");

Missing devres_release_group(&pdev->dev, NULL) on error path.

Yes. Thank you.

+               return -ENODEV;
+       }
+
+       if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
+                                    dev_name(&pdev->dev))) {
+               edac_printk(KERN_ERR, EDAC_DEVICE,
+                           "%s:Error requesting mem region\n", ecc_name);

See above.

+               return -EBUSY;
+       }
+
+       dci = edac_device_alloc_ctl_info(sizeof(*drvdata), ecc_name,
+                                        1, ecc_name, 1, 0, NULL, 0,
+                                        dev_instance++);
+
+       if (!dci) {
+               edac_printk(KERN_ERR, EDAC_DEVICE,
+                           "%s: Unable to allocate EDAC device\n", ecc_name);

See above.

+               return -ENOMEM;
+       }
+
+       drvdata = dci->pvt_info;
+       dci->dev = &pdev->dev;
+       platform_set_drvdata(pdev, dci);
+       drvdata->edac_dev_name = ecc_name;
+
+       drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+       if (!drvdata->base)
+               goto err;
+
+       /* Get driver specific data for this EDAC device */
+       drvdata->data = of_match_node(altr_edac_device_of_match, np)->data;
+
+       /* Check specific dependencies for the module */
+       if (drvdata->data->setup) {
+               res = drvdata->data->setup(pdev, drvdata->base);
+               if (res < 0)
+                       goto err;
+       }
+
+       drvdata->sb_irq = platform_get_irq(pdev, 0);
+       res = devm_request_irq(&pdev->dev, drvdata->sb_irq,
+                              altr_edac_device_handler,
+                              0, dev_name(&pdev->dev), dci);
+       if (res < 0)
+               goto err;
+
+       drvdata->db_irq = platform_get_irq(pdev, 1);
+       res = devm_request_irq(&pdev->dev, drvdata->db_irq,
+                              altr_edac_device_handler,
+                              0, dev_name(&pdev->dev), dci);
+       if (res < 0)
+               goto err;
+
+       dci->mod_name = "Altera ECC Manager";
+       dci->dev_name = drvdata->edac_dev_name;
+
+       debugfs = edac_debugfs_create_dir(ecc_name);
+       if (debugfs)
+               altr_create_edacdev_dbgfs(dci, drvdata->data, debugfs);
+
+       if (edac_device_add_device(dci))
+               goto err;
+
+       devres_close_group(&pdev->dev, NULL);
+
+       return 0;
+err:
+       edac_printk(KERN_ERR, EDAC_DEVICE,
+                   "%s:Error setting up EDAC device: %d\n", ecc_name, res);
+       devres_release_group(&pdev->dev, NULL);
+       edac_device_free_ctl_info(dci);
+
+       return res;
+}
+
+static int altr_edac_device_remove(struct platform_device *pdev)
+{
+       struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
+
+       edac_device_del_device(&pdev->dev);
+       edac_device_free_ctl_info(dci);
+
+       return 0;
+}
+
+static struct platform_driver altr_edac_device_driver = {
+       .probe =  altr_edac_device_probe,
+       .remove = altr_edac_device_remove,
+       .driver = {
+               .name = "altr_edac_device",
+               .of_match_table = altr_edac_device_of_match,
+       },
+};
+module_platform_driver(altr_edac_device_driver);
+
+/*********************** OCRAM EDAC Device Functions *********************/
+
+#ifdef CONFIG_EDAC_ALTERA_OCRAM
+
+static void *ocram_alloc_mem(size_t size, void **other)
+{
+       struct device_node *np;
+       struct gen_pool *gp;
+       void *sram_addr;
+
+       np = of_find_compatible_node(NULL, NULL, "altr,socfpga-ocram-ecc");
+       if (!np)
+               return NULL;
+
+       gp = of_gen_pool_get(np, "iram", 0);
+       if (!gp) {
+               of_node_put(np);
+               return NULL;
+       }
+       of_node_put(np);

        gp = of_gen_pool_get(np, "iram", 0);
        of_node_put(np);
        if (!gp)
                return NULL;

version is better.


I'm sorry, can you elaborate? Are you saying I should return something other than NULL?

+
+       sram_addr = (void *)gen_pool_alloc(gp, size / sizeof(size_t));
+       if (!sram_addr)
+               return NULL;
+
+       memset(sram_addr, 0, size);

Potential memory corruption, you allocate (size / sizeof(size_t)) bytes and
then write size bytes.


Yes, good catch. I thought I'd fixed this but missed it when I came back.

+       wmb();  /* Ensure data is written out */
+
+       *other = gp;    /* Remember this handle for freeing  later */
+
+       return sram_addr;
+}
+
+static void ocram_free_mem(void *p, size_t size, void *other)
+{
+       gen_pool_free((struct gen_pool *)other, (u32)p, size / sizeof(size_t));

See a comment above.

+}
+

--
With best wishes,
Vladimir


Thank you for reviewing.

Reply via email to