From c92132f5980666c7a52ecb53d98226c9986d32cd Mon Sep 17 00:00:00 2001 From: Chunhe Lan Date: Mon, 25 Nov 2013 11:28:41 +0100 Subject: edac/85xx: Add PCIe error interrupt edac support Add pcie error interrupt edac support for mpc85xx, p3041, p4080, and p5020. The mpc85xx uses the legacy interrupt report mechanism - the error interrupts are reported directly to mpic. While the p3041/ p4080/p5020 attaches the most of error interrupts to interrupt zero. And report error interrupts to mpic via interrupt 0. This patch can handle both of them. Signed-off-by: Chunhe Lan Link: http://lkml.kernel.org/r/1384712714-8826-3-git-send-email-morbidrsa@gmail.com Cc: Doug Thompson Cc: Dave Jiang Signed-off-by: Johannes Thumshirn Signed-off-by: Borislav Petkov --- drivers/edac/mpc85xx_edac.c | 98 ++++++++++++++++++++++++++++++++++++++++----- drivers/edac/mpc85xx_edac.h | 7 ++++ 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index fd46b0bd5f2a..8f9182179a7c 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -1,6 +1,8 @@ /* * Freescale MPC85xx Memory Controller kenel module * + * Parts Copyrighted (c) 2013 by Freescale Semiconductor, Inc. + * * Author: Dave Jiang * * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under @@ -196,6 +198,42 @@ static void mpc85xx_pci_check(struct edac_pci_ctl_info *pci) edac_pci_handle_npe(pci, pci->ctl_name); } +static void mpc85xx_pcie_check(struct edac_pci_ctl_info *pci) +{ + struct mpc85xx_pci_pdata *pdata = pci->pvt_info; + u32 err_detect; + + err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR); + + pr_err("PCIe error(s) detected\n"); + pr_err("PCIe ERR_DR register: 0x%08x\n", err_detect); + pr_err("PCIe ERR_CAP_STAT register: 0x%08x\n", + in_be32(pdata->pci_vbase + MPC85XX_PCI_GAS_TIMR)); + pr_err("PCIe ERR_CAP_R0 register: 0x%08x\n", + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R0)); + pr_err("PCIe ERR_CAP_R1 register: 0x%08x\n", + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R1)); + pr_err("PCIe ERR_CAP_R2 register: 0x%08x\n", + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R2)); + pr_err("PCIe ERR_CAP_R3 register: 0x%08x\n", + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R3)); + + /* clear error bits */ + out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect); +} + +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, 0, 0, PCI_CAP_ID_EXP); +} + static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id) { struct edac_pci_ctl_info *pci = dev_id; @@ -207,7 +245,10 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id) if (!err_detect) return IRQ_NONE; - mpc85xx_pci_check(pci); + if (pdata->is_pcie) + mpc85xx_pcie_check(pci); + else + mpc85xx_pci_check(pci); return IRQ_HANDLED; } @@ -239,14 +280,22 @@ int 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->is_pcie = true; + dev_set_drvdata(&op->dev, pci); pci->dev = &op->dev; pci->mod_name = EDAC_MOD_STR; pci->ctl_name = pdata->name; pci->dev_name = dev_name(&op->dev); - if (edac_op_state == EDAC_OPSTATE_POLL) - pci->edac_check = mpc85xx_pci_check; + if (edac_op_state == EDAC_OPSTATE_POLL) { + if (pdata->is_pcie) + pci->edac_check = mpc85xx_pcie_check; + else + pci->edac_check = mpc85xx_pci_check; + } pdata->edac_idx = edac_pci_idx++; @@ -275,16 +324,26 @@ int mpc85xx_pci_err_probe(struct platform_device *op) goto err; } - orig_pci_err_cap_dr = - in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR); + if (pdata->is_pcie) { + orig_pci_err_cap_dr = + in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR); + out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, ~0); + orig_pci_err_en = + in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN); + out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, 0); + } else { + 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); + /* 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); + 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); + /* 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); @@ -297,7 +356,8 @@ int 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_DISABLED | IRQF_SHARED, "[EDAC] PCI err", pci); if (res < 0) { printk(KERN_ERR @@ -312,6 +372,22 @@ int mpc85xx_pci_err_probe(struct platform_device *op) pdata->irq); } + if (pdata->is_pcie) { + /* + * Enable all PCIe error interrupt & error detect except invalid + * PEX_CONFIG_ADDR/PEX_CONFIG_DATA access interrupt generation + * enable bit and invalid PEX_CONFIG_ADDR/PEX_CONFIG_DATA access + * detection enable bit. Because PCIe bus code to initialize and + * configure these PCIe devices on booting will use some invalid + * PEX_CONFIG_ADDR/PEX_CONFIG_DATA, edac driver prints the much + * notice information. So disable this detect to fix ugly print. + */ + out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0 + & ~PEX_ERR_ICCAIE_EN_BIT); + out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, 0 + | PEX_ERR_ICCAD_DISR_BIT); + } + devres_remove_group(&op->dev, mpc85xx_pci_err_probe); edac_dbg(3, "success\n"); printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n"); diff --git a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h index 932016f2cf06..8c6256436227 100644 --- a/drivers/edac/mpc85xx_edac.h +++ b/drivers/edac/mpc85xx_edac.h @@ -134,13 +134,19 @@ #define MPC85XX_PCI_ERR_DR 0x0000 #define MPC85XX_PCI_ERR_CAP_DR 0x0004 #define MPC85XX_PCI_ERR_EN 0x0008 +#define PEX_ERR_ICCAIE_EN_BIT 0x00020000 #define MPC85XX_PCI_ERR_ATTRIB 0x000c #define MPC85XX_PCI_ERR_ADDR 0x0010 +#define PEX_ERR_ICCAD_DISR_BIT 0x00020000 #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 MPC85XX_PCIE_ERR_CAP_R0 0x0028 +#define MPC85XX_PCIE_ERR_CAP_R1 0x002c +#define MPC85XX_PCIE_ERR_CAP_R2 0x0030 +#define MPC85XX_PCIE_ERR_CAP_R3 0x0034 struct mpc85xx_mc_pdata { char *name; @@ -158,6 +164,7 @@ struct mpc85xx_l2_pdata { struct mpc85xx_pci_pdata { char *name; + bool is_pcie; int edac_idx; void __iomem *pci_vbase; int irq; -- cgit v1.2.3-70-g09d2 From 7f3f5240ce64b2b59e2a9a338b4a38931724192a Mon Sep 17 00:00:00 2001 From: Aravind Gopalakrishnan Date: Wed, 4 Dec 2013 11:40:11 -0600 Subject: amd64_edac: Fix condition to verify max channels allowed for F15 M30h The value returned from 'f15_m30h_determine_channel' will always be 0x3 max. The condition (channel > 4 || channel < 0) works as hardware never returns a value of 4, but it leads to static checker analysis errors like http://marc.info/?l=linux-edac&m=138607615131951&w=2. Fix that. Reported-by: Dan Carpenter Signed-off-by: Aravind Gopalakrishnan Link: http://lkml.kernel.org/r/20131203130857.GA32170@elgon.mountain [ Boris: massage commit message a bit. ] Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index b53d0de17e15..e2079b2dfcb4 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1578,7 +1578,7 @@ static int f15_m30h_match_to_this_node(struct amd64_pvt *pvt, unsigned range, num_dcts_intlv, dct_sel); /* Verify we stay within the MAX number of channels allowed */ - if (channel > 4 || channel < 0) + if (channel > 3) return -EINVAL; leg_mmio_hole = (u8) (dct_cont_base_reg >> 1 & BIT(0)); -- cgit v1.2.3-70-g09d2 From ba935f40979b32924824759111ed95d35469c5fa Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 6 Dec 2013 10:23:08 +0100 Subject: EDAC: Remove DEFINE_PCI_DEVICE_TABLE macro Currently, there is no other bus that has something like this macro for their device ids. Thus, DEFINE_PCI_DEVICE_TABLE macro should be removed. Signed-off-by: Jingoo Han Link: http://lkml.kernel.org/r/001c01ceefb3$5724d860$056e8920$%han@samsung.com [ Boris: swap commit message with better one. ] Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 2 +- drivers/edac/amd76x_edac.c | 2 +- drivers/edac/e752x_edac.c | 2 +- drivers/edac/e7xxx_edac.c | 2 +- drivers/edac/i3000_edac.c | 2 +- drivers/edac/i3200_edac.c | 2 +- drivers/edac/i5000_edac.c | 2 +- drivers/edac/i5100_edac.c | 2 +- drivers/edac/i5400_edac.c | 2 +- drivers/edac/i7300_edac.c | 2 +- drivers/edac/i7core_edac.c | 2 +- drivers/edac/i82443bxgx_edac.c | 2 +- drivers/edac/i82860_edac.c | 2 +- drivers/edac/i82875p_edac.c | 2 +- drivers/edac/i82975x_edac.c | 2 +- drivers/edac/r82600_edac.c | 2 +- drivers/edac/sb_edac.c | 2 +- drivers/edac/x38_edac.c | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index e2079b2dfcb4..a2f1854891f3 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2795,7 +2795,7 @@ static void amd64_remove_one_instance(struct pci_dev *pdev) * PCI core identifies what devices are on a system during boot, and then * inquiry this table to see if this driver is for a given device found. */ -static DEFINE_PCI_DEVICE_TABLE(amd64_pci_table) = { +static const struct pci_device_id amd64_pci_table[] = { { .vendor = PCI_VENDOR_ID_AMD, .device = PCI_DEVICE_ID_AMD_K8_NB_MEMCTL, diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 96e3ee3460a5..3a501b530e11 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -333,7 +333,7 @@ static void amd76x_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(amd76x_pci_tbl) = { +static const struct pci_device_id amd76x_pci_tbl[] = { { PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD762}, diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index 644fec54681f..5fb01b03773a 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -1421,7 +1421,7 @@ static void e752x_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(e752x_pci_tbl) = { +static const struct pci_device_id e752x_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7520}, diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index 1c4056a50383..3cda79bc8b00 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -555,7 +555,7 @@ static void e7xxx_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(e7xxx_pci_tbl) = { +static const struct pci_device_id e7xxx_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 7205_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7205}, diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c index 694efcbf19c0..cd28b968e5c7 100644 --- a/drivers/edac/i3000_edac.c +++ b/drivers/edac/i3000_edac.c @@ -487,7 +487,7 @@ static void i3000_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(i3000_pci_tbl) = { +static const struct pci_device_id i3000_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 3000_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0, I3000}, diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c index be10a74b16ea..fa1326e5a4b0 100644 --- a/drivers/edac/i3200_edac.c +++ b/drivers/edac/i3200_edac.c @@ -466,7 +466,7 @@ static void i3200_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(i3200_pci_tbl) = { +static const struct pci_device_id i3200_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 3200_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0, I3200}, diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index 63b2194e8c20..72e07e3cf718 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c @@ -1530,7 +1530,7 @@ static void i5000_remove_one(struct pci_dev *pdev) * * The "E500P" device is the first device supported. */ -static DEFINE_PCI_DEVICE_TABLE(i5000_pci_tbl) = { +static const struct pci_device_id i5000_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I5000_DEV16), .driver_data = I5000P}, diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c index 157b934e8ce3..36a38ee94fa8 100644 --- a/drivers/edac/i5100_edac.c +++ b/drivers/edac/i5100_edac.c @@ -1213,7 +1213,7 @@ static void i5100_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(i5100_pci_tbl) = { +static const struct pci_device_id i5100_pci_tbl[] = { /* Device 16, Function 0, Channel 0 Memory Map, Error Flag/Mask, ... */ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5100_16) }, { 0, } diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c index 0a05bbceb08f..e080cbfa8fc9 100644 --- a/drivers/edac/i5400_edac.c +++ b/drivers/edac/i5400_edac.c @@ -1416,7 +1416,7 @@ static void i5400_remove_one(struct pci_dev *pdev) * * The "E500P" device is the first device supported. */ -static DEFINE_PCI_DEVICE_TABLE(i5400_pci_tbl) = { +static const struct pci_device_id i5400_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR)}, {0,} /* 0 terminated list. */ }; diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index 9004c64b169e..d63f4798f7d0 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c @@ -1160,7 +1160,7 @@ static void i7300_remove_one(struct pci_dev *pdev) * * Has only 8086:360c PCI ID */ -static DEFINE_PCI_DEVICE_TABLE(i7300_pci_tbl) = { +static const struct pci_device_id i7300_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7300_MCH_ERR)}, {0,} /* 0 terminated list. */ }; diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 80a963d64e58..87533ca7752e 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -394,7 +394,7 @@ static const struct pci_id_table pci_dev_table[] = { /* * pci_device_id table for which devices we are looking for */ -static DEFINE_PCI_DEVICE_TABLE(i7core_pci_tbl) = { +static const struct pci_device_id i7core_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)}, {0,} /* 0 terminated list. */ diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index 57fdb77903ba..d730e276d1a8 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c @@ -386,7 +386,7 @@ static void i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_remove_one); -static DEFINE_PCI_DEVICE_TABLE(i82443bxgx_pci_tbl) = { +static const struct pci_device_id i82443bxgx_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0)}, diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index 3e3e431c8301..3382f6344e42 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -288,7 +288,7 @@ static void i82860_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(i82860_pci_tbl) = { +static const struct pci_device_id i82860_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, I82860}, diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 2f8535fc451e..80573df0a4d7 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -527,7 +527,7 @@ static void i82875p_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(i82875p_pci_tbl) = { +static const struct pci_device_id i82875p_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 82875_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, I82875P}, diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c index 0c8d4b0eaa32..10b10521f62e 100644 --- a/drivers/edac/i82975x_edac.c +++ b/drivers/edac/i82975x_edac.c @@ -628,7 +628,7 @@ static void i82975x_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(i82975x_pci_tbl) = { +static const struct pci_device_id i82975x_pci_tbl[] = { { PCI_VEND_DEV(INTEL, 82975_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, I82975X diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index 2fd6a5490905..8f936bc7a010 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -383,7 +383,7 @@ static void r82600_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(r82600_pci_tbl) = { +static const struct pci_device_id r82600_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID) }, diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 8472405c5586..b5d254bb4913 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -461,7 +461,7 @@ static const struct pci_id_table pci_dev_descr_ibridge_table[] = { /* * pci_device_id table for which devices we are looking for */ -static DEFINE_PCI_DEVICE_TABLE(sbridge_pci_tbl) = { +static const struct pci_device_id sbridge_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA)}, {0,} /* 0 terminated list. */ diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c index 1a4df82376ba..4891b450830b 100644 --- a/drivers/edac/x38_edac.c +++ b/drivers/edac/x38_edac.c @@ -448,7 +448,7 @@ static void x38_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } -static DEFINE_PCI_DEVICE_TABLE(x38_pci_tbl) = { +static const struct pci_device_id x38_pci_tbl[] = { { PCI_VEND_DEV(INTEL, X38_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0, X38}, -- cgit v1.2.3-70-g09d2 From 79db57cef949cfd0fe7f53e30666bd6945ec400a Mon Sep 17 00:00:00 2001 From: Rashika Kheria Date: Sat, 14 Dec 2013 19:28:24 +0530 Subject: amd64_edac: Mark amd64_decode_bus_error as static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch marks the function amd64_decode_bus_error() as static because it is not used outside of amd64_edac.c. It also eliminates the following warning: drivers/edac/amd64_edac.c:2038:6: warning: no previous prototype for ‘amd64_decode_bus_error’ [-Wmissing-prototypes] Signed-off-by: Rashika Kheria Reviewed-by: Josh Triplett Link: http://lkml.kernel.org/r/7cddbd4c69ed493f183383e98853181aaf75b26b.1387029387.git.rashika.kheria@gmail.com Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index a2f1854891f3..6b2542e102e1 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2035,7 +2035,7 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, __log_bus_error(mci, &err, ecc_type); } -void amd64_decode_bus_error(int node_id, struct mce *m) +static void amd64_decode_bus_error(int node_id, struct mce *m) { __amd64_decode_bus_error(mcis[node_id], m); } -- cgit v1.2.3-70-g09d2 From df781d0386a3e29c31f1d8eaf845b3224e65dd7f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 15 Dec 2013 17:29:44 +0100 Subject: amd64_edac: Simplify code around decode_bus_error Drop wrapper function and prefixes. Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 6b2542e102e1..568e97fc1489 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2005,9 +2005,9 @@ static void __log_bus_error(struct mem_ctl_info *mci, struct err_info *err, string, ""); } -static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, - struct mce *m) +static inline void decode_bus_error(int node_id, struct mce *m) { + struct mem_ctl_info *mci = mcis[node_id]; struct amd64_pvt *pvt = mci->pvt_info; u8 ecc_type = (m->status >> 45) & 0x3; u8 xec = XEC(m->status, 0x1f); @@ -2035,11 +2035,6 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, __log_bus_error(mci, &err, ecc_type); } -static void amd64_decode_bus_error(int node_id, struct mce *m) -{ - __amd64_decode_bus_error(mcis[node_id], m); -} - /* * Use pvt->F2 which contains the F2 CPU PCI device to get the related * F1 (AddrMap) and F3 (Misc) devices. Return negative value on error. @@ -2680,7 +2675,7 @@ static int amd64_init_one_instance(struct pci_dev *F2) if (report_gart_errors) amd_report_gart_errors(true); - amd_register_ecc_decoder(amd64_decode_bus_error); + amd_register_ecc_decoder(decode_bus_error); mcis[nid] = mci; @@ -2777,7 +2772,7 @@ static void amd64_remove_one_instance(struct pci_dev *pdev) /* unregister from EDAC MCE */ amd_report_gart_errors(false); - amd_unregister_ecc_decoder(amd64_decode_bus_error); + amd_unregister_ecc_decoder(decode_bus_error); kfree(ecc_stngs[nid]); ecc_stngs[nid] = NULL; -- cgit v1.2.3-70-g09d2 From d1ea71cdc9801c829d97eb42204329c28a4b2f52 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 15 Dec 2013 17:54:27 +0100 Subject: amd64_edac: Remove "amd64" prefix from static functions No need for the namespace tagging there. Cleanup setup_pci_device while at it. Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 118 ++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 568e97fc1489..98e14ee4833c 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1,7 +1,7 @@ #include "amd64_edac.h" #include -static struct edac_pci_ctl_info *amd64_ctl_pci; +static struct edac_pci_ctl_info *pci_ctl; static int report_gart_errors; module_param(report_gart_errors, int, 0644); @@ -162,7 +162,7 @@ static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, * scan the scrub rate mapping table for a close or matching bandwidth value to * issue. If requested is too big, then use last maximum value found. */ -static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) +static int __set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) { u32 scrubval; int i; @@ -198,7 +198,7 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) return 0; } -static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw) +static int set_scrub_rate(struct mem_ctl_info *mci, u32 bw) { struct amd64_pvt *pvt = mci->pvt_info; u32 min_scrubrate = 0x5; @@ -210,10 +210,10 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw) if (pvt->fam == 0x15 && pvt->model < 0x10) f15h_select_dct(pvt, 0); - return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate); + return __set_scrub_rate(pvt->F3, bw, min_scrubrate); } -static int amd64_get_scrub_rate(struct mem_ctl_info *mci) +static int get_scrub_rate(struct mem_ctl_info *mci) { struct amd64_pvt *pvt = mci->pvt_info; u32 scrubval = 0; @@ -240,8 +240,7 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci) * returns true if the SysAddr given by sys_addr matches the * DRAM base/limit associated with node_id */ -static bool amd64_base_limit_match(struct amd64_pvt *pvt, u64 sys_addr, - u8 nid) +static bool base_limit_match(struct amd64_pvt *pvt, u64 sys_addr, u8 nid) { u64 addr; @@ -285,7 +284,7 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci, if (intlv_en == 0) { for (node_id = 0; node_id < DRAM_RANGES; node_id++) { - if (amd64_base_limit_match(pvt, sys_addr, node_id)) + if (base_limit_match(pvt, sys_addr, node_id)) goto found; } goto err_no_match; @@ -309,7 +308,7 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci, } /* sanity test for sys_addr */ - if (unlikely(!amd64_base_limit_match(pvt, sys_addr, node_id))) { + if (unlikely(!base_limit_match(pvt, sys_addr, node_id))) { amd64_warn("%s: sys_addr 0x%llx falls outside base/limit address" "range for node %d with node interleaving enabled.\n", __func__, sys_addr, node_id); @@ -660,7 +659,7 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16); * Determine if the DIMMs have ECC enabled. ECC is enabled ONLY if all the DIMMs * are ECC capable. */ -static unsigned long amd64_determine_edac_cap(struct amd64_pvt *pvt) +static unsigned long determine_edac_cap(struct amd64_pvt *pvt) { u8 bit; unsigned long edac_cap = EDAC_FLAG_NONE; @@ -675,9 +674,9 @@ static unsigned long amd64_determine_edac_cap(struct amd64_pvt *pvt) return edac_cap; } -static void amd64_debug_display_dimm_sizes(struct amd64_pvt *, u8); +static void debug_display_dimm_sizes(struct amd64_pvt *, u8); -static void amd64_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) +static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) { edac_dbg(1, "F2x%d90 (DRAM Cfg Low): 0x%08x\n", chan, dclr); @@ -711,7 +710,7 @@ static void dump_misc_regs(struct amd64_pvt *pvt) (pvt->nbcap & NBCAP_SECDED) ? "yes" : "no", (pvt->nbcap & NBCAP_CHIPKILL) ? "yes" : "no"); - amd64_dump_dramcfg_low(pvt, pvt->dclr0, 0); + debug_dump_dramcfg_low(pvt, pvt->dclr0, 0); edac_dbg(1, "F3xB0 (Online Spare): 0x%08x\n", pvt->online_spare); @@ -722,19 +721,19 @@ static void dump_misc_regs(struct amd64_pvt *pvt) edac_dbg(1, " DramHoleValid: %s\n", dhar_valid(pvt) ? "yes" : "no"); - amd64_debug_display_dimm_sizes(pvt, 0); + debug_display_dimm_sizes(pvt, 0); /* everything below this point is Fam10h and above */ if (pvt->fam == 0xf) return; - amd64_debug_display_dimm_sizes(pvt, 1); + debug_display_dimm_sizes(pvt, 1); amd64_info("using %s syndromes.\n", ((pvt->ecc_sym_sz == 8) ? "x8" : "x4")); /* Only if NOT ganged does dclr1 have valid info */ if (!dct_ganging_enabled(pvt)) - amd64_dump_dramcfg_low(pvt, pvt->dclr1, 1); + debug_dump_dramcfg_low(pvt, pvt->dclr1, 1); } /* @@ -800,7 +799,7 @@ static void read_dct_base_mask(struct amd64_pvt *pvt) } } -static enum mem_type amd64_determine_memory_type(struct amd64_pvt *pvt, int cs) +static enum mem_type determine_memory_type(struct amd64_pvt *pvt, int cs) { enum mem_type type; @@ -1702,7 +1701,7 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, * debug routine to display the memory sizes of all logical DIMMs and its * CSROWs */ -static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) +static void debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) { int dimm, size0, size1; u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases; @@ -1744,7 +1743,7 @@ static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) } } -static struct amd64_family_type amd64_family_types[] = { +static struct amd64_family_type family_types[] = { [K8_CPUS] = { .ctl_name = "K8", .f1_id = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP, @@ -2191,7 +2190,7 @@ static void read_mc_regs(struct amd64_pvt *pvt) * encompasses * */ -static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) +static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) { u32 cs_mode, nr_pages; u32 dbam = dct ? pvt->dbam1 : pvt->dbam0; @@ -2258,19 +2257,19 @@ static int init_csrows(struct mem_ctl_info *mci) pvt->mc_node_id, i); if (row_dct0) { - nr_pages = amd64_csrow_nr_pages(pvt, 0, i); + nr_pages = get_csrow_nr_pages(pvt, 0, i); csrow->channels[0]->dimm->nr_pages = nr_pages; } /* K8 has only one DCT */ if (pvt->fam != 0xf && row_dct1) { - int row_dct1_pages = amd64_csrow_nr_pages(pvt, 1, i); + int row_dct1_pages = get_csrow_nr_pages(pvt, 1, i); csrow->channels[1]->dimm->nr_pages = row_dct1_pages; nr_pages += row_dct1_pages; } - mtype = amd64_determine_memory_type(pvt, i); + mtype = determine_memory_type(pvt, i); edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages); @@ -2304,7 +2303,7 @@ static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, u16 nid) } /* check MCG_CTL on all the cpus on this node */ -static bool amd64_nb_mce_bank_enabled_on_node(u16 nid) +static bool nb_mce_bank_enabled_on_node(u16 nid) { cpumask_var_t mask; int cpu, nbe; @@ -2477,7 +2476,7 @@ static bool ecc_enabled(struct pci_dev *F3, u16 nid) ecc_en = !!(value & NBCFG_ECC_ENABLE); amd64_info("DRAM ECC %s.\n", (ecc_en ? "enabled" : "disabled")); - nb_mce_en = amd64_nb_mce_bank_enabled_on_node(nid); + nb_mce_en = nb_mce_bank_enabled_on_node(nid); if (!nb_mce_en) amd64_notice("NB MCE bank disabled, set MSR " "0x%08x[4] on node %d to enable.\n", @@ -2532,7 +2531,7 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci, if (pvt->nbcap & NBCAP_CHIPKILL) mci->edac_ctl_cap |= EDAC_FLAG_S4ECD4ED; - mci->edac_cap = amd64_determine_edac_cap(pvt); + mci->edac_cap = determine_edac_cap(pvt); mci->mod_name = EDAC_MOD_STR; mci->mod_ver = EDAC_AMD64_VERSION; mci->ctl_name = fam->ctl_name; @@ -2540,14 +2539,14 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci, mci->ctl_page_to_phys = NULL; /* memory scrubber interface */ - mci->set_sdram_scrub_rate = amd64_set_scrub_rate; - mci->get_sdram_scrub_rate = amd64_get_scrub_rate; + mci->set_sdram_scrub_rate = set_scrub_rate; + mci->get_sdram_scrub_rate = get_scrub_rate; } /* * returns a pointer to the family descriptor on success, NULL otherwise. */ -static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt) +static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) { struct amd64_family_type *fam_type = NULL; @@ -2558,29 +2557,29 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt) switch (pvt->fam) { case 0xf: - fam_type = &amd64_family_types[K8_CPUS]; - pvt->ops = &amd64_family_types[K8_CPUS].ops; + fam_type = &family_types[K8_CPUS]; + pvt->ops = &family_types[K8_CPUS].ops; break; case 0x10: - fam_type = &amd64_family_types[F10_CPUS]; - pvt->ops = &amd64_family_types[F10_CPUS].ops; + fam_type = &family_types[F10_CPUS]; + pvt->ops = &family_types[F10_CPUS].ops; break; case 0x15: if (pvt->model == 0x30) { - fam_type = &amd64_family_types[F15_M30H_CPUS]; - pvt->ops = &amd64_family_types[F15_M30H_CPUS].ops; + fam_type = &family_types[F15_M30H_CPUS]; + pvt->ops = &family_types[F15_M30H_CPUS].ops; break; } - fam_type = &amd64_family_types[F15_CPUS]; - pvt->ops = &amd64_family_types[F15_CPUS].ops; + fam_type = &family_types[F15_CPUS]; + pvt->ops = &family_types[F15_CPUS].ops; break; case 0x16: - fam_type = &amd64_family_types[F16_CPUS]; - pvt->ops = &amd64_family_types[F16_CPUS].ops; + fam_type = &family_types[F16_CPUS]; + pvt->ops = &family_types[F16_CPUS].ops; break; default: @@ -2596,7 +2595,7 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt) return fam_type; } -static int amd64_init_one_instance(struct pci_dev *F2) +static int init_one_instance(struct pci_dev *F2) { struct amd64_pvt *pvt = NULL; struct amd64_family_type *fam_type = NULL; @@ -2614,7 +2613,7 @@ static int amd64_init_one_instance(struct pci_dev *F2) pvt->F2 = F2; ret = -EINVAL; - fam_type = amd64_per_family_init(pvt); + fam_type = per_family_init(pvt); if (!fam_type) goto err_free; @@ -2698,8 +2697,8 @@ err_ret: return ret; } -static int amd64_probe_one_instance(struct pci_dev *pdev, - const struct pci_device_id *mc_type) +static int probe_one_instance(struct pci_dev *pdev, + const struct pci_device_id *mc_type) { u16 nid = amd_get_node_id(pdev); struct pci_dev *F3 = node_to_amd_nb(nid)->misc; @@ -2731,7 +2730,7 @@ static int amd64_probe_one_instance(struct pci_dev *pdev, goto err_enable; } - ret = amd64_init_one_instance(pdev); + ret = init_one_instance(pdev); if (ret < 0) { amd64_err("Error probing instance: %d\n", nid); restore_ecc_error_reporting(s, nid, F3); @@ -2747,7 +2746,7 @@ err_out: return ret; } -static void amd64_remove_one_instance(struct pci_dev *pdev) +static void remove_one_instance(struct pci_dev *pdev) { struct mem_ctl_info *mci; struct amd64_pvt *pvt; @@ -2838,8 +2837,8 @@ MODULE_DEVICE_TABLE(pci, amd64_pci_table); static struct pci_driver amd64_pci_driver = { .name = EDAC_MOD_STR, - .probe = amd64_probe_one_instance, - .remove = amd64_remove_one_instance, + .probe = probe_one_instance, + .remove = remove_one_instance, .id_table = amd64_pci_table, }; @@ -2848,23 +2847,18 @@ static void setup_pci_device(void) struct mem_ctl_info *mci; struct amd64_pvt *pvt; - if (amd64_ctl_pci) + if (pci_ctl) return; mci = mcis[0]; - if (mci) { - - pvt = mci->pvt_info; - amd64_ctl_pci = - edac_pci_create_generic_ctl(&pvt->F2->dev, EDAC_MOD_STR); - - if (!amd64_ctl_pci) { - pr_warning("%s(): Unable to create PCI control\n", - __func__); + if (!mci) + return; - pr_warning("%s(): PCI error report via EDAC not set\n", - __func__); - } + pvt = mci->pvt_info; + pci_ctl = edac_pci_create_generic_ctl(&pvt->F2->dev, EDAC_MOD_STR); + if (!pci_ctl) { + pr_warn("%s(): Unable to create PCI control\n", __func__); + pr_warn("%s(): PCI error report via EDAC not set\n", __func__); } } @@ -2920,8 +2914,8 @@ err_ret: static void __exit amd64_edac_exit(void) { - if (amd64_ctl_pci) - edac_pci_release_generic_ctl(amd64_ctl_pci); + if (pci_ctl) + edac_pci_release_generic_ctl(pci_ctl); pci_unregister_driver(&amd64_pci_driver); -- cgit v1.2.3-70-g09d2 From 95285933d086271c2e05edd3949a190551625928 Mon Sep 17 00:00:00 2001 From: Rashika Kheria Date: Sat, 14 Dec 2013 19:30:11 +0530 Subject: EDAC: Mark edac_create_debug_nodes as static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch marks the function edac_create_debug_nodes() as static because it is not used outside of edac_mc_sysfs.c. Thus, it also eliminates the following warning: drivers/edac/edac_mc_sysfs.c:917:5: warning: no previous prototype for ‘edac_create_debug_nodes’ [-Wmissing-prototypes] Signed-off-by: Rashika Kheria Reviewed-by: Josh Triplett Link: http://lkml.kernel.org/r/a1c863b08c0d6f67d03280cf908c771bf26a3239.1387029387.git.rashika.kheria@gmail.com Signed-off-by: Borislav Petkov --- drivers/edac/edac_mc_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 9f7e0e609516..51c0362acf5c 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -914,7 +914,7 @@ void __exit edac_debugfs_exit(void) debugfs_remove(edac_debugfs); } -int edac_create_debug_nodes(struct mem_ctl_info *mci) +static int edac_create_debug_nodes(struct mem_ctl_info *mci) { struct dentry *d, *parent; char name[80]; -- cgit v1.2.3-70-g09d2 From 8112c0cdf7b86f5917cdffcff4ffc477eaa62ed4 Mon Sep 17 00:00:00 2001 From: Rashika Kheria Date: Sat, 14 Dec 2013 19:32:09 +0530 Subject: sb_edac: Mark get_mci_for_node_id as static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch marks the function get_mci_for_node_id() as static because it is not used outside of sb_edac.c. Thus, it also eliminates the following warning: drivers/edac/sb_edac.c:918:22: warning: no previous prototype for ‘get_mci_for_node_id’ [-Wmissing-prototypes] Signed-off-by: Rashika Kheria Reviewed-by: Josh Triplett Link: http://lkml.kernel.org/r/0441f508186fc4eeabc8e9c3e4dde013d99405d4.1387029387.git.rashika.kheria@gmail.com Signed-off-by: Borislav Petkov --- drivers/edac/sb_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index b5d254bb4913..747421e03182 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -915,7 +915,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci) } } -struct mem_ctl_info *get_mci_for_node_id(u8 node_id) +static struct mem_ctl_info *get_mci_for_node_id(u8 node_id) { struct sbridge_dev *sbridge_dev; -- cgit v1.2.3-70-g09d2 From 90ed4988b8c030d65b41b7d13140e9376dc6ec5a Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Thu, 5 Dec 2013 10:37:56 -0500 Subject: e752x_edac: Fix pci_dev usage count In case the device 0, function 1 is not found using pci_get_device(), pci_scan_single_device() will be used but, differently than pci_get_device(), it allocates a pci_dev but doesn't does bump the usage count on the pci_dev and after few module removals and loads the pci_dev will be freed. Signed-off-by: Aristeu Rozanski Reviewed-by: mark gross Link: http://lkml.kernel.org/r/20131205153755.GL4545@redhat.com Signed-off-by: Borislav Petkov --- drivers/edac/e752x_edac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index 5fb01b03773a..92d54fa65f93 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -1182,9 +1182,11 @@ static int e752x_get_devs(struct pci_dev *pdev, int dev_idx, pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, pvt->dev_info->err_dev, pvt->bridge_ck); - if (pvt->bridge_ck == NULL) + if (pvt->bridge_ck == NULL) { pvt->bridge_ck = pci_scan_single_device(pdev->bus, PCI_DEVFN(0, 1)); + pci_dev_get(pvt->bridge_ck); + } if (pvt->bridge_ck == NULL) { e752x_printk(KERN_ERR, "error reporting device not found:" -- cgit v1.2.3-70-g09d2 From 881f0fcef9993992c24f5b649a3fb67fd4208f8f Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 30 Dec 2013 12:14:12 -0800 Subject: EDAC: Don't try to cancel workqueue when it's never setup We only setup a workqueue for edac devices that use the polling method. We still try to cancel the workqueue if an edac_device uses the irq method though. This causes a warning from debug objects when we remove an edac device: WARNING: CPU: 0 PID: 56 at lib/debugobjects.c:260 debug_print_object+0x98/0xc0() ODEBUG: assert_init not available (active state 0) object type: timer_list hint: stub_timer+0x0/0x28 Modules linked in: krait_edac(-) CPU: 0 PID: 56 Comm: rmmod Not tainted 3.12.0-rc2-00035-g15292a0 #69 (unwind_backtrace+0x0/0x144) (show_stack+0x20/0x24) (dump_stack+0x74/0xb4) (warn_slowpath_common+0x78/0x9c) (warn_slowpath_fmt+0x40/0x48) (debug_print_object+0x98/0xc0) (debug_object_assert_init+0xdc/0xec) (del_timer+0x24/0x7c) (try_to_grab_pending+0xc0/0x1b0) (cancel_delayed_work+0x2c/0xa0) (edac_device_workq_teardown+0x1c/0x38) (edac_device_del_device+0xb8/0xe4) (krait_edac_remove+0x50/0x70 [krait_edac]) (platform_drv_remove+0x24/0x28) (__device_release_driver+0x68/0xc0) (driver_detach+0xc4/0xc8) (bus_remove_driver+0xac/0x114) (driver_unregister+0x38/0x58) (platform_driver_unregister+0x1c/0x20) (krait_edac_driver_exit+0x14/0x1c [krait_edac]) (SyS_delete_module+0x178/0x2b4) Fix it by skipping the workqueue teardown for such devices. Signed-off-by: Stephen Boyd Link: http://lkml.kernel.org/r/1388434457-4194-2-git-send-email-sboyd@codeaurora.org Signed-off-by: Borislav Petkov --- drivers/edac/edac_device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index 102674346035..592af5f0cf39 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -437,6 +437,9 @@ void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev) { int status; + if (!edac_dev->edac_check) + return; + status = cancel_delayed_work(&edac_dev->work); if (status == 0) { /* workq instance might be running, wait for it */ -- cgit v1.2.3-70-g09d2