aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-08-10 10:22:01 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-24 09:20:12 -0400
commit939747bd680eb09bb98792b17a5bfd2f525afe9d (patch)
tree694fc4a5bd213b7723217123a60c4361375667d4
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
i7core_edac: Be sure that the edac pci handler will be properly released
With multi-sockets, more than one edac pci handler is enabled. Be sure to un-register all instances. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/edac/edac_core.h1
-rw-r--r--drivers/edac/edac_mc.c6
-rw-r--r--drivers/edac/i7core_edac.c38
3 files changed, 28 insertions, 17 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index ce7146677e9b..7450fd3bdf0b 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -810,6 +810,7 @@ extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
810extern int edac_mc_add_mc(struct mem_ctl_info *mci); 810extern int edac_mc_add_mc(struct mem_ctl_info *mci);
811extern void edac_mc_free(struct mem_ctl_info *mci); 811extern void edac_mc_free(struct mem_ctl_info *mci);
812extern struct mem_ctl_info *edac_mc_find(int idx); 812extern struct mem_ctl_info *edac_mc_find(int idx);
813extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
813extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); 814extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
814extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, 815extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
815 unsigned long page); 816 unsigned long page);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 6b21e25f7a84..6b7e723e46be 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -239,13 +239,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
239EXPORT_SYMBOL_GPL(edac_mc_free); 239EXPORT_SYMBOL_GPL(edac_mc_free);
240 240
241 241
242/* 242/**
243 * find_mci_by_dev 243 * find_mci_by_dev
244 * 244 *
245 * scan list of controllers looking for the one that manages 245 * scan list of controllers looking for the one that manages
246 * the 'dev' device 246 * the 'dev' device
247 * @dev: pointer to a struct device related with the MCI
247 */ 248 */
248static struct mem_ctl_info *find_mci_by_dev(struct device *dev) 249struct mem_ctl_info *find_mci_by_dev(struct device *dev)
249{ 250{
250 struct mem_ctl_info *mci; 251 struct mem_ctl_info *mci;
251 struct list_head *item; 252 struct list_head *item;
@@ -261,6 +262,7 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
261 262
262 return NULL; 263 return NULL;
263} 264}
265EXPORT_SYMBOL_GPL(find_mci_by_dev);
264 266
265/* 267/*
266 * handler for EDAC to check if NMI type handler has asserted interrupt 268 * handler for EDAC to check if NMI type handler has asserted interrupt
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 0fd5b85a0f75..414182719640 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -261,6 +261,9 @@ struct i7core_pvt {
261 261
262 /* Count indicator to show errors not got */ 262 /* Count indicator to show errors not got */
263 unsigned mce_overrun; 263 unsigned mce_overrun;
264
265 /* Struct to control EDAC polling */
266 struct edac_pci_ctl_info *i7core_pci;
264}; 267};
265 268
266/* Static vars */ 269/* Static vars */
@@ -378,8 +381,6 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
378 {0,} /* 0 terminated list. */ 381 {0,} /* 0 terminated list. */
379}; 382};
380 383
381static struct edac_pci_ctl_info *i7core_pci;
382
383/**************************************************************************** 384/****************************************************************************
384 Anciliary status routines 385 Anciliary status routines
385 ****************************************************************************/ 386 ****************************************************************************/
@@ -1906,9 +1907,9 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
1906 } 1907 }
1907 1908
1908 /* allocating generic PCI control info */ 1909 /* allocating generic PCI control info */
1909 i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev, 1910 pvt->i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev,
1910 EDAC_MOD_STR); 1911 EDAC_MOD_STR);
1911 if (unlikely(!i7core_pci)) { 1912 if (unlikely(!pvt->i7core_pci)) {
1912 printk(KERN_WARNING 1913 printk(KERN_WARNING
1913 "%s(): Unable to create PCI control\n", 1914 "%s(): Unable to create PCI control\n",
1914 __func__); 1915 __func__);
@@ -2008,12 +2009,10 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
2008{ 2009{
2009 struct mem_ctl_info *mci; 2010 struct mem_ctl_info *mci;
2010 struct i7core_dev *i7core_dev, *tmp; 2011 struct i7core_dev *i7core_dev, *tmp;
2012 struct i7core_pvt *pvt;
2011 2013
2012 debugf0(__FILE__ ": %s()\n", __func__); 2014 debugf0(__FILE__ ": %s()\n", __func__);
2013 2015
2014 if (i7core_pci)
2015 edac_pci_release_generic_ctl(i7core_pci);
2016
2017 /* 2016 /*
2018 * we have a trouble here: pdev value for removal will be wrong, since 2017 * we have a trouble here: pdev value for removal will be wrong, since
2019 * it will point to the X58 register used to detect that the machine 2018 * it will point to the X58 register used to detect that the machine
@@ -2024,19 +2023,28 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
2024 2023
2025 mutex_lock(&i7core_edac_lock); 2024 mutex_lock(&i7core_edac_lock);
2026 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) { 2025 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
2027 mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev); 2026 mci = find_mci_by_dev(&i7core_dev->pdev[0]->dev);
2028 if (mci) { 2027 if (unlikely(!mci || !mci->pvt_info)) {
2029 struct i7core_pvt *pvt = mci->pvt_info; 2028 i7core_printk(KERN_ERR,
2030 2029 "Couldn't find mci hanler\n");
2030 } else {
2031 pvt = mci->pvt_info;
2031 i7core_dev = pvt->i7core_dev; 2032 i7core_dev = pvt->i7core_dev;
2033
2034 if (likely(pvt->i7core_pci))
2035 edac_pci_release_generic_ctl(pvt->i7core_pci);
2036 else
2037 i7core_printk(KERN_ERR,
2038 "Couldn't find mem_ctl_info for socket %d\n",
2039 i7core_dev->socket);
2040 pvt->i7core_pci = NULL;
2041
2042 edac_mc_del_mc(&i7core_dev->pdev[0]->dev);
2043
2032 edac_mce_unregister(&pvt->edac_mce); 2044 edac_mce_unregister(&pvt->edac_mce);
2033 kfree(mci->ctl_name); 2045 kfree(mci->ctl_name);
2034 edac_mc_free(mci); 2046 edac_mc_free(mci);
2035 i7core_put_devices(i7core_dev); 2047 i7core_put_devices(i7core_dev);
2036 } else {
2037 i7core_printk(KERN_ERR,
2038 "Couldn't find mci for socket %d\n",
2039 i7core_dev->socket);
2040 } 2048 }
2041 } 2049 }
2042 probed--; 2050 probed--;