aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i82860_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/i82860_edac.c')
-rw-r--r--drivers/edac/i82860_edac.c102
1 files changed, 51 insertions, 51 deletions
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c
index e2c3b8bc097b..d196dcc850a8 100644
--- a/drivers/edac/i82860_edac.c
+++ b/drivers/edac/i82860_edac.c
@@ -133,15 +133,50 @@ static void i82860_check(struct mem_ctl_info *mci)
133 i82860_process_error_info(mci, &info, 1); 133 i82860_process_error_info(mci, &info, 1);
134} 134}
135 135
136static int i82860_probe1(struct pci_dev *pdev, int dev_idx) 136static void i82860_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev)
137{ 137{
138 int rc = -ENODEV;
139 int index;
140 struct mem_ctl_info *mci = NULL;
141 unsigned long last_cumul_size; 138 unsigned long last_cumul_size;
142 struct i82860_error_info discard; 139 u16 mchcfg_ddim; /* DRAM Data Integrity Mode 0=none, 2=edac */
140 u16 value;
141 u32 cumul_size;
142 struct csrow_info *csrow;
143 int index;
144
145 pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim);
146 mchcfg_ddim = mchcfg_ddim & 0x180;
147 last_cumul_size = 0;
148
149 /* The group row boundary (GRA) reg values are boundary address
150 * for each DRAM row with a granularity of 16MB. GRA regs are
151 * cumulative; therefore GRA15 will contain the total memory contained
152 * in all eight rows.
153 */
154 for (index = 0; index < mci->nr_csrows; index++) {
155 csrow = &mci->csrows[index];
156 pci_read_config_word(pdev, I82860_GBA + index * 2, &value);
157 cumul_size = (value & I82860_GBA_MASK) <<
158 (I82860_GBA_SHIFT - PAGE_SHIFT);
159 debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
160 cumul_size);
161
162 if (cumul_size == last_cumul_size)
163 continue; /* not populated */
143 164
144 u16 mchcfg_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ 165 csrow->first_page = last_cumul_size;
166 csrow->last_page = cumul_size - 1;
167 csrow->nr_pages = cumul_size - last_cumul_size;
168 last_cumul_size = cumul_size;
169 csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */
170 csrow->mtype = MEM_RMBS;
171 csrow->dtype = DEV_UNKNOWN;
172 csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
173 }
174}
175
176static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
177{
178 struct mem_ctl_info *mci;
179 struct i82860_error_info discard;
145 180
146 /* RDRAM has channels but these don't map onto the abstractions that 181 /* RDRAM has channels but these don't map onto the abstractions that
147 edac uses. 182 edac uses.
@@ -159,53 +194,15 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
159 debugf3("%s(): init mci\n", __func__); 194 debugf3("%s(): init mci\n", __func__);
160 mci->dev = &pdev->dev; 195 mci->dev = &pdev->dev;
161 mci->mtype_cap = MEM_FLAG_DDR; 196 mci->mtype_cap = MEM_FLAG_DDR;
162
163 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; 197 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
164 /* I"m not sure about this but I think that all RDRAM is SECDED */ 198 /* I"m not sure about this but I think that all RDRAM is SECDED */
165 mci->edac_cap = EDAC_FLAG_SECDED; 199 mci->edac_cap = EDAC_FLAG_SECDED;
166 /* adjust FLAGS */
167
168 mci->mod_name = EDAC_MOD_STR; 200 mci->mod_name = EDAC_MOD_STR;
169 mci->mod_ver = I82860_REVISION; 201 mci->mod_ver = I82860_REVISION;
170 mci->ctl_name = i82860_devs[dev_idx].ctl_name; 202 mci->ctl_name = i82860_devs[dev_idx].ctl_name;
171 mci->edac_check = i82860_check; 203 mci->edac_check = i82860_check;
172 mci->ctl_page_to_phys = NULL; 204 mci->ctl_page_to_phys = NULL;
173 205 i82860_init_csrows(mci, pdev);
174 pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim);
175 mchcfg_ddim = mchcfg_ddim & 0x180;
176
177 /*
178 * The group row boundary (GRA) reg values are boundary address
179 * for each DRAM row with a granularity of 16MB. GRA regs are
180 * cumulative; therefore GRA15 will contain the total memory contained
181 * in all eight rows.
182 */
183 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
184 u16 value;
185 u32 cumul_size;
186 struct csrow_info *csrow = &mci->csrows[index];
187
188 pci_read_config_word(pdev, I82860_GBA + index * 2,
189 &value);
190
191 cumul_size = (value & I82860_GBA_MASK) <<
192 (I82860_GBA_SHIFT - PAGE_SHIFT);
193 debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
194 cumul_size);
195
196 if (cumul_size == last_cumul_size)
197 continue; /* not populated */
198
199 csrow->first_page = last_cumul_size;
200 csrow->last_page = cumul_size - 1;
201 csrow->nr_pages = cumul_size - last_cumul_size;
202 last_cumul_size = cumul_size;
203 csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */
204 csrow->mtype = MEM_RMBS;
205 csrow->dtype = DEV_UNKNOWN;
206 csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
207 }
208
209 i82860_get_error_info(mci, &discard); /* clear counters */ 206 i82860_get_error_info(mci, &discard); /* clear counters */
210 207
211 /* Here we assume that we will never see multiple instances of this 208 /* Here we assume that we will never see multiple instances of this
@@ -213,14 +210,17 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
213 */ 210 */
214 if (edac_mc_add_mc(mci,0)) { 211 if (edac_mc_add_mc(mci,0)) {
215 debugf3("%s(): failed edac_mc_add_mc()\n", __func__); 212 debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
216 edac_mc_free(mci); 213 goto fail;
217 } else {
218 /* get this far and it's successful */
219 debugf3("%s(): success\n", __func__);
220 rc = 0;
221 } 214 }
222 215
223 return rc; 216 /* get this far and it's successful */
217 debugf3("%s(): success\n", __func__);
218
219 return 0;
220
221fail:
222 edac_mc_free(mci);
223 return -ENODEV;
224} 224}
225 225
226/* returns count (>= 0), or negative on error */ 226/* returns count (>= 0), or negative on error */