diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/edac/amd76x_edac.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/edac/amd76x_edac.c')
-rw-r--r-- | drivers/edac/amd76x_edac.c | 72 |
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, | |||
180 | static void amd76x_check(struct mem_ctl_info *mci) | 177 | static 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 | ||
298 | fail: | 286 | fail: |
@@ -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 */ |
304 | static int amd76x_init_one(struct pci_dev *pdev, | 292 | static 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 | */ |
321 | static void amd76x_remove_one(struct pci_dev *pdev) | 309 | static 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 | ||
336 | static DEFINE_PCI_DEVICE_TABLE(amd76x_pci_tbl) = { | 324 | static 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); | |||
350 | static struct pci_driver amd76x_driver = { | 338 | static 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 | ||