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.l...@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(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 40d2e1d..4a03e1a 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -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);
 }
 
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index ce77aad..ae4dbe2 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -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
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 3eb32f6..14a4116 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -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 */
 
diff --git a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h
index 932016f..3ba235a 100644
--- a/drivers/edac/mpc85xx_edac.h
+++ b/drivers/edac/mpc85xx_edac.h
@@ -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.8.1.2


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to