Merge remote-tracking branch 'asoc/fix/fsl' into asoc-next
[cascardo/linux.git] / drivers / edac / i3200_edac.c
index 4e83376..aa44c17 100644 (file)
@@ -106,16 +106,26 @@ static int nr_channels;
 
 static int how_many_channels(struct pci_dev *pdev)
 {
+       int n_channels;
+
        unsigned char capid0_8b; /* 8th byte of CAPID0 */
 
        pci_read_config_byte(pdev, I3200_CAPID0 + 8, &capid0_8b);
+
        if (capid0_8b & 0x20) { /* check DCD: Dual Channel Disable */
                edac_dbg(0, "In single channel mode\n");
-               return 1;
+               n_channels = 1;
        } else {
                edac_dbg(0, "In dual channel mode\n");
-               return 2;
+               n_channels = 2;
        }
+
+       if (capid0_8b & 0x10) /* check if both channels are filled */
+               edac_dbg(0, "2 DIMMS per channel disabled\n");
+       else
+               edac_dbg(0, "2 DIMMS per channel enabled\n");
+
+       return n_channels;
 }
 
 static unsigned long eccerrlog_syndrome(u64 log)
@@ -290,6 +300,8 @@ static void i3200_get_drbs(void __iomem *window,
        for (i = 0; i < I3200_RANKS_PER_CHANNEL; i++) {
                drbs[0][i] = readw(window + I3200_C0DRB + 2*i) & I3200_DRB_MASK;
                drbs[1][i] = readw(window + I3200_C1DRB + 2*i) & I3200_DRB_MASK;
+
+               edac_dbg(0, "drb[0][%d] = %d, drb[1][%d] = %d\n", i, drbs[0][i], i, drbs[1][i]);
        }
 }
 
@@ -311,6 +323,9 @@ static unsigned long drb_to_nr_pages(
        int n;
 
        n = drbs[channel][rank];
+       if (!n)
+               return 0;
+
        if (rank > 0)
                n -= drbs[channel][rank - 1];
        if (stacked && (channel == 1) &&
@@ -377,19 +392,19 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
         * cumulative; the last one will contain the total memory
         * contained in all ranks.
         */
-       for (i = 0; i < mci->nr_csrows; i++) {
+       for (i = 0; i < I3200_DIMMS; i++) {
                unsigned long nr_pages;
-               struct csrow_info *csrow = mci->csrows[i];
 
-               nr_pages = drb_to_nr_pages(drbs, stacked,
-                       i / I3200_RANKS_PER_CHANNEL,
-                       i % I3200_RANKS_PER_CHANNEL);
+               for (j = 0; j < nr_channels; j++) {
+                       struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
+                                                              mci->n_layers, i, j, 0);
 
-               if (nr_pages == 0)
-                       continue;
+                       nr_pages = drb_to_nr_pages(drbs, stacked, j, i);
+                       if (nr_pages == 0)
+                               continue;
 
-               for (j = 0; j < nr_channels; j++) {
-                       struct dimm_info *dimm = csrow->channels[j]->dimm;
+                       edac_dbg(0, "csrow %d, channel %d%s, size = %ld Mb\n", i, j,
+                                stacked ? " (stacked)" : "", PAGES_TO_MiB(nr_pages));
 
                        dimm->nr_pages = nr_pages;
                        dimm->grain = nr_pages << PAGE_SHIFT;