diff options
-rw-r--r-- | drivers/edac/i7core_edac.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 7ee5034100b9..7164707ed99e 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1471,10 +1471,6 @@ static int mci_bind_devs(struct mem_ctl_info *mci, | |||
1471 | struct pci_dev *pdev; | 1471 | struct pci_dev *pdev; |
1472 | int i, func, slot; | 1472 | int i, func, slot; |
1473 | 1473 | ||
1474 | /* Associates i7core_dev and mci for future usage */ | ||
1475 | pvt->i7core_dev = i7core_dev; | ||
1476 | i7core_dev->mci = mci; | ||
1477 | |||
1478 | pvt->is_registered = 0; | 1474 | pvt->is_registered = 0; |
1479 | for (i = 0; i < i7core_dev->n_devs; i++) { | 1475 | for (i = 0; i < i7core_dev->n_devs; i++) { |
1480 | pdev = i7core_dev->pdev[i]; | 1476 | pdev = i7core_dev->pdev[i]; |
@@ -1918,6 +1914,39 @@ static void i7core_pci_ctl_release(struct i7core_pvt *pvt) | |||
1918 | pvt->i7core_pci = NULL; | 1914 | pvt->i7core_pci = NULL; |
1919 | } | 1915 | } |
1920 | 1916 | ||
1917 | static void i7core_unregister_mci(struct i7core_dev *i7core_dev) | ||
1918 | { | ||
1919 | struct mem_ctl_info *mci = i7core_dev->mci; | ||
1920 | struct i7core_pvt *pvt; | ||
1921 | |||
1922 | if (unlikely(!mci || !mci->pvt_info)) { | ||
1923 | debugf0("MC: " __FILE__ ": %s(): dev = %p\n", | ||
1924 | __func__, &i7core_dev->pdev[0]->dev); | ||
1925 | |||
1926 | i7core_printk(KERN_ERR, "Couldn't find mci handler\n"); | ||
1927 | return; | ||
1928 | } | ||
1929 | |||
1930 | pvt = mci->pvt_info; | ||
1931 | |||
1932 | debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", | ||
1933 | __func__, mci, &i7core_dev->pdev[0]->dev); | ||
1934 | |||
1935 | /* Disable MCE NMI handler */ | ||
1936 | edac_mce_unregister(&pvt->edac_mce); | ||
1937 | |||
1938 | /* Disable EDAC polling */ | ||
1939 | i7core_pci_ctl_release(pvt); | ||
1940 | |||
1941 | /* Remove MC sysfs nodes */ | ||
1942 | edac_mc_del_mc(mci->dev); | ||
1943 | |||
1944 | debugf1("%s: free mci struct\n", mci->ctl_name); | ||
1945 | kfree(mci->ctl_name); | ||
1946 | edac_mc_free(mci); | ||
1947 | i7core_dev->mci = NULL; | ||
1948 | } | ||
1949 | |||
1921 | static int i7core_register_mci(struct i7core_dev *i7core_dev, | 1950 | static int i7core_register_mci(struct i7core_dev *i7core_dev, |
1922 | const int num_channels, const int num_csrows) | 1951 | const int num_channels, const int num_csrows) |
1923 | { | 1952 | { |
@@ -2003,6 +2032,10 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, | |||
2003 | goto fail1; | 2032 | goto fail1; |
2004 | } | 2033 | } |
2005 | 2034 | ||
2035 | /* Associates i7core_dev and mci for future usage */ | ||
2036 | pvt->i7core_dev = i7core_dev; | ||
2037 | i7core_dev->mci = mci; | ||
2038 | |||
2006 | return 0; | 2039 | return 0; |
2007 | 2040 | ||
2008 | fail1: | 2041 | fail1: |
@@ -2011,6 +2044,7 @@ fail1: | |||
2011 | fail0: | 2044 | fail0: |
2012 | kfree(mci->ctl_name); | 2045 | kfree(mci->ctl_name); |
2013 | edac_mc_free(mci); | 2046 | edac_mc_free(mci); |
2047 | i7core_dev->mci = NULL; | ||
2014 | return rc; | 2048 | return rc; |
2015 | } | 2049 | } |
2016 | 2050 | ||
@@ -2065,6 +2099,10 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
2065 | return 0; | 2099 | return 0; |
2066 | 2100 | ||
2067 | fail1: | 2101 | fail1: |
2102 | list_for_each_entry(i7core_dev, &i7core_edac_list, list) { | ||
2103 | if (i7core_dev->mci) | ||
2104 | i7core_unregister_mci(i7core_dev); | ||
2105 | } | ||
2068 | i7core_put_all_devices(); | 2106 | i7core_put_all_devices(); |
2069 | fail0: | 2107 | fail0: |
2070 | mutex_unlock(&i7core_edac_lock); | 2108 | mutex_unlock(&i7core_edac_lock); |
@@ -2077,9 +2115,7 @@ fail0: | |||
2077 | */ | 2115 | */ |
2078 | static void __devexit i7core_remove(struct pci_dev *pdev) | 2116 | static void __devexit i7core_remove(struct pci_dev *pdev) |
2079 | { | 2117 | { |
2080 | struct mem_ctl_info *mci; | ||
2081 | struct i7core_dev *i7core_dev; | 2118 | struct i7core_dev *i7core_dev; |
2082 | struct i7core_pvt *pvt; | ||
2083 | 2119 | ||
2084 | debugf0(__FILE__ ": %s()\n", __func__); | 2120 | debugf0(__FILE__ ": %s()\n", __func__); |
2085 | 2121 | ||
@@ -2099,32 +2135,8 @@ static void __devexit i7core_remove(struct pci_dev *pdev) | |||
2099 | } | 2135 | } |
2100 | 2136 | ||
2101 | list_for_each_entry(i7core_dev, &i7core_edac_list, list) { | 2137 | list_for_each_entry(i7core_dev, &i7core_edac_list, list) { |
2102 | mci = i7core_dev->mci; | 2138 | if (i7core_dev->mci) |
2103 | if (unlikely(!mci || !mci->pvt_info)) { | 2139 | i7core_unregister_mci(i7core_dev); |
2104 | debugf0("MC: " __FILE__ ": %s(): dev = %p\n", | ||
2105 | __func__, &i7core_dev->pdev[0]->dev); | ||
2106 | |||
2107 | i7core_printk(KERN_ERR, | ||
2108 | "Couldn't find mci hanler\n"); | ||
2109 | } else { | ||
2110 | pvt = mci->pvt_info; | ||
2111 | |||
2112 | debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", | ||
2113 | __func__, mci, &i7core_dev->pdev[0]->dev); | ||
2114 | |||
2115 | /* Disable MCE NMI handler */ | ||
2116 | edac_mce_unregister(&pvt->edac_mce); | ||
2117 | |||
2118 | /* Disable EDAC polling */ | ||
2119 | i7core_pci_ctl_release(pvt); | ||
2120 | |||
2121 | /* Remove MC sysfs nodes */ | ||
2122 | edac_mc_del_mc(mci->dev); | ||
2123 | |||
2124 | debugf1("%s: free mci struct\n", mci->ctl_name); | ||
2125 | kfree(mci->ctl_name); | ||
2126 | edac_mc_free(mci); | ||
2127 | } | ||
2128 | } | 2140 | } |
2129 | 2141 | ||
2130 | /* Release PCI resources */ | 2142 | /* Release PCI resources */ |