[PATCH v2 2/3] edac: Add L3/SoC support to the APM X-Gene SoC EDAC driver
Loc Ho
lho at apm.com
Wed Jul 29 16:39:10 PDT 2015
Hi Borislav,
>> +
>> +static void xgene_edac_l3_hw_init(struct edac_device_ctl_info *edac_dev,
>> + bool enable)
>
> arg alignment. It should be
>
> function name(arg1, arg2,
> arg3, arg4,
> arg5...
>
> Check your other functions too.
I will check and fix other functions if any. But this function is just
fine. It may be off just by the + extra character with patch
generation only.
>> +{
>> + struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
>> + struct dentry *edac_debugfs;
>> + char name[30];
>> +
>> + if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
>> + return;
>> +
>> + /*
>> + * Todo: Switch to common EDAC debug file system for edac device
>> + * when available.
>> + */
>
> What is that?
Debug folder node shows up at /sys/kernel/debug/<file here> while the
MC debug node shows up at /sys/kernel/debug/edac where <file here> is
the driver node name. It would be better if everything shows up at
/sys/kernel/debug/edac. For this to happen, I need EDAC core change to
provide an parent node.
>
>> + if (!ctx->edac->dfs) {
>> + ctx->edac->dfs = debugfs_create_dir(edac_dev->dev->kobj.name,
>> + NULL);
>> + if (!ctx->edac->dfs)
>> + return;
>> + }
>> + sprintf(name, "l3c%d", ctx->edac_idx);
>> + edac_debugfs = debugfs_create_dir(name, ctx->edac->dfs);
>> + if (!edac_debugfs)
>> + return;
>> +
>> + debugfs_create_file("l3_inject_ctrl", S_IWUSR, edac_debugfs, edac_dev,
>> + &xgene_edac_l3_debug_inject_fops);
>> +}
>> +
>> +static int xgene_edac_l3_add(struct xgene_edac *edac, struct device_node *np,
>> + int version)
>> +{
>> + struct edac_device_ctl_info *edac_dev;
>> + struct xgene_edac_dev_ctx *ctx;
>> + struct resource res;
>> + void __iomem *dev_csr;
>> + int edac_idx;
>> + int rc = 0;
>> +
>> + if (!devres_open_group(edac->dev, xgene_edac_l3_add, GFP_KERNEL))
>> + return -ENOMEM;
>> +
>> + rc = of_address_to_resource(np, 0, &res);
>> + if (rc < 0) {
>> + dev_err(edac->dev, "no L3 resource address\n");
>> + goto err;
>> + }
>> + dev_csr = devm_ioremap_resource(edac->dev, &res);
>> + if (IS_ERR(dev_csr)) {
>> + dev_err(edac->dev,
>> + "devm_ioremap_resource failed for L3 resource address\n");
>> + rc = PTR_ERR(dev_csr);
>> + goto err;
>> + }
>>
>> + edac_idx = edac_device_alloc_index();
>> + edac_dev = edac_device_alloc_ctl_info(sizeof(*ctx),
>> + "l3c", 1, "l3c", 1, 0, NULL, 0,
>> + edac_idx);
>> + if (!edac_dev) {
>> + rc = -ENOMEM;
>> + goto err;
>> + }
>> +
>> + ctx = edac_dev->pvt_info;
>> + ctx->dev_csr = dev_csr;
>> + ctx->name = "xgene_l3_err";
>> + ctx->edac_idx = edac_idx;
>> + ctx->edac = edac;
>> + ctx->edac_dev = edac_dev;
>> + ctx->ddev = *edac->dev;
>> + ctx->version = version;
>> + edac_dev->dev = &ctx->ddev;
>> + edac_dev->ctl_name = ctx->name;
>> + edac_dev->dev_name = ctx->name;
>> + edac_dev->mod_name = EDAC_MOD_STR;
>> +
>> + if (edac_op_state == EDAC_OPSTATE_POLL)
>> + edac_dev->edac_check = xgene_edac_l3_check;
>
> So depending on what SoC elements you detect, the last one's check
> function will win?
>
> If xgene_edac loads on multiple SoC elements, you need a global xgene
> check function for which l3, soc, mc, etc register...
No... each EDAC instance has its own context as we allocated via
function edac_device_alloc_ctl_info. Per type of instance will use the
same type function.
>> +
>> +static const char * const *xgene_edac_soc_mem_data(
>> + struct xgene_edac_dev_ctx *ctx)
>> +{
>> + switch (ctx->version) {
>> + case 1:
>> + return soc_mem_err_v1;
>> + default:
>> + return NULL;
>> + }
>> +}
>
> That's one badly formatted function used only once. Just move the logic
> there and kill it.
For format, code looks fine. In any case, I will roll this into the code.
>> +static int xgene_edac_soc_add(struct xgene_edac *edac, struct device_node *np,
>> + int version)
>> +{
>> + struct edac_device_ctl_info *edac_dev;
>> + struct xgene_edac_dev_ctx *ctx;
>> + void __iomem *dev_csr;
>> + struct resource res;
>> + int edac_idx;
>> + int rc = 0;
>> +
>> + if (!devres_open_group(edac->dev, xgene_edac_soc_add, GFP_KERNEL))
>> + return -ENOMEM;
>> +
>> + rc = of_address_to_resource(np, 0, &res);
>> + if (rc < 0) {
>> + dev_err(edac->dev, "no SoC resource address\n");
>> + goto err;
>> + }
>> + dev_csr = devm_ioremap_resource(edac->dev, &res);
>> + if (IS_ERR(dev_csr)) {
>> + dev_err(edac->dev,
>> + "devm_ioremap_resource failed for soc resource address\n");
>> + rc = PTR_ERR(dev_csr);
>> + goto err;
>> + }
>> +
>> + edac_idx = edac_device_alloc_index();
>> + edac_dev = edac_device_alloc_ctl_info(sizeof(*ctx),
>> + "SOC", 1, "SOC", 1, 2, NULL, 0,
>> + edac_idx);
>> + if (!edac_dev) {
>> + rc = -ENOMEM;
>> + goto err;
>> + }
>> +
>> + ctx = edac_dev->pvt_info;
>> + ctx->dev_csr = dev_csr;
>> + ctx->name = "xgene_soc_err";
>> + ctx->edac_idx = edac_idx;
>> + ctx->edac = edac;
>> + ctx->edac_dev = edac_dev;
>> + ctx->ddev = *edac->dev;
>> + ctx->version = version;
>> + edac_dev->dev = &ctx->ddev;
>> + edac_dev->ctl_name = ctx->name;
>> + edac_dev->dev_name = ctx->name;
>> + edac_dev->mod_name = EDAC_MOD_STR;
>> +
>> + if (edac_op_state == EDAC_OPSTATE_POLL)
>> + edac_dev->edac_check = xgene_edac_soc_check;
>
> Same here about the ->edac_check function.
Same comment as above.
-Loc
More information about the linux-arm-kernel
mailing list