aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/amd76x_edac.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/edac/amd76x_edac.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/edac/amd76x_edac.c')
-rw-r--r--drivers/edac/amd76x_edac.c72
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c
index 96e3ee3460a..e47e73bbbcc 100644
--- a/drivers/edac/amd76x_edac.c
+++ b/drivers/edac/amd76x_edac.c
@@ -29,6 +29,7 @@
29 edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg) 29 edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg)
30 30
31#define AMD76X_NR_CSROWS 8 31#define AMD76X_NR_CSROWS 8
32#define AMD76X_NR_CHANS 1
32#define AMD76X_NR_DIMMS 4 33#define AMD76X_NR_DIMMS 4
33 34
34/* AMD 76x register addresses - device 0 function 0 - PCI bridge */ 35/* AMD 76x register addresses - device 0 function 0 - PCI bridge */
@@ -105,7 +106,7 @@ static void amd76x_get_error_info(struct mem_ctl_info *mci,
105{ 106{
106 struct pci_dev *pdev; 107 struct pci_dev *pdev;
107 108
108 pdev = to_pci_dev(mci->pdev); 109 pdev = to_pci_dev(mci->dev);
109 pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, 110 pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS,
110 &info->ecc_mode_status); 111 &info->ecc_mode_status);
111 112
@@ -145,10 +146,8 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
145 146
146 if (handle_errors) { 147 if (handle_errors) {
147 row = (info->ecc_mode_status >> 4) & 0xf; 148 row = (info->ecc_mode_status >> 4) & 0xf;
148 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 149 edac_mc_handle_ue(mci, mci->csrows[row].first_page, 0,
149 mci->csrows[row]->first_page, 0, 0, 150 row, mci->ctl_name);
150 row, 0, -1,
151 mci->ctl_name, "");
152 } 151 }
153 } 152 }
154 153
@@ -160,10 +159,8 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
160 159
161 if (handle_errors) { 160 if (handle_errors) {
162 row = info->ecc_mode_status & 0xf; 161 row = info->ecc_mode_status & 0xf;
163 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 162 edac_mc_handle_ce(mci, mci->csrows[row].first_page, 0,
164 mci->csrows[row]->first_page, 0, 0, 163 0, row, 0, mci->ctl_name);
165 row, 0, -1,
166 mci->ctl_name, "");
167 } 164 }
168 } 165 }
169 166
@@ -180,7 +177,7 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
180static void amd76x_check(struct mem_ctl_info *mci) 177static void amd76x_check(struct mem_ctl_info *mci)
181{ 178{
182 struct amd76x_error_info info; 179 struct amd76x_error_info info;
183 edac_dbg(3, "\n"); 180 debugf3("%s()\n", __func__);
184 amd76x_get_error_info(mci, &info); 181 amd76x_get_error_info(mci, &info);
185 amd76x_process_error_info(mci, &info, 1); 182 amd76x_process_error_info(mci, &info, 1);
186} 183}
@@ -189,13 +186,11 @@ static void amd76x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
189 enum edac_type edac_mode) 186 enum edac_type edac_mode)
190{ 187{
191 struct csrow_info *csrow; 188 struct csrow_info *csrow;
192 struct dimm_info *dimm;
193 u32 mba, mba_base, mba_mask, dms; 189 u32 mba, mba_base, mba_mask, dms;
194 int index; 190 int index;
195 191
196 for (index = 0; index < mci->nr_csrows; index++) { 192 for (index = 0; index < mci->nr_csrows; index++) {
197 csrow = mci->csrows[index]; 193 csrow = &mci->csrows[index];
198 dimm = csrow->channels[0]->dimm;
199 194
200 /* find the DRAM Chip Select Base address and mask */ 195 /* find the DRAM Chip Select Base address and mask */
201 pci_read_config_dword(pdev, 196 pci_read_config_dword(pdev,
@@ -208,13 +203,13 @@ static void amd76x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
208 mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; 203 mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL;
209 pci_read_config_dword(pdev, AMD76X_DRAM_MODE_STATUS, &dms); 204 pci_read_config_dword(pdev, AMD76X_DRAM_MODE_STATUS, &dms);
210 csrow->first_page = mba_base >> PAGE_SHIFT; 205 csrow->first_page = mba_base >> PAGE_SHIFT;
211 dimm->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; 206 csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT;
212 csrow->last_page = csrow->first_page + dimm->nr_pages - 1; 207 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
213 csrow->page_mask = mba_mask >> PAGE_SHIFT; 208 csrow->page_mask = mba_mask >> PAGE_SHIFT;
214 dimm->grain = dimm->nr_pages << PAGE_SHIFT; 209 csrow->grain = csrow->nr_pages << PAGE_SHIFT;
215 dimm->mtype = MEM_RDDR; 210 csrow->mtype = MEM_RDDR;
216 dimm->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN; 211 csrow->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN;
217 dimm->edac_mode = edac_mode; 212 csrow->edac_mode = edac_mode;
218 } 213 }
219} 214}
220 215
@@ -235,29 +230,22 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
235 EDAC_SECDED, 230 EDAC_SECDED,
236 EDAC_SECDED 231 EDAC_SECDED
237 }; 232 };
238 struct mem_ctl_info *mci; 233 struct mem_ctl_info *mci = NULL;
239 struct edac_mc_layer layers[2];
240 u32 ems; 234 u32 ems;
241 u32 ems_mode; 235 u32 ems_mode;
242 struct amd76x_error_info discard; 236 struct amd76x_error_info discard;
243 237
244 edac_dbg(0, "\n"); 238 debugf0("%s()\n", __func__);
245 pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems); 239 pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems);
246 ems_mode = (ems >> 10) & 0x3; 240 ems_mode = (ems >> 10) & 0x3;
241 mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS, 0);
247 242
248 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; 243 if (mci == NULL) {
249 layers[0].size = AMD76X_NR_CSROWS;
250 layers[0].is_virt_csrow = true;
251 layers[1].type = EDAC_MC_LAYER_CHANNEL;
252 layers[1].size = 1;
253 layers[1].is_virt_csrow = false;
254 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
255
256 if (mci == NULL)
257 return -ENOMEM; 244 return -ENOMEM;
245 }
258 246
259 edac_dbg(0, "mci = %p\n", mci); 247 debugf0("%s(): mci = %p\n", __func__, mci);
260 mci->pdev = &pdev->dev; 248 mci->dev = &pdev->dev;
261 mci->mtype_cap = MEM_FLAG_RDDR; 249 mci->mtype_cap = MEM_FLAG_RDDR;
262 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; 250 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
263 mci->edac_cap = ems_mode ? 251 mci->edac_cap = ems_mode ?
@@ -276,7 +264,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
276 * type of memory controller. The ID is therefore hardcoded to 0. 264 * type of memory controller. The ID is therefore hardcoded to 0.
277 */ 265 */
278 if (edac_mc_add_mc(mci)) { 266 if (edac_mc_add_mc(mci)) {
279 edac_dbg(3, "failed edac_mc_add_mc()\n"); 267 debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
280 goto fail; 268 goto fail;
281 } 269 }
282 270
@@ -292,7 +280,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
292 } 280 }
293 281
294 /* get this far and it's successful */ 282 /* get this far and it's successful */
295 edac_dbg(3, "success\n"); 283 debugf3("%s(): success\n", __func__);
296 return 0; 284 return 0;
297 285
298fail: 286fail:
@@ -301,10 +289,10 @@ fail:
301} 289}
302 290
303/* returns count (>= 0), or negative on error */ 291/* returns count (>= 0), or negative on error */
304static int amd76x_init_one(struct pci_dev *pdev, 292static int __devinit amd76x_init_one(struct pci_dev *pdev,
305 const struct pci_device_id *ent) 293 const struct pci_device_id *ent)
306{ 294{
307 edac_dbg(0, "\n"); 295 debugf0("%s()\n", __func__);
308 296
309 /* don't need to call pci_enable_device() */ 297 /* don't need to call pci_enable_device() */
310 return amd76x_probe1(pdev, ent->driver_data); 298 return amd76x_probe1(pdev, ent->driver_data);
@@ -318,11 +306,11 @@ static int amd76x_init_one(struct pci_dev *pdev,
318 * structure for the device then delete the mci and free the 306 * structure for the device then delete the mci and free the
319 * resources. 307 * resources.
320 */ 308 */
321static void amd76x_remove_one(struct pci_dev *pdev) 309static void __devexit amd76x_remove_one(struct pci_dev *pdev)
322{ 310{
323 struct mem_ctl_info *mci; 311 struct mem_ctl_info *mci;
324 312
325 edac_dbg(0, "\n"); 313 debugf0("%s()\n", __func__);
326 314
327 if (amd76x_pci) 315 if (amd76x_pci)
328 edac_pci_release_generic_ctl(amd76x_pci); 316 edac_pci_release_generic_ctl(amd76x_pci);
@@ -333,7 +321,7 @@ static void amd76x_remove_one(struct pci_dev *pdev)
333 edac_mc_free(mci); 321 edac_mc_free(mci);
334} 322}
335 323
336static DEFINE_PCI_DEVICE_TABLE(amd76x_pci_tbl) = { 324static const struct pci_device_id amd76x_pci_tbl[] __devinitdata = {
337 { 325 {
338 PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0, 326 PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
339 AMD762}, 327 AMD762},
@@ -350,7 +338,7 @@ MODULE_DEVICE_TABLE(pci, amd76x_pci_tbl);
350static struct pci_driver amd76x_driver = { 338static struct pci_driver amd76x_driver = {
351 .name = EDAC_MOD_STR, 339 .name = EDAC_MOD_STR,
352 .probe = amd76x_init_one, 340 .probe = amd76x_init_one,
353 .remove = amd76x_remove_one, 341 .remove = __devexit_p(amd76x_remove_one),
354 .id_table = amd76x_pci_tbl, 342 .id_table = amd76x_pci_tbl,
355}; 343};
356 344