@@ -236,6 +236,7 @@ void fsl_arch_pci_sys_remove(struct fsl_pci *pci)
if (!hose)
return;
+ mpc85xx_pci_err_remove(to_platform_device(pci->dev));
pcibios_free_controller(hose);
}
@@ -35,11 +35,17 @@ static inline void fsl_pci_assign_primary(void) {}
#ifdef CONFIG_EDAC_MPC85XX
int mpc85xx_pci_err_probe(struct platform_device *op);
+int mpc85xx_pci_err_remove(struct platform_device *op);
#else
static inline int mpc85xx_pci_err_probe(struct platform_device *op)
{
return -ENOTSUPP;
}
+static inline int mpc85xx_pci_err_remove(struct platform_device *op)
+{
+ return -ENOTSUPP;
+}
+
#endif
#ifdef CONFIG_FSL_PCI
@@ -21,6 +21,7 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
+#include <linux/fsl/pci-common.h>
#include "edac_module.h"
#include "edac_core.h"
#include "mpc85xx_edac.h"
@@ -214,11 +215,13 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
int mpc85xx_pci_err_probe(struct platform_device *op)
{
+ struct fsl_pci *fslpci;
struct edac_pci_ctl_info *pci;
struct mpc85xx_pci_pdata *pdata;
- struct resource r;
int res = 0;
+ fslpci = platform_get_drvdata(op);
+
if (!devres_open_group(&op->dev, mpc85xx_pci_err_probe, GFP_KERNEL))
return -ENOMEM;
@@ -239,7 +242,6 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
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;
@@ -250,30 +252,8 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
pdata->edac_idx = edac_pci_idx++;
- res = of_address_to_resource(op->dev.of_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, resource_size(&r),
- 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, resource_size(&r));
- if (!pdata->pci_vbase) {
- printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
- res = -ENOMEM;
- goto err;
- }
+ pdata->pci_vbase = (void *)fslpci->regs + MPC85XX_PCI_ERR_OFFSET;
orig_pci_err_cap_dr =
in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
@@ -327,20 +307,25 @@ err:
}
EXPORT_SYMBOL(mpc85xx_pci_err_probe);
-static int mpc85xx_pci_err_remove(struct platform_device *op)
+int mpc85xx_pci_err_remove(struct platform_device *op)
{
- struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
- struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
+ struct edac_pci_ctl_info *pci;
+ struct mpc85xx_pci_pdata *pdata;
edac_dbg(0, "\n");
+ pci = edac_pci_del_device(&op->dev);
+
+ if (!pci)
+ return -EINVAL;
+
+ pdata = pci->pvt_info;
+
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);
@@ -348,6 +333,7 @@ static int mpc85xx_pci_err_remove(struct platform_device *op)
return 0;
}
+EXPORT_SYMBOL(mpc85xx_pci_err_remove);
#endif /* CONFIG_PCI */
@@ -131,6 +131,7 @@
#define PCI_EDE_PERR_MASK (PCI_EDE_TGT_PERR | PCI_EDE_MST_PERR | \
PCI_EDE_ADDR_PERR)
+#define MPC85XX_PCI_ERR_OFFSET 0x0e00
#define MPC85XX_PCI_ERR_DR 0x0000
#define MPC85XX_PCI_ERR_CAP_DR 0x0004
#define MPC85XX_PCI_ERR_EN 0x0008
1. The pci-fsl-common driver has set fsl_pci to device as drvdata, so EDAC driver can not call dev_set_drvdata() again. fsl_pci contains regs field to point PCI CCSR, so EDAC may directly use the pointer and not need to call devm_ioremap(). 2. Add mpc85xx_pci_err_remove() to disable PCI error interrupt and delete PCI EDAC from EDAC subsystem. Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> --- change log: v1-v3: Derived from http://patchwork.ozlabs.org/patch/278965/ Added mpc85xx_pci_err_remove() Based on upstream master. Based on the discussion of RFC version here http://patchwork.ozlabs.org/patch/274487/ arch/powerpc/sysdev/fsl_pci.c | 1 + arch/powerpc/sysdev/fsl_pci.h | 6 ++++++ drivers/edac/mpc85xx_edac.c | 46 +++++++++++++++---------------------------- drivers/edac/mpc85xx_edac.h | 1 + 4 files changed, 24 insertions(+), 30 deletions(-)