EDAC, amd64_edac: Drop pci_register_driver() use
authorBorislav Petkov <bp@suse.de>
Fri, 6 May 2016 17:44:27 +0000 (19:44 +0200)
committerBorislav Petkov <bp@suse.de>
Mon, 9 May 2016 18:41:16 +0000 (20:41 +0200)
- remove homegrown instances counting.
- take F3 PCI device from amd_nb caching instead of F2 which was used with the
PCI core.

With those changes, the driver doesn't need to register a PCI driver and
relies on the northbridges caching which we do anyway on AMD.

Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Yazen Ghannam <yazen.ghannam@amd.com>
drivers/edac/amd64_edac.c
drivers/edac/amd64_edac.h

index 651d96c..624e2f7 100644 (file)
@@ -15,11 +15,6 @@ module_param(ecc_enable_override, int, 0644);
 
 static struct msr __percpu *msrs;
 
-/*
- * count successfully initialized driver instances for setup_pci_device()
- */
-static atomic_t drv_instances = ATOMIC_INIT(0);
-
 /* Per-node stuff */
 static struct ecc_settings **ecc_stngs;
 
@@ -1918,7 +1913,7 @@ static struct amd64_family_type family_types[] = {
        [K8_CPUS] = {
                .ctl_name = "K8",
                .f1_id = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP,
-               .f3_id = PCI_DEVICE_ID_AMD_K8_NB_MISC,
+               .f2_id = PCI_DEVICE_ID_AMD_K8_NB_MEMCTL,
                .ops = {
                        .early_channel_count    = k8_early_channel_count,
                        .map_sysaddr_to_csrow   = k8_map_sysaddr_to_csrow,
@@ -1928,7 +1923,7 @@ static struct amd64_family_type family_types[] = {
        [F10_CPUS] = {
                .ctl_name = "F10h",
                .f1_id = PCI_DEVICE_ID_AMD_10H_NB_MAP,
-               .f3_id = PCI_DEVICE_ID_AMD_10H_NB_MISC,
+               .f2_id = PCI_DEVICE_ID_AMD_10H_NB_DRAM,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
@@ -1938,7 +1933,7 @@ static struct amd64_family_type family_types[] = {
        [F15_CPUS] = {
                .ctl_name = "F15h",
                .f1_id = PCI_DEVICE_ID_AMD_15H_NB_F1,
-               .f3_id = PCI_DEVICE_ID_AMD_15H_NB_F3,
+               .f2_id = PCI_DEVICE_ID_AMD_15H_NB_F2,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
@@ -1948,7 +1943,7 @@ static struct amd64_family_type family_types[] = {
        [F15_M30H_CPUS] = {
                .ctl_name = "F15h_M30h",
                .f1_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F1,
-               .f3_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F3,
+               .f2_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F2,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
@@ -1958,7 +1953,7 @@ static struct amd64_family_type family_types[] = {
        [F15_M60H_CPUS] = {
                .ctl_name = "F15h_M60h",
                .f1_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F1,
-               .f3_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F3,
+               .f2_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F2,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
@@ -1968,7 +1963,7 @@ static struct amd64_family_type family_types[] = {
        [F16_CPUS] = {
                .ctl_name = "F16h",
                .f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1,
-               .f3_id = PCI_DEVICE_ID_AMD_16H_NB_F3,
+               .f2_id = PCI_DEVICE_ID_AMD_16H_NB_F2,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
@@ -1978,7 +1973,7 @@ static struct amd64_family_type family_types[] = {
        [F16_M30H_CPUS] = {
                .ctl_name = "F16h_M30h",
                .f1_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F1,
-               .f3_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F3,
+               .f2_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F2,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
@@ -2227,13 +2222,13 @@ static inline void decode_bus_error(int node_id, struct mce *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.
+ * Use pvt->F3 which contains the F3 CPU PCI device to get the related
+ * F1 (AddrMap) and F2 (Dct) devices. Return negative value on error.
  */
-static int reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 f1_id, u16 f3_id)
+static int reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 f1_id, u16 f2_id)
 {
        /* Reserve the ADDRESS MAP Device */
-       pvt->F1 = pci_get_related_function(pvt->F2->vendor, f1_id, pvt->F2);
+       pvt->F1 = pci_get_related_function(pvt->F3->vendor, f1_id, pvt->F3);
        if (!pvt->F1) {
                amd64_err("error address map device not found: "
                          "vendor %x device 0x%x (broken BIOS?)\n",
@@ -2241,15 +2236,15 @@ static int reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 f1_id, u16 f3_id)
                return -ENODEV;
        }
 
-       /* Reserve the MISC Device */
-       pvt->F3 = pci_get_related_function(pvt->F2->vendor, f3_id, pvt->F2);
-       if (!pvt->F3) {
+       /* Reserve the DCT Device */
+       pvt->F2 = pci_get_related_function(pvt->F3->vendor, f2_id, pvt->F3);
+       if (!pvt->F2) {
                pci_dev_put(pvt->F1);
                pvt->F1 = NULL;
 
-               amd64_err("error F3 device not found: "
+               amd64_err("error F2 device not found: "
                          "vendor %x device 0x%x (broken BIOS?)\n",
-                         PCI_VENDOR_ID_AMD, f3_id);
+                         PCI_VENDOR_ID_AMD, f2_id);
 
                return -ENODEV;
        }
@@ -2263,7 +2258,7 @@ static int reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 f1_id, u16 f3_id)
 static void free_mc_sibling_devs(struct amd64_pvt *pvt)
 {
        pci_dev_put(pvt->F1);
-       pci_dev_put(pvt->F3);
+       pci_dev_put(pvt->F2);
 }
 
 /*
@@ -2778,14 +2773,14 @@ static const struct attribute_group *amd64_edac_attr_groups[] = {
        NULL
 };
 
-static int init_one_instance(struct pci_dev *F2)
+static int init_one_instance(unsigned int nid)
 {
-       struct amd64_pvt *pvt = NULL;
+       struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
        struct amd64_family_type *fam_type = NULL;
        struct mem_ctl_info *mci = NULL;
        struct edac_mc_layer layers[2];
+       struct amd64_pvt *pvt = NULL;
        int err = 0, ret;
-       u16 nid = amd_pci_dev_to_node_id(F2);
 
        ret = -ENOMEM;
        pvt = kzalloc(sizeof(struct amd64_pvt), GFP_KERNEL);
@@ -2793,7 +2788,7 @@ static int init_one_instance(struct pci_dev *F2)
                goto err_ret;
 
        pvt->mc_node_id = nid;
-       pvt->F2 = F2;
+       pvt->F3 = F3;
 
        ret = -EINVAL;
        fam_type = per_family_init(pvt);
@@ -2801,7 +2796,7 @@ static int init_one_instance(struct pci_dev *F2)
                goto err_free;
 
        ret = -ENODEV;
-       err = reserve_mc_sibling_devs(pvt, fam_type->f1_id, fam_type->f3_id);
+       err = reserve_mc_sibling_devs(pvt, fam_type->f1_id, fam_type->f2_id);
        if (err)
                goto err_free;
 
@@ -2836,7 +2831,7 @@ static int init_one_instance(struct pci_dev *F2)
                goto err_siblings;
 
        mci->pvt_info = pvt;
-       mci->pdev = &pvt->F2->dev;
+       mci->pdev = &pvt->F3->dev;
 
        setup_mci_misc_attrs(mci, fam_type);
 
@@ -2855,8 +2850,6 @@ static int init_one_instance(struct pci_dev *F2)
 
        amd_register_ecc_decoder(decode_bus_error);
 
-       atomic_inc(&drv_instances);
-
        return 0;
 
 err_add_mc:
@@ -2872,19 +2865,11 @@ err_ret:
        return ret;
 }
 
-static int probe_one_instance(struct pci_dev *pdev,
-                             const struct pci_device_id *mc_type)
+static int probe_one_instance(unsigned int nid)
 {
-       u16 nid = amd_pci_dev_to_node_id(pdev);
        struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
        struct ecc_settings *s;
-       int ret = 0;
-
-       ret = pci_enable_device(pdev);
-       if (ret < 0) {
-               edac_dbg(0, "ret=%d\n", ret);
-               return -EIO;
-       }
+       int ret;
 
        ret = -ENOMEM;
        s = kzalloc(sizeof(struct ecc_settings), GFP_KERNEL);
@@ -2905,7 +2890,7 @@ static int probe_one_instance(struct pci_dev *pdev,
                        goto err_enable;
        }
 
-       ret = init_one_instance(pdev);
+       ret = init_one_instance(nid);
        if (ret < 0) {
                amd64_err("Error probing instance: %d\n", nid);
                restore_ecc_error_reporting(s, nid, F3);
@@ -2921,19 +2906,18 @@ err_out:
        return ret;
 }
 
-static void remove_one_instance(struct pci_dev *pdev)
+static void remove_one_instance(unsigned int nid)
 {
-       struct mem_ctl_info *mci;
-       struct amd64_pvt *pvt;
-       u16 nid = amd_pci_dev_to_node_id(pdev);
        struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
        struct ecc_settings *s = ecc_stngs[nid];
+       struct mem_ctl_info *mci;
+       struct amd64_pvt *pvt;
 
-       mci = find_mci_by_dev(&pdev->dev);
+       mci = find_mci_by_dev(&F3->dev);
        WARN_ON(!mci);
 
        /* Remove from EDAC CORE tracking list */
-       mci = edac_mc_del_mc(&pdev->dev);
+       mci = edac_mc_del_mc(&F3->dev);
        if (!mci)
                return;
 
@@ -2957,31 +2941,6 @@ static void remove_one_instance(struct pci_dev *pdev)
        edac_mc_free(mci);
 }
 
-/*
- * This table is part of the interface for loading drivers for PCI devices. The
- * 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 const struct pci_device_id amd64_pci_table[] = {
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL) },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_DRAM) },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F2) },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F2) },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F2) },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F2) },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F2) },
-       {0, }
-};
-MODULE_DEVICE_TABLE(pci, amd64_pci_table);
-
-static struct pci_driver amd64_pci_driver = {
-       .name           = EDAC_MOD_STR,
-       .probe          = probe_one_instance,
-       .remove         = remove_one_instance,
-       .id_table       = amd64_pci_table,
-       .driver.probe_type = PROBE_FORCE_SYNCHRONOUS,
-};
-
 static void setup_pci_device(void)
 {
        struct mem_ctl_info *mci;
@@ -3005,6 +2964,7 @@ static void setup_pci_device(void)
 static int __init amd64_edac_init(void)
 {
        int err = -ENODEV;
+       int i;
 
        opstate_init();
 
@@ -3020,13 +2980,14 @@ static int __init amd64_edac_init(void)
        if (!msrs)
                goto err_free;
 
-       err = pci_register_driver(&amd64_pci_driver);
-       if (err)
-               goto err_pci;
+       for (i = 0; i < amd_nb_num(); i++)
+               if (probe_one_instance(i)) {
+                       /* unwind properly */
+                       while (--i >= 0)
+                               remove_one_instance(i);
 
-       err = -ENODEV;
-       if (!atomic_read(&drv_instances))
-               goto err_no_instances;
+                       goto err_pci;
+               }
 
        setup_pci_device();
 
@@ -3038,9 +2999,6 @@ static int __init amd64_edac_init(void)
 
        return 0;
 
-err_no_instances:
-       pci_unregister_driver(&amd64_pci_driver);
-
 err_pci:
        msrs_free(msrs);
        msrs = NULL;
@@ -3055,10 +3013,13 @@ err_ret:
 
 static void __exit amd64_edac_exit(void)
 {
+       int i;
+
        if (pci_ctl)
                edac_pci_release_generic_ctl(pci_ctl);
 
-       pci_unregister_driver(&amd64_pci_driver);
+       for (i = 0; i < amd_nb_num(); i++)
+               remove_one_instance(i);
 
        kfree(ecc_stngs);
        ecc_stngs = NULL;
index c0f248f..c088704 100644 (file)
@@ -422,7 +422,7 @@ struct low_ops {
 
 struct amd64_family_type {
        const char *ctl_name;
-       u16 f1_id, f3_id;
+       u16 f1_id, f2_id;
        struct low_ops ops;
 };