static int highbank_l2_err_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 int octeon_l2c_remove(struct platform_device *pdev) { struct edac_device_ctl_info *l2c = platform_get_drvdata(pdev); edac_device_del_device(&pdev->dev); edac_device_free_ctl_info(l2c); return 0; }
static int qcom_llcc_edac_remove(struct platform_device *pdev) { struct edac_device_ctl_info *edev_ctl = dev_get_drvdata(&pdev->dev); edac_device_del_device(edev_ctl->dev); edac_device_free_ctl_info(edev_ctl); return 0; }
static int qcom_llcc_edac_probe(struct platform_device *pdev) { struct llcc_drv_data *llcc_driv_data = pdev->dev.platform_data; struct edac_device_ctl_info *edev_ctl; struct device *dev = &pdev->dev; int ecc_irq; int rc; rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap); if (rc) return rc; /* Allocate edac control info */ edev_ctl = edac_device_alloc_ctl_info(0, "qcom-llcc", 1, "bank", llcc_driv_data->num_banks, 1, NULL, 0, edac_device_alloc_index()); if (!edev_ctl) return -ENOMEM; edev_ctl->dev = dev; edev_ctl->mod_name = dev_name(dev); edev_ctl->dev_name = dev_name(dev); edev_ctl->ctl_name = "llcc"; edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE; edev_ctl->pvt_info = llcc_driv_data; rc = edac_device_add_device(edev_ctl); if (rc) goto out_mem; platform_set_drvdata(pdev, edev_ctl); /* Request for ecc irq */ ecc_irq = llcc_driv_data->ecc_irq; if (ecc_irq < 0) { rc = -ENODEV; goto out_dev; } rc = devm_request_irq(dev, ecc_irq, llcc_ecc_irq_handler, IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl); if (rc) goto out_dev; return rc; out_dev: edac_device_del_device(edev_ctl->dev); out_mem: edac_device_free_ctl_info(edev_ctl); return rc; }
/** * zynqmp_ocm_edac_remove - Unbind driver from controller * @pdev: Pointer to the platform_device struct * * Return: Unconditionally 0 */ static int zynqmp_ocm_edac_remove(struct platform_device *pdev) { struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); struct zynqmp_ocm_edac_priv *priv = dci->pvt_info; writel(OCM_CEUE_MASK, priv->baseaddr + OCM_IDS_OFST); edac_device_del_device(&pdev->dev); edac_device_free_ctl_info(dci); return 0; }
static int mpc85xx_l2_err_remove(struct of_device *op) { struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev); struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info; debugf0("%s()\n", __func__); if (edac_op_state == EDAC_OPSTATE_INT) { out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0); irq_dispose_mapping(pdata->irq); } out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable); edac_device_del_device(&op->dev); edac_device_free_ctl_info(edac_dev); return 0; }
/** * pl310_edac_l2_remove - Unbind driver from controller * @pdev: Pointer to the platform_device struct * * This routine unbinds the EDAC device controller instance associated * with the specified arm,pl310-cache controller described by the * OpenFirmware device tree node passed as a parameter. * * Return: Always returns 0 */ static int pl310_edac_l2_remove(struct platform_device *pdev) { struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); struct pl310_edac_l2_priv *priv = dci->pvt_info; u32 regval; if (edac_op_state != EDAC_OPSTATE_POLL) { regval = readl(priv->base+L2X0_INTR_MASK); regval &= ~(L2X0_INTR_PARRD_MASK | L2X0_INTR_PARRT_MASK); writel(regval, priv->base+L2X0_INTR_MASK); } edac_device_del_device(&pdev->dev); edac_device_free_ctl_info(dci); return 0; }
static void amd8111_dev_remove(struct pci_dev *dev) { struct amd8111_dev_info *dev_info; for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++) if (dev_info->dev->device == dev->device) break; if (!dev_info->err_dev) /* should never happen */ return; if (dev_info->edac_dev) { edac_device_del_device(dev_info->edac_dev->dev); edac_device_free_ctl_info(dev_info->edac_dev); } if (dev_info->exit) dev_info->exit(dev_info); pci_dev_put(dev_info->dev); }
static int __devinit mpc85xx_l2_err_probe(struct of_device *op, const struct of_device_id *match) { struct edac_device_ctl_info *edac_dev; struct mpc85xx_l2_pdata *pdata; struct resource r; int res; if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL)) return -ENOMEM; edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata), "cpu", 1, "L", 1, 2, NULL, 0, edac_dev_idx); if (!edac_dev) { devres_release_group(&op->dev, mpc85xx_l2_err_probe); return -ENOMEM; } pdata = edac_dev->pvt_info; pdata->name = "mpc85xx_l2_err"; pdata->irq = NO_IRQ; edac_dev->dev = &op->dev; dev_set_drvdata(edac_dev->dev, edac_dev); edac_dev->ctl_name = pdata->name; edac_dev->dev_name = pdata->name; res = of_address_to_resource(op->node, 0, &r); if (res) { printk(KERN_ERR "%s: Unable to get resource for " "L2 err regs\n", __func__); goto err; } /* we only need the error registers */ r.start += 0xe00; if (!devm_request_mem_region(&op->dev, r.start, r.end - r.start + 1, pdata->name)) { printk(KERN_ERR "%s: Error while requesting mem region\n", __func__); res = -EBUSY; goto err; } pdata->l2_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1); if (!pdata->l2_vbase) { printk(KERN_ERR "%s: Unable to setup L2 err regs\n", __func__); res = -ENOMEM; goto err; } out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0); orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS); /* clear the err_dis */ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0); edac_dev->mod_name = EDAC_MOD_STR; if (edac_op_state == EDAC_OPSTATE_POLL) edac_dev->edac_check = mpc85xx_l2_check; mpc85xx_set_l2_sysfs_attributes(edac_dev); pdata->edac_idx = edac_dev_idx++; if (edac_device_add_device(edac_dev) > 0) { debugf3("%s(): failed edac_device_add_device()\n", __func__); goto err; } if (edac_op_state == EDAC_OPSTATE_INT) { pdata->irq = irq_of_parse_and_map(op->node, 0); res = devm_request_irq(&op->dev, pdata->irq, mpc85xx_l2_isr, IRQF_DISABLED, "[EDAC] L2 err", edac_dev); if (res < 0) { printk(KERN_ERR "%s: Unable to requiest irq %d for " "MPC85xx L2 err\n", __func__, pdata->irq); irq_dispose_mapping(pdata->irq); res = -ENODEV; goto err2; } printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for L2 Err\n", pdata->irq); edac_dev->op_state = OP_RUNNING_INTERRUPT; out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK); } devres_remove_group(&op->dev, mpc85xx_l2_err_probe); debugf3("%s(): success\n", __func__); printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n"); return 0; err2: edac_device_del_device(&op->dev); err: devres_release_group(&op->dev, mpc85xx_l2_err_probe); edac_device_free_ctl_info(edac_dev); return res; }
static int highbank_l2_err_probe(struct platform_device *pdev) { const struct of_device_id *id; struct edac_device_ctl_info *dci; struct hb_l2_drvdata *drvdata; struct resource *r; int res = 0; dci = edac_device_alloc_ctl_info(sizeof(*drvdata), "cpu", 1, "L", 1, 2, NULL, 0, 0); if (!dci) return -ENOMEM; drvdata = dci->pvt_info; dci->dev = &pdev->dev; platform_set_drvdata(pdev, dci); if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "Unable to get mem resource\n"); res = -ENODEV; goto err; } if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), dev_name(&pdev->dev))) { dev_err(&pdev->dev, "Error while requesting mem region\n"); res = -EBUSY; goto err; } drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (!drvdata->base) { dev_err(&pdev->dev, "Unable to map regs\n"); res = -ENOMEM; goto err; } id = of_match_device(hb_l2_err_of_match, &pdev->dev); dci->mod_name = pdev->dev.driver->name; dci->ctl_name = id ? id->compatible : "unknown"; dci->dev_name = dev_name(&pdev->dev); if (edac_device_add_device(dci)) goto err; drvdata->db_irq = platform_get_irq(pdev, 0); res = devm_request_irq(&pdev->dev, drvdata->db_irq, highbank_l2_err_handler, 0, dev_name(&pdev->dev), dci); if (res < 0) goto err2; drvdata->sb_irq = platform_get_irq(pdev, 1); res = devm_request_irq(&pdev->dev, drvdata->sb_irq, highbank_l2_err_handler, 0, dev_name(&pdev->dev), dci); if (res < 0) goto err2; devres_close_group(&pdev->dev, NULL); return 0; err2: edac_device_del_device(&pdev->dev); err: devres_release_group(&pdev->dev, NULL); edac_device_free_ctl_info(dci); return res; }
/** * pl310_edac_l2_probe - Check controller and bind driver * @pdev: Pointer to the platform_device struct * * This routine probes a specific arm,pl310-cache instance for binding * with the driver. * * Return: 0 if the controller instance was successfully bound to the * driver; otherwise, < 0 on error. */ static int pl310_edac_l2_probe(struct platform_device *pdev) { struct edac_device_ctl_info *dci; struct pl310_edac_l2_priv *priv; int rc; struct resource *res; void __iomem *baseaddr; u32 regval; /* Get the data from the platform device */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); baseaddr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(baseaddr)) return PTR_ERR(baseaddr); /* Check for the ecc enable status */ if (pl310_edac_l2_get_paritystate(baseaddr) == false) { dev_err(&pdev->dev, "parity check not enabled\n"); return -ENXIO; } dci = edac_device_alloc_ctl_info(sizeof(*priv), "l2cache", 1, "L", 1, 1, NULL, 0, edac_device_alloc_index()); if (IS_ERR(dci)) return PTR_ERR(dci); priv = dci->pvt_info; priv->base = baseaddr; dci->dev = &pdev->dev; dci->mod_name = "pl310_edac_l2"; dci->ctl_name = "pl310_l2_controller"; dci->dev_name = dev_name(&pdev->dev); priv->irq = platform_get_irq(pdev, 0); rc = devm_request_irq(&pdev->dev, priv->irq, pl310_edac_l2_int_handler, 0, dev_name(&pdev->dev), (void *)dci); if (rc < 0) { dci->edac_check = pl310_edac_l2_poll_handler; edac_op_state = EDAC_OPSTATE_POLL; } rc = edac_device_add_device(dci); if (rc) { dev_err(&pdev->dev, "failed to register with EDAC core\n"); goto del_edac_device; } if (edac_op_state != EDAC_OPSTATE_POLL) { regval = readl(priv->base+L2X0_INTR_MASK); regval |= (L2X0_INTR_PARRD_MASK | L2X0_INTR_PARRT_MASK); writel(regval, priv->base+L2X0_INTR_MASK); } return rc; del_edac_device: edac_device_del_device(&pdev->dev); edac_device_free_ctl_info(dci); return rc; }
/** * zynqmp_ocm_edac_probe - Check controller and bind driver * @pdev: Pointer to the platform_device struct * * Probes a specific controller instance for binding with the driver. * * Return: 0 if the controller instance was successfully bound to the * driver; otherwise, < 0 on error. */ static int zynqmp_ocm_edac_probe(struct platform_device *pdev) { struct edac_device_ctl_info *dci; struct zynqmp_ocm_edac_priv *priv; int irq, status; struct resource *res; void __iomem *baseaddr; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); baseaddr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(baseaddr)) return PTR_ERR(baseaddr); if (!zynqmp_ocm_edac_get_eccstate(baseaddr)) { edac_printk(KERN_INFO, EDAC_DEVICE, "ECC not enabled - Disabling EDAC driver\n"); return -ENXIO; } dci = edac_device_alloc_ctl_info(sizeof(*priv), ZYNQMP_OCM_EDAC_STRING, 1, ZYNQMP_OCM_EDAC_STRING, 1, 0, NULL, 0, 0); if (!dci) { edac_printk(KERN_ERR, EDAC_DEVICE, "Unable to allocate EDAC device\n"); return -ENOMEM; } priv = dci->pvt_info; platform_set_drvdata(pdev, dci); dci->dev = &pdev->dev; priv->baseaddr = baseaddr; dci->mod_name = pdev->dev.driver->name; dci->ctl_name = ZYNQMP_OCM_EDAC_STRING; dci->dev_name = dev_name(&pdev->dev); zynqmp_set_ocm_edac_sysfs_attributes(dci); if (edac_device_add_device(dci)) goto free_dev_ctl; irq = platform_get_irq(pdev, 0); if (irq < 0) { edac_printk(KERN_ERR, EDAC_DEVICE, "No irq %d in DT\n", irq); return irq; } status = devm_request_irq(&pdev->dev, irq, zynqmp_ocm_edac_intr_handler, 0, dev_name(&pdev->dev), dci); if (status < 0) { edac_printk(KERN_ERR, EDAC_DEVICE, "Failed to request Irq\n"); goto free_edac_dev; } writel(OCM_CEUE_MASK, priv->baseaddr + OCM_IEN_OFST); return 0; free_edac_dev: edac_device_del_device(&pdev->dev); free_dev_ctl: edac_device_free_ctl_info(dci); return -1; }