static int mpc85xx_pci_err_remove(struct of_device *op) { struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev); struct mpc85xx_pci_pdata *pdata = pci->pvt_info; debugf0("%s()\n", __func__); out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, orig_pci_err_cap_dr); out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en); edac_pci_del_device(pci->dev); if (edac_op_state == EDAC_OPSTATE_INT) irq_dispose_mapping(pdata->irq); edac_pci_free_ctl_info(pci); return 0; }
static void amd8111_pci_remove(struct pci_dev *dev) { struct amd8111_pci_info *pci_info; for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++) if (pci_info->dev->device == dev->device) break; if (!pci_info->err_dev) /* should never happen */ return; if (pci_info->edac_dev) { edac_pci_del_device(pci_info->edac_dev->dev); edac_pci_free_ctl_info(pci_info->edac_dev); } if (pci_info->exit) pci_info->exit(pci_info); pci_dev_put(pci_info->dev); }
static void amd8131_remove(struct pci_dev *dev) { struct amd8131_dev_info *dev_info; for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE; dev_info++) if (dev_info->devfn == dev->devfn) break; if (dev_info->inst == NO_BRIDGE) return; if (dev_info->edac_dev) { edac_pci_del_device(dev_info->edac_dev->dev); edac_pci_free_ctl_info(dev_info->edac_dev); } if (amd8131_chipset.exit) amd8131_chipset.exit(dev_info); pci_dev_put(dev_info->dev); }
static int __devinit mpc85xx_pci_err_probe(struct of_device *op, const struct of_device_id *match) { struct edac_pci_ctl_info *pci; struct mpc85xx_pci_pdata *pdata; struct resource r; int res = 0; if (!devres_open_group(&op->dev, mpc85xx_pci_err_probe, GFP_KERNEL)) return -ENOMEM; pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mpc85xx_pci_err"); if (!pci) return -ENOMEM; pdata = pci->pvt_info; pdata->name = "mpc85xx_pci_err"; pdata->irq = NO_IRQ; dev_set_drvdata(&op->dev, pci); pci->dev = &op->dev; pci->mod_name = EDAC_MOD_STR; pci->ctl_name = pdata->name; pci->dev_name = op->dev.bus_id; if (edac_op_state == EDAC_OPSTATE_POLL) pci->edac_check = mpc85xx_pci_check; pdata->edac_idx = edac_pci_idx++; res = of_address_to_resource(op->node, 0, &r); if (res) { printk(KERN_ERR "%s: Unable to get resource for " "PCI 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->pci_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1); if (!pdata->pci_vbase) { printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__); res = -ENOMEM; goto err; } orig_pci_err_cap_dr = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR); /* PCI master abort is expected during config cycles */ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40); orig_pci_err_en = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN); /* disable master abort reporting */ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40); /* clear error bits */ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0); if (edac_pci_add_device(pci, pdata->edac_idx) > 0) { debugf3("%s(): failed edac_pci_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_pci_isr, IRQF_DISABLED, "[EDAC] PCI err", pci); if (res < 0) { printk(KERN_ERR "%s: Unable to requiest irq %d for " "MPC85xx PCI err\n", __func__, pdata->irq); irq_dispose_mapping(pdata->irq); res = -ENODEV; goto err2; } printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n", pdata->irq); } devres_remove_group(&op->dev, mpc85xx_pci_err_probe); debugf3("%s(): success\n", __func__); printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n"); return 0; err2: edac_pci_del_device(&op->dev); err: edac_pci_free_ctl_info(pci); devres_release_group(&op->dev, mpc85xx_pci_err_probe); return res; }