amd64_edac: Fix DCT argument type
[pandora-kernel.git] / drivers / edac / amd64_edac.c
index 1cd82f9..cc4f887 100644 (file)
@@ -24,51 +24,6 @@ static atomic_t drv_instances = ATOMIC_INIT(0);
 static struct mem_ctl_info **mcis;
 static struct ecc_settings **ecc_stngs;
 
-/*
- * Address to DRAM bank mapping: see F2x80 for K8 and F2x[1,0]80 for Fam10 and
- * later.
- */
-static int ddr2_dbam_revCG[] = {
-                          [0]          = 32,
-                          [1]          = 64,
-                          [2]          = 128,
-                          [3]          = 256,
-                          [4]          = 512,
-                          [5]          = 1024,
-                          [6]          = 2048,
-};
-
-static int ddr2_dbam_revD[] = {
-                          [0]          = 32,
-                          [1]          = 64,
-                          [2 ... 3]    = 128,
-                          [4]          = 256,
-                          [5]          = 512,
-                          [6]          = 256,
-                          [7]          = 512,
-                          [8 ... 9]    = 1024,
-                          [10]         = 2048,
-};
-
-static int ddr2_dbam[] = { [0]         = 128,
-                          [1]          = 256,
-                          [2 ... 4]    = 512,
-                          [5 ... 6]    = 1024,
-                          [7 ... 8]    = 2048,
-                          [9 ... 10]   = 4096,
-                          [11]         = 8192,
-};
-
-static int ddr3_dbam[] = { [0]         = -1,
-                          [1]          = 256,
-                          [2]          = 512,
-                          [3 ... 4]    = -1,
-                          [5 ... 6]    = 1024,
-                          [7 ... 8]    = 2048,
-                          [9 ... 10]   = 4096,
-                          [11]         = 8192,
-};
-
 /*
  * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing
  * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
@@ -76,8 +31,6 @@ static int ddr3_dbam[] = { [0]                = -1,
  *
  *FIXME: Produce a better mapping/linearisation.
  */
-
-
 struct scrubrate {
        u32 scrubval;           /* bit pattern for scrub rate */
        u32 bandwidth;          /* bandwidth consumed (bytes/sec) */
@@ -240,8 +193,12 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate)
 static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw)
 {
        struct amd64_pvt *pvt = mci->pvt_info;
+       u32 min_scrubrate = 0x5;
 
-       return __amd64_set_scrub_rate(pvt->F3, bw, pvt->min_scrubrate);
+       if (boot_cpu_data.x86 == 0xf)
+               min_scrubrate = 0x0;
+
+       return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate);
 }
 
 static int amd64_get_scrub_rate(struct mem_ctl_info *mci)
@@ -269,7 +226,8 @@ 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, int nid)
+static bool amd64_base_limit_match(struct amd64_pvt *pvt, u64 sys_addr,
+                                  unsigned nid)
 {
        u64 addr;
 
@@ -295,7 +253,7 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
                                                u64 sys_addr)
 {
        struct amd64_pvt *pvt;
-       int node_id;
+       unsigned node_id;
        u32 intlv_en, bits;
 
        /*
@@ -345,7 +303,7 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
        }
 
 found:
-       return edac_mc_find(node_id);
+       return edac_mc_find((int)node_id);
 
 err_no_match:
        debugf2("sys_addr 0x%lx doesn't match any node\n",
@@ -645,7 +603,7 @@ static u64 sys_addr_to_input_addr(struct mem_ctl_info *mci, u64 sys_addr)
 static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr)
 {
        struct amd64_pvt *pvt;
-       int node_id, intlv_shift;
+       unsigned node_id, intlv_shift;
        u64 bits, dram_addr;
        u32 intlv_sel;
 
@@ -659,10 +617,10 @@ static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr)
         */
        pvt = mci->pvt_info;
        node_id = pvt->mc_node_id;
-       BUG_ON((node_id < 0) || (node_id > 7));
 
-       intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0));
+       BUG_ON(node_id > 7);
 
+       intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0));
        if (intlv_shift == 0) {
                debugf1("    InputAddr 0x%lx translates to DramAddr of "
                        "same value\n", (unsigned long)input_addr);
@@ -810,8 +768,7 @@ static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt)
        return edac_cap;
 }
 
-
-static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt);
+static void amd64_debug_display_dimm_sizes(struct amd64_pvt *, u8);
 
 static void amd64_dump_dramcfg_low(u32 dclr, int chan)
 {
@@ -859,15 +816,15 @@ static void dump_misc_regs(struct amd64_pvt *pvt)
 
        debugf1("  DramHoleValid: %s\n", dhar_valid(pvt) ? "yes" : "no");
 
-       amd64_debug_display_dimm_sizes(0, pvt);
+       amd64_debug_display_dimm_sizes(pvt, 0);
 
        /* everything below this point is Fam10h and above */
        if (boot_cpu_data.x86 == 0xf)
                return;
 
-       amd64_debug_display_dimm_sizes(1, pvt);
+       amd64_debug_display_dimm_sizes(pvt, 1);
 
-       amd64_info("using %s syndromes.\n", ((pvt->syn_type == 8) ? "x8" : "x4"));
+       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))
@@ -898,8 +855,8 @@ static void read_dct_base_mask(struct amd64_pvt *pvt)
        prep_chip_selects(pvt);
 
        for_each_chip_select(cs, 0, pvt) {
-               u32 reg0   = DCSB0 + (cs * 4);
-               u32 reg1   = DCSB1 + (cs * 4);
+               int reg0   = DCSB0 + (cs * 4);
+               int reg1   = DCSB1 + (cs * 4);
                u32 *base0 = &pvt->csels[0].csbases[cs];
                u32 *base1 = &pvt->csels[1].csbases[cs];
 
@@ -916,8 +873,8 @@ static void read_dct_base_mask(struct amd64_pvt *pvt)
        }
 
        for_each_chip_select_mask(cs, 0, pvt) {
-               u32 reg0   = DCSM0 + (cs * 4);
-               u32 reg1   = DCSM1 + (cs * 4);
+               int reg0   = DCSM0 + (cs * 4);
+               int reg1   = DCSM1 + (cs * 4);
                u32 *mask0 = &pvt->csels[0].csmasks[cs];
                u32 *mask1 = &pvt->csels[1].csmasks[cs];
 
@@ -962,7 +919,7 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
 
        if (pvt->ext_model >= K8_REV_F)
                /* RevF (NPT) and later */
-               flag = pvt->dclr0 & F10_WIDTH_128;
+               flag = pvt->dclr0 & WIDTH_128;
        else
                /* RevE and earlier */
                flag = pvt->dclr0 & REVE_WIDTH_128;
@@ -989,7 +946,7 @@ static u64 get_error_address(struct mce *m)
 
 static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
 {
-       u32 off = range << 3;
+       int off = range << 3;
 
        amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off,  &pvt->ranges[range].base.lo);
        amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo);
@@ -1062,18 +1019,41 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
        }
 }
 
-static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
+static int ddr2_cs_size(unsigned i, bool dct_width)
 {
-       int *dbam_map;
+       unsigned shift = 0;
 
-       if (pvt->ext_model >= K8_REV_F)
-               dbam_map = ddr2_dbam;
-       else if (pvt->ext_model >= K8_REV_D)
-               dbam_map = ddr2_dbam_revD;
+       if (i <= 2)
+               shift = i;
+       else if (!(i & 0x1))
+               shift = i >> 1;
        else
-               dbam_map = ddr2_dbam_revCG;
+               shift = (i + 1) >> 1;
 
-       return dbam_map[cs_mode];
+       return 128 << (shift + !!dct_width);
+}
+
+static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
+                                 unsigned cs_mode)
+{
+       u32 dclr = dct ? pvt->dclr1 : pvt->dclr0;
+
+       if (pvt->ext_model >= K8_REV_F) {
+               WARN_ON(cs_mode > 11);
+               return ddr2_cs_size(cs_mode, dclr & WIDTH_128);
+       }
+       else if (pvt->ext_model >= K8_REV_D) {
+               WARN_ON(cs_mode > 10);
+
+               if (cs_mode == 3 || cs_mode == 8)
+                       return 32 << (cs_mode - 1);
+               else
+                       return 32 << cs_mode;
+       }
+       else {
+               WARN_ON(cs_mode > 6);
+               return 32 << cs_mode;
+       }
 }
 
 /*
@@ -1089,7 +1069,7 @@ static int f1x_early_channel_count(struct amd64_pvt *pvt)
        int i, j, channels = 0;
 
        /* On F10h, if we are in 128 bit mode, then we are using 2 channels */
-       if (boot_cpu_data.x86 == 0x10 && (pvt->dclr0 & F10_WIDTH_128))
+       if (boot_cpu_data.x86 == 0x10 && (pvt->dclr0 & WIDTH_128))
                return 2;
 
        /*
@@ -1126,28 +1106,64 @@ static int f1x_early_channel_count(struct amd64_pvt *pvt)
        return channels;
 }
 
-static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
+static int ddr3_cs_size(unsigned i, bool dct_width)
 {
-       int *dbam_map;
+       unsigned shift = 0;
+       int cs_size = 0;
+
+       if (i == 0 || i == 3 || i == 4)
+               cs_size = -1;
+       else if (i <= 2)
+               shift = i;
+       else if (i == 12)
+               shift = 7;
+       else if (!(i & 0x1))
+               shift = i >> 1;
+       else
+               shift = (i + 1) >> 1;
+
+       if (cs_size != -1)
+               cs_size = (128 * (1 << !!dct_width)) << shift;
+
+       return cs_size;
+}
+
+static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
+                                  unsigned cs_mode)
+{
+       u32 dclr = dct ? pvt->dclr1 : pvt->dclr0;
+
+       WARN_ON(cs_mode > 11);
 
        if (pvt->dchr0 & DDR3_MODE || pvt->dchr1 & DDR3_MODE)
-               dbam_map = ddr3_dbam;
+               return ddr3_cs_size(cs_mode, dclr & WIDTH_128);
        else
-               dbam_map = ddr2_dbam;
+               return ddr2_cs_size(cs_mode, dclr & WIDTH_128);
+}
 
-       return dbam_map[cs_mode];
+/*
+ * F15h supports only 64bit DCT interfaces
+ */
+static int f15_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
+                                  unsigned cs_mode)
+{
+       WARN_ON(cs_mode > 12);
+
+       return ddr3_cs_size(cs_mode, false);
 }
 
-static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
+static void read_dram_ctl_register(struct amd64_pvt *pvt)
 {
 
+       if (boot_cpu_data.x86 == 0xf)
+               return;
+
        if (!amd64_read_dct_pci_cfg(pvt, DCT_SEL_LO, &pvt->dct_sel_lo)) {
                debugf0("F2x110 (DCTSelLow): 0x%08x, High range addrs at: 0x%x\n",
                        pvt->dct_sel_lo, dct_sel_baseaddr(pvt));
 
-               debugf0("  mode: %s, All DCTs on: %s\n",
-                       (dct_ganging_enabled(pvt) ? "ganged" : "unganged"),
-                       (dct_dram_enabled(pvt) ? "yes"   : "no"));
+               debugf0("  DCTs operate in %s mode.\n",
+                       (dct_ganging_enabled(pvt) ? "ganged" : "unganged"));
 
                if (!dct_ganging_enabled(pvt))
                        debugf0("  Address range split per DCT: %s\n",
@@ -1174,7 +1190,7 @@ static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
 static u8 f1x_determine_channel(struct amd64_pvt *pvt, u64 sys_addr,
                                bool hi_range_sel, u8 intlv_en)
 {
-       u32 dct_sel_high = (pvt->dct_sel_lo >> 1) & 1;
+       u8 dct_sel_high = (pvt->dct_sel_lo >> 1) & 1;
 
        if (dct_ganging_enabled(pvt))
                return 0;
@@ -1209,14 +1225,13 @@ static u8 f1x_determine_channel(struct amd64_pvt *pvt, u64 sys_addr,
 }
 
 /* Convert the sys_addr to the normalized DCT address */
-static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, int range,
+static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, unsigned range,
                                 u64 sys_addr, bool hi_rng,
                                 u32 dct_sel_base_addr)
 {
        u64 chan_off;
        u64 dram_base           = get_dram_base(pvt, range);
        u64 hole_off            = f10_dhar_offset(pvt);
-       u32 hole_valid          = dhar_valid(pvt);
        u64 dct_sel_base_off    = (pvt->dct_sel_hi & 0xFFFFFC00) << 16;
 
        if (hi_rng) {
@@ -1233,7 +1248,7 @@ static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, int range,
                 */
                if ((!(dct_sel_base_addr >> 16) ||
                     dct_sel_base_addr < dhar_base(pvt)) &&
-                   hole_valid &&
+                   dhar_valid(pvt) &&
                    (sys_addr >= BIT_64(32)))
                        chan_off = hole_off;
                else
@@ -1248,7 +1263,7 @@ static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, int range,
                 * else
                 *      remove dram base to normalize to DCT address
                 */
-               if (hole_valid && (sys_addr >= BIT_64(32)))
+               if (dhar_valid(pvt) && (sys_addr >= BIT_64(32)))
                        chan_off = hole_off;
                else
                        chan_off = dram_base;
@@ -1364,7 +1379,7 @@ static u64 f1x_swap_interleaved_region(struct amd64_pvt *pvt, u64 sys_addr)
 }
 
 /* For a given @dram_range, check if @sys_addr falls within it. */
-static int f1x_match_to_this_node(struct amd64_pvt *pvt, int range,
+static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
                                  u64 sys_addr, int *nid, int *chan_sel)
 {
        int cs_found = -EINVAL;
@@ -1452,7 +1467,8 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, int range,
 static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
                                       int *node, int *chan_sel)
 {
-       int range, cs_found = -EINVAL;
+       int cs_found = -EINVAL;
+       unsigned range;
 
        for (range = 0; range < DRAM_RANGES; range++) {
 
@@ -1519,14 +1535,14 @@ 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(int ctrl, struct amd64_pvt *pvt)
+static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
 {
        int dimm, size0, size1, factor = 0;
        u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases;
        u32 dbam  = ctrl ? pvt->dbam1 : pvt->dbam0;
 
        if (boot_cpu_data.x86 == 0xf) {
-               if (pvt->dclr0 & F10_WIDTH_128)
+               if (pvt->dclr0 & WIDTH_128)
                        factor = 1;
 
                /* K8 families < revF not supported yet */
@@ -1549,11 +1565,13 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt)
 
                size0 = 0;
                if (dcsb[dimm*2] & DCSB_CS_ENABLE)
-                       size0 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));
+                       size0 = pvt->ops->dbam_to_cs(pvt, ctrl,
+                                                    DBAM_DIMM(dimm, dbam));
 
                size1 = 0;
                if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE)
-                       size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));
+                       size1 = pvt->ops->dbam_to_cs(pvt, ctrl,
+                                                    DBAM_DIMM(dimm, dbam));
 
                amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
                                dimm * 2,     size0 << factor,
@@ -1579,7 +1597,6 @@ static struct amd64_family_type amd64_family_types[] = {
                .f3_id = PCI_DEVICE_ID_AMD_10H_NB_MISC,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
-                       .read_dram_ctl_register = f10_read_dram_ctl_register,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
                        .dbam_to_cs             = f10_dbam_to_chip_select,
                        .read_dct_pci_cfg       = f10_read_dct_pci_cfg,
@@ -1587,9 +1604,12 @@ static struct amd64_family_type amd64_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,
                .ops = {
                        .early_channel_count    = f1x_early_channel_count,
                        .map_sysaddr_to_csrow   = f1x_map_sysaddr_to_csrow,
+                       .dbam_to_cs             = f15_dbam_to_chip_select,
                        .read_dct_pci_cfg       = f15_read_dct_pci_cfg,
                }
        },
@@ -1760,20 +1780,20 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
        struct amd64_pvt *pvt = mci->pvt_info;
        int err_sym = -1;
 
-       if (pvt->syn_type == 8)
+       if (pvt->ecc_sym_sz == 8)
                err_sym = decode_syndrome(syndrome, x8_vectors,
                                          ARRAY_SIZE(x8_vectors),
-                                         pvt->syn_type);
-       else if (pvt->syn_type == 4)
+                                         pvt->ecc_sym_sz);
+       else if (pvt->ecc_sym_sz == 4)
                err_sym = decode_syndrome(syndrome, x4_vectors,
                                          ARRAY_SIZE(x4_vectors),
-                                         pvt->syn_type);
+                                         pvt->ecc_sym_sz);
        else {
-               amd64_warn("Illegal syndrome type: %u\n", pvt->syn_type);
+               amd64_warn("Illegal syndrome type: %u\n", pvt->ecc_sym_sz);
                return err_sym;
        }
 
-       return map_err_sym_to_channel(err_sym, pvt->syn_type);
+       return map_err_sym_to_channel(err_sym, pvt->ecc_sym_sz);
 }
 
 /*
@@ -1918,9 +1938,10 @@ static void free_mc_sibling_devs(struct amd64_pvt *pvt)
  */
 static void read_mc_regs(struct amd64_pvt *pvt)
 {
+       struct cpuinfo_x86 *c = &boot_cpu_data;
        u64 msr_val;
        u32 tmp;
-       int range;
+       unsigned range;
 
        /*
         * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since
@@ -1939,8 +1960,7 @@ static void read_mc_regs(struct amd64_pvt *pvt)
 
        amd64_read_pci_cfg(pvt->F3, NBCAP, &pvt->nbcap);
 
-       if (pvt->ops->read_dram_ctl_register)
-               pvt->ops->read_dram_ctl_register(pvt);
+       read_dram_ctl_register(pvt);
 
        for (range = 0; range < DRAM_RANGES; range++) {
                u8 rw;
@@ -1980,19 +2000,16 @@ static void read_mc_regs(struct amd64_pvt *pvt)
                amd64_read_dct_pci_cfg(pvt, DCHR1, &pvt->dchr1);
        }
 
-       if (boot_cpu_data.x86 >= 0x10) {
+       pvt->ecc_sym_sz = 4;
+
+       if (c->x86 >= 0x10) {
                amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp);
                amd64_read_dct_pci_cfg(pvt, DBAM1, &pvt->dbam1);
-       }
-
-       if (boot_cpu_data.x86 == 0x10 &&
-           boot_cpu_data.x86_model > 7 &&
-           /* F3x180[EccSymbolSize]=1 => x8 symbols */
-           tmp & BIT(25))
-               pvt->syn_type = 8;
-       else
-               pvt->syn_type = 4;
 
+               /* F10h, revD and later can do x8 ECC too */
+               if ((c->x86 > 0x10 || c->x86_model > 7) && tmp & BIT(25))
+                       pvt->ecc_sym_sz = 8;
+       }
        dump_misc_regs(pvt);
 }
 
@@ -2030,7 +2047,7 @@ static void read_mc_regs(struct amd64_pvt *pvt)
  *     encompasses
  *
  */
-static u32 amd64_csrow_nr_pages(int csrow_nr, struct amd64_pvt *pvt)
+static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
 {
        u32 cs_mode, nr_pages;
 
@@ -2043,7 +2060,7 @@ static u32 amd64_csrow_nr_pages(int csrow_nr, struct amd64_pvt *pvt)
         */
        cs_mode = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;
 
-       nr_pages = pvt->ops->dbam_to_cs(pvt, cs_mode) << (20 - PAGE_SHIFT);
+       nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode) << (20 - PAGE_SHIFT);
 
        /*
         * If dual channel then double the memory size of single channel.
@@ -2091,7 +2108,7 @@ static int init_csrows(struct mem_ctl_info *mci)
                        i, pvt->mc_node_id);
 
                empty = 0;
-               csrow->nr_pages = amd64_csrow_nr_pages(i, pvt);
+               csrow->nr_pages = amd64_csrow_nr_pages(pvt, 0, i);
                find_csrow_limits(mci, i, &input_addr_min, &input_addr_max);
                sys_addr = input_addr_to_sys_addr(mci, input_addr_min);
                csrow->first_page = (u32) (sys_addr >> PAGE_SHIFT);
@@ -2130,7 +2147,7 @@ static int init_csrows(struct mem_ctl_info *mci)
 }
 
 /* get all cores on this DCT */
-static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
+static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, unsigned nid)
 {
        int cpu;
 
@@ -2140,7 +2157,7 @@ static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
 }
 
 /* check MCG_CTL on all the cpus on this node */
-static bool amd64_nb_mce_bank_enabled_on_node(int nid)
+static bool amd64_nb_mce_bank_enabled_on_node(unsigned nid)
 {
        cpumask_var_t mask;
        int cpu, nbe;
@@ -2348,7 +2365,8 @@ static void set_mc_sysfs_attrs(struct mem_ctl_info *mci)
        mci->mc_driver_sysfs_attributes = sysfs_attrs;
 }
 
-static void setup_mci_misc_attrs(struct mem_ctl_info *mci)
+static void setup_mci_misc_attrs(struct mem_ctl_info *mci,
+                                struct amd64_family_type *fam)
 {
        struct amd64_pvt *pvt = mci->pvt_info;
 
@@ -2364,7 +2382,7 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci)
        mci->edac_cap           = amd64_determine_edac_cap(pvt);
        mci->mod_name           = EDAC_MOD_STR;
        mci->mod_ver            = EDAC_AMD64_VERSION;
-       mci->ctl_name           = pvt->ctl_name;
+       mci->ctl_name           = fam->ctl_name;
        mci->dev_name           = pci_name(pvt->F2);
        mci->ctl_page_to_phys   = NULL;
 
@@ -2385,14 +2403,16 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt)
        case 0xf:
                fam_type                = &amd64_family_types[K8_CPUS];
                pvt->ops                = &amd64_family_types[K8_CPUS].ops;
-               pvt->ctl_name           = fam_type->ctl_name;
-               pvt->min_scrubrate      = K8_MIN_SCRUB_RATE_BITS;
                break;
+
        case 0x10:
                fam_type                = &amd64_family_types[F10_CPUS];
                pvt->ops                = &amd64_family_types[F10_CPUS].ops;
-               pvt->ctl_name           = fam_type->ctl_name;
-               pvt->min_scrubrate      = F10_MIN_SCRUB_RATE_BITS;
+               break;
+
+       case 0x15:
+               fam_type                = &amd64_family_types[F15_CPUS];
+               pvt->ops                = &amd64_family_types[F15_CPUS].ops;
                break;
 
        default:
@@ -2402,7 +2422,7 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt)
 
        pvt->ext_model = boot_cpu_data.x86_model >> 4;
 
-       amd64_info("%s %sdetected (node %d).\n", pvt->ctl_name,
+       amd64_info("%s %sdetected (node %d).\n", fam_type->ctl_name,
                     (fam == 0xf ?
                                (pvt->ext_model >= K8_REV_F  ? "revF or later "
                                                             : "revE or earlier ")
@@ -2456,7 +2476,7 @@ static int amd64_init_one_instance(struct pci_dev *F2)
        mci->pvt_info = pvt;
        mci->dev = &pvt->F2->dev;
 
-       setup_mci_misc_attrs(mci);
+       setup_mci_misc_attrs(mci, fam_type);
 
        if (init_csrows(mci))
                mci->edac_cap = EDAC_FLAG_NONE;
@@ -2599,6 +2619,15 @@ static const struct pci_device_id amd64_pci_table[] __devinitdata = {
                .class          = 0,
                .class_mask     = 0,
        },
+       {
+               .vendor         = PCI_VENDOR_ID_AMD,
+               .device         = PCI_DEVICE_ID_AMD_15H_NB_F2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .class          = 0,
+               .class_mask     = 0,
+       },
+
        {0, }
 };
 MODULE_DEVICE_TABLE(pci, amd64_pci_table);
@@ -2639,7 +2668,7 @@ static int __init amd64_edac_init(void)
 {
        int err = -ENODEV;
 
-       edac_printk(KERN_INFO, EDAC_MOD_STR, EDAC_AMD64_VERSION "\n");
+       printk(KERN_INFO "AMD64 EDAC driver v%s\n", EDAC_AMD64_VERSION);
 
        opstate_init();