aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/r82600_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/r82600_edac.c')
-rw-r--r--drivers/edac/r82600_edac.c71
1 files changed, 27 insertions, 44 deletions
diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c
index 5966916d02bd..2c29fafe67c7 100644
--- a/drivers/edac/r82600_edac.c
+++ b/drivers/edac/r82600_edac.c
@@ -18,19 +18,16 @@
18#include <linux/config.h> 18#include <linux/config.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/init.h> 20#include <linux/init.h>
21
22#include <linux/pci.h> 21#include <linux/pci.h>
23#include <linux/pci_ids.h> 22#include <linux/pci_ids.h>
24
25#include <linux/slab.h> 23#include <linux/slab.h>
26
27#include "edac_mc.h" 24#include "edac_mc.h"
28 25
29#define r82600_printk(level, fmt, arg...) \ 26#define r82600_printk(level, fmt, arg...) \
30 edac_printk(level, "r82600", fmt, ##arg) 27 edac_printk(level, "r82600", fmt, ##arg)
31 28
32#define r82600_mc_printk(mci, level, fmt, arg...) \ 29#define r82600_mc_printk(mci, level, fmt, arg...) \
33 edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg) 30 edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg)
34 31
35/* Radisys say "The 82600 integrates a main memory SDRAM controller that 32/* Radisys say "The 82600 integrates a main memory SDRAM controller that
36 * supports up to four banks of memory. The four banks can support a mix of 33 * supports up to four banks of memory. The four banks can support a mix of
@@ -132,10 +129,8 @@ struct r82600_error_info {
132 u32 eapr; 129 u32 eapr;
133}; 130};
134 131
135
136static unsigned int disable_hardware_scrub = 0; 132static unsigned int disable_hardware_scrub = 0;
137 133
138
139static void r82600_get_error_info (struct mem_ctl_info *mci, 134static void r82600_get_error_info (struct mem_ctl_info *mci,
140 struct r82600_error_info *info) 135 struct r82600_error_info *info)
141{ 136{
@@ -144,17 +139,16 @@ static void r82600_get_error_info (struct mem_ctl_info *mci,
144 if (info->eapr & BIT(0)) 139 if (info->eapr & BIT(0))
145 /* Clear error to allow next error to be reported [p.62] */ 140 /* Clear error to allow next error to be reported [p.62] */
146 pci_write_bits32(mci->pdev, R82600_EAP, 141 pci_write_bits32(mci->pdev, R82600_EAP,
147 ((u32) BIT(0) & (u32) BIT(1)), 142 ((u32) BIT(0) & (u32) BIT(1)),
148 ((u32) BIT(0) & (u32) BIT(1))); 143 ((u32) BIT(0) & (u32) BIT(1)));
149 144
150 if (info->eapr & BIT(1)) 145 if (info->eapr & BIT(1))
151 /* Clear error to allow next error to be reported [p.62] */ 146 /* Clear error to allow next error to be reported [p.62] */
152 pci_write_bits32(mci->pdev, R82600_EAP, 147 pci_write_bits32(mci->pdev, R82600_EAP,
153 ((u32) BIT(0) & (u32) BIT(1)), 148 ((u32) BIT(0) & (u32) BIT(1)),
154 ((u32) BIT(0) & (u32) BIT(1))); 149 ((u32) BIT(0) & (u32) BIT(1)));
155} 150}
156 151
157
158static int r82600_process_error_info (struct mem_ctl_info *mci, 152static int r82600_process_error_info (struct mem_ctl_info *mci,
159 struct r82600_error_info *info, int handle_errors) 153 struct r82600_error_info *info, int handle_errors)
160{ 154{
@@ -173,26 +167,25 @@ static int r82600_process_error_info (struct mem_ctl_info *mci,
173 * granularity (upper 19 bits only) */ 167 * granularity (upper 19 bits only) */
174 page = eapaddr >> PAGE_SHIFT; 168 page = eapaddr >> PAGE_SHIFT;
175 169
176 if (info->eapr & BIT(0)) { /* CE? */ 170 if (info->eapr & BIT(0)) { /* CE? */
177 error_found = 1; 171 error_found = 1;
178 172
179 if (handle_errors) 173 if (handle_errors)
180 edac_mc_handle_ce( 174 edac_mc_handle_ce(mci, page, 0, /* not avail */
181 mci, page, 0, /* not avail */ 175 syndrome,
182 syndrome, 176 edac_mc_find_csrow_by_page(mci, page),
183 edac_mc_find_csrow_by_page(mci, page), 177 0, /* channel */
184 0, /* channel */ 178 mci->ctl_name);
185 mci->ctl_name);
186 } 179 }
187 180
188 if (info->eapr & BIT(1)) { /* UE? */ 181 if (info->eapr & BIT(1)) { /* UE? */
189 error_found = 1; 182 error_found = 1;
190 183
191 if (handle_errors) 184 if (handle_errors)
192 /* 82600 doesn't give enough info */ 185 /* 82600 doesn't give enough info */
193 edac_mc_handle_ue(mci, page, 0, 186 edac_mc_handle_ue(mci, page, 0,
194 edac_mc_find_csrow_by_page(mci, page), 187 edac_mc_find_csrow_by_page(mci, page),
195 mci->ctl_name); 188 mci->ctl_name);
196 } 189 }
197 190
198 return error_found; 191 return error_found;
@@ -222,21 +215,15 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
222 struct r82600_error_info discard; 215 struct r82600_error_info discard;
223 216
224 debugf0("%s()\n", __func__); 217 debugf0("%s()\n", __func__);
225
226
227 pci_read_config_byte(pdev, R82600_DRAMC, &dramcr); 218 pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
228 pci_read_config_dword(pdev, R82600_EAP, &eapr); 219 pci_read_config_dword(pdev, R82600_EAP, &eapr);
229
230 ecc_on = dramcr & BIT(5); 220 ecc_on = dramcr & BIT(5);
231 reg_sdram = dramcr & BIT(4); 221 reg_sdram = dramcr & BIT(4);
232 scrub_disabled = eapr & BIT(31); 222 scrub_disabled = eapr & BIT(31);
233 sdram_refresh_rate = dramcr & (BIT(0) | BIT(1)); 223 sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
234
235 debugf2("%s(): sdram refresh rate = %#0x\n", __func__, 224 debugf2("%s(): sdram refresh rate = %#0x\n", __func__,
236 sdram_refresh_rate); 225 sdram_refresh_rate);
237
238 debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr); 226 debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr);
239
240 mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS); 227 mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS);
241 228
242 if (mci == NULL) { 229 if (mci == NULL) {
@@ -245,19 +232,19 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
245 } 232 }
246 233
247 debugf0("%s(): mci = %p\n", __func__, mci); 234 debugf0("%s(): mci = %p\n", __func__, mci);
248
249 mci->pdev = pdev; 235 mci->pdev = pdev;
250 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; 236 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
251
252 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; 237 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
253 /* FIXME try to work out if the chip leads have been * 238 /* FIXME try to work out if the chip leads have been used for COM2
254 * used for COM2 instead on this board? [MA6?] MAYBE: */ 239 * instead on this board? [MA6?] MAYBE:
240 */
255 241
256 /* On the R82600, the pins for memory bits 72:65 - i.e. the * 242 /* On the R82600, the pins for memory bits 72:65 - i.e. the *
257 * EC bits are shared with the pins for COM2 (!), so if COM2 * 243 * EC bits are shared with the pins for COM2 (!), so if COM2 *
258 * is enabled, we assume COM2 is wired up, and thus no EDAC * 244 * is enabled, we assume COM2 is wired up, and thus no EDAC *
259 * is possible. */ 245 * is possible. */
260 mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; 246 mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
247
261 if (ecc_on) { 248 if (ecc_on) {
262 if (scrub_disabled) 249 if (scrub_disabled)
263 debugf3("%s(): mci = %p - Scrubbing disabled! EAP: " 250 debugf3("%s(): mci = %p - Scrubbing disabled! EAP: "
@@ -295,7 +282,6 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
295 continue; 282 continue;
296 283
297 row_base = row_high_limit_last; 284 row_base = row_high_limit_last;
298
299 csrow->first_page = row_base >> PAGE_SHIFT; 285 csrow->first_page = row_base >> PAGE_SHIFT;
300 csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1; 286 csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
301 csrow->nr_pages = csrow->last_page - csrow->first_page + 1; 287 csrow->nr_pages = csrow->last_page - csrow->first_page + 1;
@@ -338,7 +324,7 @@ fail:
338 324
339/* returns count (>= 0), or negative on error */ 325/* returns count (>= 0), or negative on error */
340static int __devinit r82600_init_one(struct pci_dev *pdev, 326static int __devinit r82600_init_one(struct pci_dev *pdev,
341 const struct pci_device_id *ent) 327 const struct pci_device_id *ent)
342{ 328{
343 debugf0("%s()\n", __func__); 329 debugf0("%s()\n", __func__);
344 330
@@ -346,7 +332,6 @@ static int __devinit r82600_init_one(struct pci_dev *pdev,
346 return r82600_probe1(pdev, ent->driver_data); 332 return r82600_probe1(pdev, ent->driver_data);
347} 333}
348 334
349
350static void __devexit r82600_remove_one(struct pci_dev *pdev) 335static void __devexit r82600_remove_one(struct pci_dev *pdev)
351{ 336{
352 struct mem_ctl_info *mci; 337 struct mem_ctl_info *mci;
@@ -359,15 +344,17 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev)
359 edac_mc_free(mci); 344 edac_mc_free(mci);
360} 345}
361 346
362
363static const struct pci_device_id r82600_pci_tbl[] __devinitdata = { 347static const struct pci_device_id r82600_pci_tbl[] __devinitdata = {
364 {PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)}, 348 {
365 {0,} /* 0 terminated list. */ 349 PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)
350 },
351 {
352 0,
353 } /* 0 terminated list. */
366}; 354};
367 355
368MODULE_DEVICE_TABLE(pci, r82600_pci_tbl); 356MODULE_DEVICE_TABLE(pci, r82600_pci_tbl);
369 357
370
371static struct pci_driver r82600_driver = { 358static struct pci_driver r82600_driver = {
372 .name = EDAC_MOD_STR, 359 .name = EDAC_MOD_STR,
373 .probe = r82600_init_one, 360 .probe = r82600_init_one,
@@ -375,26 +362,22 @@ static struct pci_driver r82600_driver = {
375 .id_table = r82600_pci_tbl, 362 .id_table = r82600_pci_tbl,
376}; 363};
377 364
378
379static int __init r82600_init(void) 365static int __init r82600_init(void)
380{ 366{
381 return pci_register_driver(&r82600_driver); 367 return pci_register_driver(&r82600_driver);
382} 368}
383 369
384
385static void __exit r82600_exit(void) 370static void __exit r82600_exit(void)
386{ 371{
387 pci_unregister_driver(&r82600_driver); 372 pci_unregister_driver(&r82600_driver);
388} 373}
389 374
390
391module_init(r82600_init); 375module_init(r82600_init);
392module_exit(r82600_exit); 376module_exit(r82600_exit);
393 377
394
395MODULE_LICENSE("GPL"); 378MODULE_LICENSE("GPL");
396MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. " 379MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
397 "on behalf of EADS Astrium"); 380 "on behalf of EADS Astrium");
398MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers"); 381MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
399 382
400module_param(disable_hardware_scrub, bool, 0644); 383module_param(disable_hardware_scrub, bool, 0644);