aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7core_edac.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 391348bf93d2..c3fec5de3e51 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1138,11 +1138,18 @@ static void i7core_put_devices(struct i7core_dev *i7core_dev)
1138{ 1138{
1139 int i; 1139 int i;
1140 1140
1141 for (i = 0; i < N_DEVS; i++) 1141 debugf0(__FILE__ ": %s()\n", __func__);
1142 pci_dev_put(i7core_dev->pdev[i]); 1142 for (i = 0; i < N_DEVS; i++) {
1143 1143 struct pci_dev *pdev = i7core_dev->pdev[i];
1144 list_del(&i7core_dev->list); 1144 if (!pdev)
1145 continue;
1146 debugf0("Removing dev %02x:%02x.%d\n",
1147 pdev->bus->number,
1148 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1149 pci_dev_put(pdev);
1150 }
1145 kfree(i7core_dev->pdev); 1151 kfree(i7core_dev->pdev);
1152 list_del(&i7core_dev->list);
1146 kfree(i7core_dev); 1153 kfree(i7core_dev);
1147} 1154}
1148 1155
@@ -1863,31 +1870,39 @@ fail0:
1863static void __devexit i7core_remove(struct pci_dev *pdev) 1870static void __devexit i7core_remove(struct pci_dev *pdev)
1864{ 1871{
1865 struct mem_ctl_info *mci; 1872 struct mem_ctl_info *mci;
1866 struct i7core_pvt *pvt; 1873 struct i7core_dev *i7core_dev, *tmp;
1867 struct i7core_dev *i7core_dev;
1868 1874
1869 debugf0(__FILE__ ": %s()\n", __func__); 1875 debugf0(__FILE__ ": %s()\n", __func__);
1870 1876
1871 if (i7core_pci) 1877 if (i7core_pci)
1872 edac_pci_release_generic_ctl(i7core_pci); 1878 edac_pci_release_generic_ctl(i7core_pci);
1873 1879
1880 /*
1881 * we have a trouble here: pdev value for removal will be wrong, since
1882 * it will point to the X58 register used to detect that the machine
1883 * is a Nehalem or upper design. However, due to the way several PCI
1884 * devices are grouped together to provide MC functionality, we need
1885 * to use a different method for releasing the devices
1886 */
1874 1887
1875 mci = edac_mc_del_mc(&pdev->dev);
1876 if (!mci)
1877 return;
1878
1879 /* Unregisters on edac_mce in order to receive memory errors */
1880 pvt = mci->pvt_info;
1881 i7core_dev = pvt->i7core_dev;
1882 edac_mce_unregister(&pvt->edac_mce);
1883
1884 /* retrieve references to resources, and free those resources */
1885 mutex_lock(&i7core_edac_lock); 1888 mutex_lock(&i7core_edac_lock);
1886 i7core_put_devices(i7core_dev); 1889 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
1890 mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev);
1891 if (mci) {
1892 struct i7core_pvt *pvt = mci->pvt_info;
1893
1894 i7core_dev = pvt->i7core_dev;
1895 edac_mce_unregister(&pvt->edac_mce);
1896 kfree(mci->ctl_name);
1897 edac_mc_free(mci);
1898 i7core_put_devices(i7core_dev);
1899 } else {
1900 i7core_printk(KERN_ERR,
1901 "Couldn't find mci for socket %d\n",
1902 i7core_dev->socket);
1903 }
1904 }
1887 mutex_unlock(&i7core_edac_lock); 1905 mutex_unlock(&i7core_edac_lock);
1888
1889 kfree(mci->ctl_name);
1890 edac_mc_free(mci);
1891} 1906}
1892 1907
1893MODULE_DEVICE_TABLE(pci, i7core_pci_tbl); 1908MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);