Hi all, Any concerns of this patch?
Best Regards, Shaohui Xie >-----Original Message----- >From: Xie Shaohui-B21989 >Sent: Tuesday, July 26, 2011 2:52 PM >To: linuxppc-dev@lists.ozlabs.org; Kumar Gala >Cc: mm-comm...@vger.kernel.org; avoront...@mvista.com; da...@davemloft.net; >grant.lik...@secretlab.ca; a...@linux-foundation.org; Jiang Kai-B18973 >Subject: RE: [PATCH 4/4] edac/85xx: PCI/PCIE error interrupt edac support. > >I've verified this patch can apply for galak/powerpc.git 'next' branch >with no change. > > >Best Regards, >Shaohui Xie > > >>-----Original Message----- >>From: Xie Shaohui-B21989 >>Sent: Thursday, July 21, 2011 6:33 PM >>To: linuxppc-dev@lists.ozlabs.org >>Cc: Gala Kumar-B11780; mm-comm...@vger.kernel.org; avoront...@mvista.com; >>da...@davemloft.net; grant.lik...@secretlab.ca; a...@linux-foundation.org; >>Jiang Kai-B18973; Kumar Gala; Xie Shaohui-B21989 >>Subject: [PATCH 4/4] edac/85xx: PCI/PCIE error interrupt edac support. >> >>From: Kai.Jiang <kai.ji...@freescale.com> >> >>Add pcie error interrupt edac support for mpc85xx and p4080. >>mpc85xx uses the legacy interrupt report mechanism - the error interrupts >>are reported directly to mpic. While, p4080 attaches most of error >>interrupts to interrupt 0. And report error interrupt to mpic via >>interrupt 0. This patch can handle both of them. >> >> >>Due to the error management register offset and definition >> >>difference between pci and pcie, use ccsr_pci structure to merge pci and >>pcie edac code into one. >> >>Signed-off-by: Kai.Jiang <kai.ji...@freescale.com> >>Signed-off-by: Kumar Gala <ga...@kernel.crashing.org> >>Signed-off-by: Shaohui Xie <shaohui....@freescale.com> >>--- >> drivers/edac/mpc85xx_edac.c | 239 ++++++++++++++++++++++++++++++++----- >- >>---- >> drivers/edac/mpc85xx_edac.h | 17 +-- >> 2 files changed, 188 insertions(+), 68 deletions(-) >> >>diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c >>index b048a5f..dde156f 100644 >>--- a/drivers/edac/mpc85xx_edac.c >>+++ b/drivers/edac/mpc85xx_edac.c >>@@ -1,5 +1,6 @@ >> /* >> * Freescale MPC85xx Memory Controller kenel module >>+ * Copyright (c) 2011 Freescale Semiconductor, Inc. >> * >> * Author: Dave Jiang <dji...@mvista.com> >> * >>@@ -21,6 +22,8 @@ >> >> #include <linux/of_platform.h> >> #include <linux/of_device.h> >>+#include <include/asm/pci.h> >>+#include <sysdev/fsl_pci.h> >> #include "edac_module.h" >> #include "edac_core.h" >> #include "mpc85xx_edac.h" >>@@ -34,14 +37,6 @@ static int edac_mc_idx; static u32 >>orig_ddr_err_disable; static u32 orig_ddr_err_sbe; >> >>-/* >>- * PCI Err defines >>- */ >>-#ifdef CONFIG_PCI >>-static u32 orig_pci_err_cap_dr; >>-static u32 orig_pci_err_en; >>-#endif >>- >> static u32 orig_l2_err_disable; >> #ifdef CONFIG_FSL_SOC_BOOKE >> static u32 orig_hid1[2]; >>@@ -151,37 +146,52 @@ static void mpc85xx_pci_check(struct >>edac_pci_ctl_info *pci) { >> struct mpc85xx_pci_pdata *pdata = pci->pvt_info; >> u32 err_detect; >>+ struct ccsr_pci *reg = pdata->pci_reg; >>+ >>+ err_detect = in_be32(&pdata->pci_reg->pex_err_dr); >>+ >>+ if (pdata->pcie_flag) { >>+ printk(KERN_ERR "PCIE error(s) detected\n"); >>+ printk(KERN_ERR "PCIE ERR_DR register: 0x%08x\n", err_detect); >>+ printk(KERN_ERR "PCIE ERR_CAP_STAT register: 0x%08x\n", >>+ in_be32(®->pex_err_cap_stat)); >>+ printk(KERN_ERR "PCIE ERR_CAP_R0 register: 0x%08x\n", >>+ in_be32(®->pex_err_cap_r0)); >>+ printk(KERN_ERR "PCIE ERR_CAP_R1 register: 0x%08x\n", >>+ in_be32(®->pex_err_cap_r1)); >>+ printk(KERN_ERR "PCIE ERR_CAP_R2 register: 0x%08x\n", >>+ in_be32(®->pex_err_cap_r2)); >>+ printk(KERN_ERR "PCIE ERR_CAP_R3 register: 0x%08x\n", >>+ in_be32(®->pex_err_cap_r3)); >>+ } else { >>+ /* master aborts can happen during PCI config cycles */ >>+ if (!(err_detect & ~(PCI_EDE_MULTI_ERR | PCI_EDE_MST_ABRT))) { >>+ out_be32(®->pex_err_dr, err_detect); >>+ return; >>+ } >> >>- err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR); >>- >>- /* master aborts can happen during PCI config cycles */ >>- if (!(err_detect & ~(PCI_EDE_MULTI_ERR | PCI_EDE_MST_ABRT))) { >>- out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect); >>- return; >>+ printk(KERN_ERR "PCI error(s) detected\n"); >>+ printk(KERN_ERR "PCI/X ERR_DR register: 0x%08x\n", err_detect); >>+ printk(KERN_ERR "PCI/X ERR_ATTRIB register: 0x%08x\n", >>+ in_be32(®->pex_err_attrib)); >>+ printk(KERN_ERR "PCI/X ERR_ADDR register: 0x%08x\n", >>+ in_be32(®->pex_err_disr)); >>+ printk(KERN_ERR "PCI/X ERR_EXT_ADDR register: 0x%08x\n", >>+ in_be32(®->pex_err_ext_addr)); >>+ printk(KERN_ERR "PCI/X ERR_DL register: 0x%08x\n", >>+ in_be32(®->pex_err_dl)); >>+ printk(KERN_ERR "PCI/X ERR_DH register: 0x%08x\n", >>+ in_be32(®->pex_err_dh)); >>+ >>+ if (err_detect & PCI_EDE_PERR_MASK) >>+ edac_pci_handle_pe(pci, pci->ctl_name); >>+ >>+ if ((err_detect & ~PCI_EDE_MULTI_ERR) & ~PCI_EDE_PERR_MASK) >>+ edac_pci_handle_npe(pci, pci->ctl_name); >> } >> >>- printk(KERN_ERR "PCI error(s) detected\n"); >>- printk(KERN_ERR "PCI/X ERR_DR register: %#08x\n", err_detect); >>- >>- printk(KERN_ERR "PCI/X ERR_ATTRIB register: %#08x\n", >>- in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ATTRIB)); >>- printk(KERN_ERR "PCI/X ERR_ADDR register: %#08x\n", >>- in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR)); >>- printk(KERN_ERR "PCI/X ERR_EXT_ADDR register: %#08x\n", >>- in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EXT_ADDR)); >>- printk(KERN_ERR "PCI/X ERR_DL register: %#08x\n", >>- in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DL)); >>- printk(KERN_ERR "PCI/X ERR_DH register: %#08x\n", >>- in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DH)); >>- >> /* clear error bits */ >>- out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect); >>- >>- if (err_detect & PCI_EDE_PERR_MASK) >>- edac_pci_handle_pe(pci, pci->ctl_name); >>- >>- if ((err_detect & ~PCI_EDE_MULTI_ERR) & ~PCI_EDE_PERR_MASK) >>- edac_pci_handle_npe(pci, pci->ctl_name); >>+ out_be32(®->pex_err_dr, err_detect); >> } >> >> static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id) @@ -190,7 >>+200,7 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id) >> struct mpc85xx_pci_pdata *pdata = pci->pvt_info; >> u32 err_detect; >> >>- err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR); >>+ err_detect = in_be32(&pdata->pci_reg->pex_err_dr); >> >> if (!err_detect) >> return IRQ_NONE; >>@@ -200,11 +210,99 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void >>*dev_id) >> return IRQ_HANDLED; >> } >> >>+#define MPC85XX_MPIC_EIMR0 0x3910 >>+/* >>+ * This function is for error interrupt ORed mechanism. >>+ * This mechanism attaches most functions' error interrupts to interrupt >>0. >>+ * And report error interrupt to mpic via interrupt 0. >>+ * EIMR0 - Error Interrupt Mask Register 0. >>+ * >>+ * This function check whether the device support error interrupt ORed >>+ * mechanism via device tree. If supported, umask pcie error interrupt >>+ * bit in EIMR0. >>+ */ >>+static int mpc85xx_err_int_en(struct device *op) { >>+ u32 *int_cell = NULL; >>+ struct device_node *np = NULL; >>+ void __iomem *mpic_base = NULL; >>+ u32 reg_tmp = 0; >>+ u32 int_len = 0; >>+ struct resource r; >>+ int res = 0; >>+ >>+ if (!op->of_node) >>+ return -EINVAL; >>+ /* >>+ * Unmask pcie error interrupt bit in EIMR0 >>+ * extend interrupt specifier has 4 cells. For the 3rd cell: >>+ * 0 -- normal interrupt; 1 -- error interrupt. >>+ */ >>+ int_cell = (u32 *)of_get_property(op->of_node, "interrupts", >>&int_len); >>+ if ((int_len/sizeof(u32)) == 4) { >>+ /* soc has error interrupt integration handling mechanism */ >>+ if (*(int_cell + 2) == 1) { >>+ np = of_find_node_by_type(NULL, "open-pic"); >>+ >>+ if (of_address_to_resource(np, 0, &r)) { >>+ printk(KERN_ERR >>+ "%s:Failed to map mpic regs\n", __func__); >>+ of_node_put(np); >>+ res = -ENOMEM; >>+ goto err; >>+ } >>+ >>+ if (!request_mem_region(r.start, >>+ r.end - r.start + 1, "mpic")) { >>+ printk(KERN_ERR >>+ "%s:Error while requesting mem region\n", >>+ __func__); >>+ res = -EBUSY; >>+ goto err; >>+ } >>+ >>+ mpic_base = ioremap(r.start, r.end - r.start + 1); >>+ if (!mpic_base) { >>+ printk(KERN_ERR >>+ "%s:Unable to map mpic regs\n", __func__); >>+ res = -ENOMEM; >>+ goto err_ioremap; >>+ } >>+ >>+ reg_tmp = in_be32(mpic_base + MPC85XX_MPIC_EIMR0); >>+ out_be32(mpic_base + MPC85XX_MPIC_EIMR0, >>+ reg_tmp & ~(1 << (31 - *(int_cell + 3)))); >>+ iounmap(mpic_base); >>+ release_mem_region(r.start, r.end - r.start + 1); >>+ of_node_put(np); >>+ } >>+ } >>+ >>+ return 0; >>+err_ioremap: >>+ release_mem_region(r.start, r.end - r.start + 1); >>+err: >>+ >>+ return res; >>+} >>+ >>+static int mpc85xx_pcie_find_capability(struct device_node *np) { >>+ struct pci_controller *hose; >>+ if (!np) >>+ return -EINVAL; >>+ >>+ hose = pci_find_hose_for_OF_device(np); >>+ return early_find_capability(hose, hose->bus->number, >>+ 0, PCI_CAP_ID_EXP); >>+} >>+ >> static int __devinit mpc85xx_pci_err_probe(struct platform_device *op) >{ >> struct edac_pci_ctl_info *pci; >> struct mpc85xx_pci_pdata *pdata; >> struct resource r; >>+ struct ccsr_pci *reg = NULL; >> int res = 0; >> >> if (!devres_open_group(&op->dev, mpc85xx_pci_err_probe, GFP_KERNEL)) >>@@ -217,6 +315,10 @@ static int __devinit mpc85xx_pci_err_probe(struct >>platform_device *op) >> pdata = pci->pvt_info; >> pdata->name = "mpc85xx_pci_err"; >> pdata->irq = NO_IRQ; >>+ >>+ if (mpc85xx_pcie_find_capability(op->dev.of_node) > 0) >>+ pdata->pcie_flag = 1; >>+ >> dev_set_drvdata(&op->dev, pci); >> pci->dev = &op->dev; >> pci->mod_name = EDAC_MOD_STR; >>@@ -235,37 +337,40 @@ static int __devinit mpc85xx_pci_err_probe(struct >>platform_device *op) >> 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__); >>+ 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) { >>+ pdata->pci_reg = devm_ioremap(&op->dev, r.start, resource_size(&r)); >>+ if (!pdata->pci_reg) { >> 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); >>+ if (mpc85xx_err_int_en(&op->dev) < 0) >>+ goto err; >> >>- orig_pci_err_en = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN); >>+ reg = pdata->pci_reg; >>+ /* disable pci/pcie error detect */ >>+ if (pdata->pcie_flag) { >>+ pdata->orig_pci_err_dr = in_be32(®->pex_err_disr); >>+ out_be32(®->pex_err_disr, ~0); >>+ } else { >>+ pdata->orig_pci_err_dr = in_be32(®->pex_err_cap_dr); >>+ out_be32(®->pex_err_cap_dr, ~0); >>+ } >> >>- /* disable master abort reporting */ >>- out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40); >>+ /* disable all pcie error interrupt */ >>+ pdata->orig_pci_err_en = in_be32(®->pex_err_en); >>+ out_be32(®->pex_err_en, 0); >> >>- /* clear error bits */ >>- out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0); >>+ /* clear all error bits */ >>+ out_be32(®->pex_err_dr, ~0); >> >> if (edac_pci_add_device(pci, pdata->edac_idx) > 0) { >> debugf3("%s(): failed edac_pci_add_device()\n", __func__); @@ >>-275,7 +380,7 @@ static int __devinit mpc85xx_pci_err_probe(struct >>platform_device *op) >> if (edac_op_state == EDAC_OPSTATE_INT) { >> pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); >> res = devm_request_irq(&op->dev, pdata->irq, >>- mpc85xx_pci_isr, IRQF_DISABLED, >>+ mpc85xx_pci_isr, IRQF_SHARED, >> "[EDAC] PCI err", pci); >> if (res < 0) { >> printk(KERN_ERR >>@@ -290,6 +395,17 @@ static int __devinit mpc85xx_pci_err_probe(struct >>platform_device *op) >> pdata->irq); >> } >> >>+ if (pdata->pcie_flag) { >>+ /* enable all pcie error interrupt & error detect */ >>+ out_be32(®->pex_err_en, ~0); >>+ out_be32(®->pex_err_disr, 0); >>+ } else { >>+ /* PCI master abort is expected during config cycles */ >>+ out_be32(®->pex_err_cap_dr, PCI_ERR_CAP_DR_DIS_MST); >>+ /* disable master abort reporting */ >>+ out_be32(®->pex_err_en, PCI_ERR_EN_DIS_MST); >>+ } >>+ >> devres_remove_group(&op->dev, mpc85xx_pci_err_probe); >> debugf3("%s(): success\n", __func__); >> printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n"); @@ -311,10 >>+427,13 @@ static int mpc85xx_pci_err_remove(struct platform_device *op) >> >> debugf0("%s()\n", __func__); >> >>- out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, >>- orig_pci_err_cap_dr); >>+ if (pdata->pcie_flag) >>+ out_be32(&pdata->pci_reg->pex_err_disr, pdata- >>>orig_pci_err_dr); >>+ else >>+ out_be32(&pdata->pci_reg->pex_err_cap_dr, >>+ pdata->orig_pci_err_dr); >> >>- out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en); >>+ out_be32(&pdata->pci_reg->pex_err_en, pdata->orig_pci_err_en); >> >> edac_pci_del_device(pci->dev); >> >>@@ -333,6 +452,12 @@ static struct of_device_id mpc85xx_pci_err_of_match[] >>= { >> { >> .compatible = "fsl,mpc8540-pci", >> }, >>+ { >>+ .compatible = "fsl,mpc8548-pcie", >>+ }, >>+ { >>+ .compatible = "fsl,p4080-pcie", >>+ }, >> {}, >> }; >> MODULE_DEVICE_TABLE(of, mpc85xx_pci_err_of_match); diff --git >>a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h index >>932016f..d0e7b11 100644 >>--- a/drivers/edac/mpc85xx_edac.h >>+++ b/drivers/edac/mpc85xx_edac.h >>@@ -131,16 +131,8 @@ >> #define PCI_EDE_PERR_MASK (PCI_EDE_TGT_PERR | PCI_EDE_MST_PERR | \ >> PCI_EDE_ADDR_PERR) >> >>-#define MPC85XX_PCI_ERR_DR 0x0000 >>-#define MPC85XX_PCI_ERR_CAP_DR 0x0004 >>-#define MPC85XX_PCI_ERR_EN 0x0008 >>-#define MPC85XX_PCI_ERR_ATTRIB 0x000c >>-#define MPC85XX_PCI_ERR_ADDR 0x0010 >>-#define MPC85XX_PCI_ERR_EXT_ADDR 0x0014 >>-#define MPC85XX_PCI_ERR_DL 0x0018 >>-#define MPC85XX_PCI_ERR_DH 0x001c >>-#define MPC85XX_PCI_GAS_TIMR 0x0020 >>-#define MPC85XX_PCI_PCIX_TIMR 0x0024 >>+#define PCI_ERR_CAP_DR_DIS_MST 0x40 >>+#define PCI_ERR_EN_DIS_MST (~0x40) >> >> struct mpc85xx_mc_pdata { >> char *name; >>@@ -159,8 +151,11 @@ struct mpc85xx_l2_pdata { struct mpc85xx_pci_pdata >{ >> char *name; >> int edac_idx; >>- void __iomem *pci_vbase; >> int irq; >>+ struct ccsr_pci *pci_reg; >>+ u8 pcie_flag; >>+ u32 orig_pci_err_dr; >>+ u32 orig_pci_err_en; >> }; >> >> #endif >>-- >>1.6.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev