diff options
Diffstat (limited to 'drivers/edac/amd76x_edac.c')
-rw-r--r-- | drivers/edac/amd76x_edac.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index f8fd3c807bde..9774d443fa57 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c | |||
@@ -29,7 +29,6 @@ | |||
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 | ||
33 | #define AMD76X_NR_DIMMS 4 | 32 | #define AMD76X_NR_DIMMS 4 |
34 | 33 | ||
35 | /* AMD 76x register addresses - device 0 function 0 - PCI bridge */ | 34 | /* AMD 76x register addresses - device 0 function 0 - PCI bridge */ |
@@ -146,8 +145,10 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci, | |||
146 | 145 | ||
147 | if (handle_errors) { | 146 | if (handle_errors) { |
148 | row = (info->ecc_mode_status >> 4) & 0xf; | 147 | row = (info->ecc_mode_status >> 4) & 0xf; |
149 | edac_mc_handle_ue(mci, mci->csrows[row].first_page, 0, | 148 | edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, |
150 | row, mci->ctl_name); | 149 | mci->csrows[row].first_page, 0, 0, |
150 | row, 0, -1, | ||
151 | mci->ctl_name, "", NULL); | ||
151 | } | 152 | } |
152 | } | 153 | } |
153 | 154 | ||
@@ -159,8 +160,10 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci, | |||
159 | 160 | ||
160 | if (handle_errors) { | 161 | if (handle_errors) { |
161 | row = info->ecc_mode_status & 0xf; | 162 | row = info->ecc_mode_status & 0xf; |
162 | edac_mc_handle_ce(mci, mci->csrows[row].first_page, 0, | 163 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, |
163 | 0, row, 0, mci->ctl_name); | 164 | mci->csrows[row].first_page, 0, 0, |
165 | row, 0, -1, | ||
166 | mci->ctl_name, "", NULL); | ||
164 | } | 167 | } |
165 | } | 168 | } |
166 | 169 | ||
@@ -186,11 +189,13 @@ static void amd76x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, | |||
186 | enum edac_type edac_mode) | 189 | enum edac_type edac_mode) |
187 | { | 190 | { |
188 | struct csrow_info *csrow; | 191 | struct csrow_info *csrow; |
192 | struct dimm_info *dimm; | ||
189 | u32 mba, mba_base, mba_mask, dms; | 193 | u32 mba, mba_base, mba_mask, dms; |
190 | int index; | 194 | int index; |
191 | 195 | ||
192 | for (index = 0; index < mci->nr_csrows; index++) { | 196 | for (index = 0; index < mci->nr_csrows; index++) { |
193 | csrow = &mci->csrows[index]; | 197 | csrow = &mci->csrows[index]; |
198 | dimm = csrow->channels[0].dimm; | ||
194 | 199 | ||
195 | /* find the DRAM Chip Select Base address and mask */ | 200 | /* find the DRAM Chip Select Base address and mask */ |
196 | pci_read_config_dword(pdev, | 201 | pci_read_config_dword(pdev, |
@@ -203,13 +208,13 @@ static void amd76x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, | |||
203 | mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; | 208 | mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; |
204 | pci_read_config_dword(pdev, AMD76X_DRAM_MODE_STATUS, &dms); | 209 | pci_read_config_dword(pdev, AMD76X_DRAM_MODE_STATUS, &dms); |
205 | csrow->first_page = mba_base >> PAGE_SHIFT; | 210 | csrow->first_page = mba_base >> PAGE_SHIFT; |
206 | csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; | 211 | dimm->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; |
207 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; | 212 | csrow->last_page = csrow->first_page + dimm->nr_pages - 1; |
208 | csrow->page_mask = mba_mask >> PAGE_SHIFT; | 213 | csrow->page_mask = mba_mask >> PAGE_SHIFT; |
209 | csrow->grain = csrow->nr_pages << PAGE_SHIFT; | 214 | dimm->grain = dimm->nr_pages << PAGE_SHIFT; |
210 | csrow->mtype = MEM_RDDR; | 215 | dimm->mtype = MEM_RDDR; |
211 | csrow->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN; | 216 | dimm->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN; |
212 | csrow->edac_mode = edac_mode; | 217 | dimm->edac_mode = edac_mode; |
213 | } | 218 | } |
214 | } | 219 | } |
215 | 220 | ||
@@ -230,7 +235,8 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) | |||
230 | EDAC_SECDED, | 235 | EDAC_SECDED, |
231 | EDAC_SECDED | 236 | EDAC_SECDED |
232 | }; | 237 | }; |
233 | struct mem_ctl_info *mci = NULL; | 238 | struct mem_ctl_info *mci; |
239 | struct edac_mc_layer layers[2]; | ||
234 | u32 ems; | 240 | u32 ems; |
235 | u32 ems_mode; | 241 | u32 ems_mode; |
236 | struct amd76x_error_info discard; | 242 | struct amd76x_error_info discard; |
@@ -238,11 +244,17 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) | |||
238 | debugf0("%s()\n", __func__); | 244 | debugf0("%s()\n", __func__); |
239 | pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems); | 245 | pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems); |
240 | ems_mode = (ems >> 10) & 0x3; | 246 | ems_mode = (ems >> 10) & 0x3; |
241 | mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS, 0); | ||
242 | 247 | ||
243 | if (mci == NULL) { | 248 | layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; |
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) | ||
244 | return -ENOMEM; | 257 | return -ENOMEM; |
245 | } | ||
246 | 258 | ||
247 | debugf0("%s(): mci = %p\n", __func__, mci); | 259 | debugf0("%s(): mci = %p\n", __func__, mci); |
248 | mci->dev = &pdev->dev; | 260 | mci->dev = &pdev->dev; |