Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.9 885 lines 22 kB view raw
1/* 2 * Marvell MV64x60 Memory Controller kernel module for PPC platforms 3 * 4 * Author: Dave Jiang <djiang@mvista.com> 5 * 6 * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under 7 * the terms of the GNU General Public License version 2. This program 8 * is licensed "as is" without any warranty of any kind, whether express 9 * or implied. 10 * 11 */ 12 13#include <linux/module.h> 14#include <linux/init.h> 15#include <linux/interrupt.h> 16#include <linux/io.h> 17#include <linux/edac.h> 18#include <linux/gfp.h> 19 20#include "edac_core.h" 21#include "edac_module.h" 22#include "mv64x60_edac.h" 23 24static const char *mv64x60_ctl_name = "MV64x60"; 25static int edac_dev_idx; 26static int edac_pci_idx; 27static int edac_mc_idx; 28 29/*********************** PCI err device **********************************/ 30#ifdef CONFIG_PCI 31static void mv64x60_pci_check(struct edac_pci_ctl_info *pci) 32{ 33 struct mv64x60_pci_pdata *pdata = pci->pvt_info; 34 u32 cause; 35 36 cause = in_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE); 37 if (!cause) 38 return; 39 40 printk(KERN_ERR "Error in PCI %d Interface\n", pdata->pci_hose); 41 printk(KERN_ERR "Cause register: 0x%08x\n", cause); 42 printk(KERN_ERR "Address Low: 0x%08x\n", 43 in_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_LO)); 44 printk(KERN_ERR "Address High: 0x%08x\n", 45 in_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_HI)); 46 printk(KERN_ERR "Attribute: 0x%08x\n", 47 in_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_ATTR)); 48 printk(KERN_ERR "Command: 0x%08x\n", 49 in_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_CMD)); 50 out_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE, ~cause); 51 52 if (cause & MV64X60_PCI_PE_MASK) 53 edac_pci_handle_pe(pci, pci->ctl_name); 54 55 if (!(cause & MV64X60_PCI_PE_MASK)) 56 edac_pci_handle_npe(pci, pci->ctl_name); 57} 58 59static irqreturn_t mv64x60_pci_isr(int irq, void *dev_id) 60{ 61 struct edac_pci_ctl_info *pci = dev_id; 62 struct mv64x60_pci_pdata *pdata = pci->pvt_info; 63 u32 val; 64 65 val = in_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE); 66 if (!val) 67 return IRQ_NONE; 68 69 mv64x60_pci_check(pci); 70 71 return IRQ_HANDLED; 72} 73 74/* 75 * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of 76 * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as 77 * well. IOW, don't set bit 0. 78 */ 79 80/* Erratum FEr PCI-#16: clear bit 0 of PCI SERRn Mask reg. */ 81static int __init mv64x60_pci_fixup(struct platform_device *pdev) 82{ 83 struct resource *r; 84 void __iomem *pci_serr; 85 86 r = platform_get_resource(pdev, IORESOURCE_MEM, 1); 87 if (!r) { 88 printk(KERN_ERR "%s: Unable to get resource for " 89 "PCI err regs\n", __func__); 90 return -ENOENT; 91 } 92 93 pci_serr = ioremap(r->start, resource_size(r)); 94 if (!pci_serr) 95 return -ENOMEM; 96 97 out_le32(pci_serr, in_le32(pci_serr) & ~0x1); 98 iounmap(pci_serr); 99 100 return 0; 101} 102 103static int mv64x60_pci_err_probe(struct platform_device *pdev) 104{ 105 struct edac_pci_ctl_info *pci; 106 struct mv64x60_pci_pdata *pdata; 107 struct resource *r; 108 int res = 0; 109 110 if (!devres_open_group(&pdev->dev, mv64x60_pci_err_probe, GFP_KERNEL)) 111 return -ENOMEM; 112 113 pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mv64x60_pci_err"); 114 if (!pci) 115 return -ENOMEM; 116 117 pdata = pci->pvt_info; 118 119 pdata->pci_hose = pdev->id; 120 pdata->name = "mpc85xx_pci_err"; 121 platform_set_drvdata(pdev, pci); 122 pci->dev = &pdev->dev; 123 pci->dev_name = dev_name(&pdev->dev); 124 pci->mod_name = EDAC_MOD_STR; 125 pci->ctl_name = pdata->name; 126 127 if (edac_op_state == EDAC_OPSTATE_POLL) 128 pci->edac_check = mv64x60_pci_check; 129 130 pdata->edac_idx = edac_pci_idx++; 131 132 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 133 if (!r) { 134 printk(KERN_ERR "%s: Unable to get resource for " 135 "PCI err regs\n", __func__); 136 res = -ENOENT; 137 goto err; 138 } 139 140 if (!devm_request_mem_region(&pdev->dev, 141 r->start, 142 resource_size(r), 143 pdata->name)) { 144 printk(KERN_ERR "%s: Error while requesting mem region\n", 145 __func__); 146 res = -EBUSY; 147 goto err; 148 } 149 150 pdata->pci_vbase = devm_ioremap(&pdev->dev, 151 r->start, 152 resource_size(r)); 153 if (!pdata->pci_vbase) { 154 printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__); 155 res = -ENOMEM; 156 goto err; 157 } 158 159 res = mv64x60_pci_fixup(pdev); 160 if (res < 0) { 161 printk(KERN_ERR "%s: PCI fixup failed\n", __func__); 162 goto err; 163 } 164 165 out_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE, 0); 166 out_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_MASK, 0); 167 out_le32(pdata->pci_vbase + MV64X60_PCI_ERROR_MASK, 168 MV64X60_PCIx_ERR_MASK_VAL); 169 170 if (edac_pci_add_device(pci, pdata->edac_idx) > 0) { 171 edac_dbg(3, "failed edac_pci_add_device()\n"); 172 goto err; 173 } 174 175 if (edac_op_state == EDAC_OPSTATE_INT) { 176 pdata->irq = platform_get_irq(pdev, 0); 177 res = devm_request_irq(&pdev->dev, 178 pdata->irq, 179 mv64x60_pci_isr, 180 0, 181 "[EDAC] PCI err", 182 pci); 183 if (res < 0) { 184 printk(KERN_ERR "%s: Unable to request irq %d for " 185 "MV64x60 PCI ERR\n", __func__, pdata->irq); 186 res = -ENODEV; 187 goto err2; 188 } 189 printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n", 190 pdata->irq); 191 } 192 193 devres_remove_group(&pdev->dev, mv64x60_pci_err_probe); 194 195 /* get this far and it's successful */ 196 edac_dbg(3, "success\n"); 197 198 return 0; 199 200err2: 201 edac_pci_del_device(&pdev->dev); 202err: 203 edac_pci_free_ctl_info(pci); 204 devres_release_group(&pdev->dev, mv64x60_pci_err_probe); 205 return res; 206} 207 208static int mv64x60_pci_err_remove(struct platform_device *pdev) 209{ 210 struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev); 211 212 edac_dbg(0, "\n"); 213 214 edac_pci_del_device(&pdev->dev); 215 216 edac_pci_free_ctl_info(pci); 217 218 return 0; 219} 220 221static struct platform_driver mv64x60_pci_err_driver = { 222 .probe = mv64x60_pci_err_probe, 223 .remove = mv64x60_pci_err_remove, 224 .driver = { 225 .name = "mv64x60_pci_err", 226 } 227}; 228 229#endif /* CONFIG_PCI */ 230 231/*********************** SRAM err device **********************************/ 232static void mv64x60_sram_check(struct edac_device_ctl_info *edac_dev) 233{ 234 struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info; 235 u32 cause; 236 237 cause = in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE); 238 if (!cause) 239 return; 240 241 printk(KERN_ERR "Error in internal SRAM\n"); 242 printk(KERN_ERR "Cause register: 0x%08x\n", cause); 243 printk(KERN_ERR "Address Low: 0x%08x\n", 244 in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_ADDR_LO)); 245 printk(KERN_ERR "Address High: 0x%08x\n", 246 in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_ADDR_HI)); 247 printk(KERN_ERR "Data Low: 0x%08x\n", 248 in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_DATA_LO)); 249 printk(KERN_ERR "Data High: 0x%08x\n", 250 in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_DATA_HI)); 251 printk(KERN_ERR "Parity: 0x%08x\n", 252 in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_PARITY)); 253 out_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE, 0); 254 255 edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name); 256} 257 258static irqreturn_t mv64x60_sram_isr(int irq, void *dev_id) 259{ 260 struct edac_device_ctl_info *edac_dev = dev_id; 261 struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info; 262 u32 cause; 263 264 cause = in_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE); 265 if (!cause) 266 return IRQ_NONE; 267 268 mv64x60_sram_check(edac_dev); 269 270 return IRQ_HANDLED; 271} 272 273static int mv64x60_sram_err_probe(struct platform_device *pdev) 274{ 275 struct edac_device_ctl_info *edac_dev; 276 struct mv64x60_sram_pdata *pdata; 277 struct resource *r; 278 int res = 0; 279 280 if (!devres_open_group(&pdev->dev, mv64x60_sram_err_probe, GFP_KERNEL)) 281 return -ENOMEM; 282 283 edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata), 284 "sram", 1, NULL, 0, 0, NULL, 0, 285 edac_dev_idx); 286 if (!edac_dev) { 287 devres_release_group(&pdev->dev, mv64x60_sram_err_probe); 288 return -ENOMEM; 289 } 290 291 pdata = edac_dev->pvt_info; 292 pdata->name = "mv64x60_sram_err"; 293 edac_dev->dev = &pdev->dev; 294 platform_set_drvdata(pdev, edac_dev); 295 edac_dev->dev_name = dev_name(&pdev->dev); 296 297 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 298 if (!r) { 299 printk(KERN_ERR "%s: Unable to get resource for " 300 "SRAM err regs\n", __func__); 301 res = -ENOENT; 302 goto err; 303 } 304 305 if (!devm_request_mem_region(&pdev->dev, 306 r->start, 307 resource_size(r), 308 pdata->name)) { 309 printk(KERN_ERR "%s: Error while request mem region\n", 310 __func__); 311 res = -EBUSY; 312 goto err; 313 } 314 315 pdata->sram_vbase = devm_ioremap(&pdev->dev, 316 r->start, 317 resource_size(r)); 318 if (!pdata->sram_vbase) { 319 printk(KERN_ERR "%s: Unable to setup SRAM err regs\n", 320 __func__); 321 res = -ENOMEM; 322 goto err; 323 } 324 325 /* setup SRAM err registers */ 326 out_le32(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE, 0); 327 328 edac_dev->mod_name = EDAC_MOD_STR; 329 edac_dev->ctl_name = pdata->name; 330 331 if (edac_op_state == EDAC_OPSTATE_POLL) 332 edac_dev->edac_check = mv64x60_sram_check; 333 334 pdata->edac_idx = edac_dev_idx++; 335 336 if (edac_device_add_device(edac_dev) > 0) { 337 edac_dbg(3, "failed edac_device_add_device()\n"); 338 goto err; 339 } 340 341 if (edac_op_state == EDAC_OPSTATE_INT) { 342 pdata->irq = platform_get_irq(pdev, 0); 343 res = devm_request_irq(&pdev->dev, 344 pdata->irq, 345 mv64x60_sram_isr, 346 0, 347 "[EDAC] SRAM err", 348 edac_dev); 349 if (res < 0) { 350 printk(KERN_ERR 351 "%s: Unable to request irq %d for " 352 "MV64x60 SRAM ERR\n", __func__, pdata->irq); 353 res = -ENODEV; 354 goto err2; 355 } 356 357 printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for SRAM Err\n", 358 pdata->irq); 359 } 360 361 devres_remove_group(&pdev->dev, mv64x60_sram_err_probe); 362 363 /* get this far and it's successful */ 364 edac_dbg(3, "success\n"); 365 366 return 0; 367 368err2: 369 edac_device_del_device(&pdev->dev); 370err: 371 devres_release_group(&pdev->dev, mv64x60_sram_err_probe); 372 edac_device_free_ctl_info(edac_dev); 373 return res; 374} 375 376static int mv64x60_sram_err_remove(struct platform_device *pdev) 377{ 378 struct edac_device_ctl_info *edac_dev = platform_get_drvdata(pdev); 379 380 edac_dbg(0, "\n"); 381 382 edac_device_del_device(&pdev->dev); 383 edac_device_free_ctl_info(edac_dev); 384 385 return 0; 386} 387 388static struct platform_driver mv64x60_sram_err_driver = { 389 .probe = mv64x60_sram_err_probe, 390 .remove = mv64x60_sram_err_remove, 391 .driver = { 392 .name = "mv64x60_sram_err", 393 } 394}; 395 396/*********************** CPU err device **********************************/ 397static void mv64x60_cpu_check(struct edac_device_ctl_info *edac_dev) 398{ 399 struct mv64x60_cpu_pdata *pdata = edac_dev->pvt_info; 400 u32 cause; 401 402 cause = in_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE) & 403 MV64x60_CPU_CAUSE_MASK; 404 if (!cause) 405 return; 406 407 printk(KERN_ERR "Error on CPU interface\n"); 408 printk(KERN_ERR "Cause register: 0x%08x\n", cause); 409 printk(KERN_ERR "Address Low: 0x%08x\n", 410 in_le32(pdata->cpu_vbase[0] + MV64x60_CPU_ERR_ADDR_LO)); 411 printk(KERN_ERR "Address High: 0x%08x\n", 412 in_le32(pdata->cpu_vbase[0] + MV64x60_CPU_ERR_ADDR_HI)); 413 printk(KERN_ERR "Data Low: 0x%08x\n", 414 in_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_DATA_LO)); 415 printk(KERN_ERR "Data High: 0x%08x\n", 416 in_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_DATA_HI)); 417 printk(KERN_ERR "Parity: 0x%08x\n", 418 in_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_PARITY)); 419 out_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE, 0); 420 421 edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name); 422} 423 424static irqreturn_t mv64x60_cpu_isr(int irq, void *dev_id) 425{ 426 struct edac_device_ctl_info *edac_dev = dev_id; 427 struct mv64x60_cpu_pdata *pdata = edac_dev->pvt_info; 428 u32 cause; 429 430 cause = in_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE) & 431 MV64x60_CPU_CAUSE_MASK; 432 if (!cause) 433 return IRQ_NONE; 434 435 mv64x60_cpu_check(edac_dev); 436 437 return IRQ_HANDLED; 438} 439 440static int mv64x60_cpu_err_probe(struct platform_device *pdev) 441{ 442 struct edac_device_ctl_info *edac_dev; 443 struct resource *r; 444 struct mv64x60_cpu_pdata *pdata; 445 int res = 0; 446 447 if (!devres_open_group(&pdev->dev, mv64x60_cpu_err_probe, GFP_KERNEL)) 448 return -ENOMEM; 449 450 edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata), 451 "cpu", 1, NULL, 0, 0, NULL, 0, 452 edac_dev_idx); 453 if (!edac_dev) { 454 devres_release_group(&pdev->dev, mv64x60_cpu_err_probe); 455 return -ENOMEM; 456 } 457 458 pdata = edac_dev->pvt_info; 459 pdata->name = "mv64x60_cpu_err"; 460 edac_dev->dev = &pdev->dev; 461 platform_set_drvdata(pdev, edac_dev); 462 edac_dev->dev_name = dev_name(&pdev->dev); 463 464 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 465 if (!r) { 466 printk(KERN_ERR "%s: Unable to get resource for " 467 "CPU err regs\n", __func__); 468 res = -ENOENT; 469 goto err; 470 } 471 472 if (!devm_request_mem_region(&pdev->dev, 473 r->start, 474 resource_size(r), 475 pdata->name)) { 476 printk(KERN_ERR "%s: Error while requesting mem region\n", 477 __func__); 478 res = -EBUSY; 479 goto err; 480 } 481 482 pdata->cpu_vbase[0] = devm_ioremap(&pdev->dev, 483 r->start, 484 resource_size(r)); 485 if (!pdata->cpu_vbase[0]) { 486 printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__); 487 res = -ENOMEM; 488 goto err; 489 } 490 491 r = platform_get_resource(pdev, IORESOURCE_MEM, 1); 492 if (!r) { 493 printk(KERN_ERR "%s: Unable to get resource for " 494 "CPU err regs\n", __func__); 495 res = -ENOENT; 496 goto err; 497 } 498 499 if (!devm_request_mem_region(&pdev->dev, 500 r->start, 501 resource_size(r), 502 pdata->name)) { 503 printk(KERN_ERR "%s: Error while requesting mem region\n", 504 __func__); 505 res = -EBUSY; 506 goto err; 507 } 508 509 pdata->cpu_vbase[1] = devm_ioremap(&pdev->dev, 510 r->start, 511 resource_size(r)); 512 if (!pdata->cpu_vbase[1]) { 513 printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__); 514 res = -ENOMEM; 515 goto err; 516 } 517 518 /* setup CPU err registers */ 519 out_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE, 0); 520 out_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_MASK, 0); 521 out_le32(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_MASK, 0x000000ff); 522 523 edac_dev->mod_name = EDAC_MOD_STR; 524 edac_dev->ctl_name = pdata->name; 525 if (edac_op_state == EDAC_OPSTATE_POLL) 526 edac_dev->edac_check = mv64x60_cpu_check; 527 528 pdata->edac_idx = edac_dev_idx++; 529 530 if (edac_device_add_device(edac_dev) > 0) { 531 edac_dbg(3, "failed edac_device_add_device()\n"); 532 goto err; 533 } 534 535 if (edac_op_state == EDAC_OPSTATE_INT) { 536 pdata->irq = platform_get_irq(pdev, 0); 537 res = devm_request_irq(&pdev->dev, 538 pdata->irq, 539 mv64x60_cpu_isr, 540 0, 541 "[EDAC] CPU err", 542 edac_dev); 543 if (res < 0) { 544 printk(KERN_ERR 545 "%s: Unable to request irq %d for MV64x60 " 546 "CPU ERR\n", __func__, pdata->irq); 547 res = -ENODEV; 548 goto err2; 549 } 550 551 printk(KERN_INFO EDAC_MOD_STR 552 " acquired irq %d for CPU Err\n", pdata->irq); 553 } 554 555 devres_remove_group(&pdev->dev, mv64x60_cpu_err_probe); 556 557 /* get this far and it's successful */ 558 edac_dbg(3, "success\n"); 559 560 return 0; 561 562err2: 563 edac_device_del_device(&pdev->dev); 564err: 565 devres_release_group(&pdev->dev, mv64x60_cpu_err_probe); 566 edac_device_free_ctl_info(edac_dev); 567 return res; 568} 569 570static int mv64x60_cpu_err_remove(struct platform_device *pdev) 571{ 572 struct edac_device_ctl_info *edac_dev = platform_get_drvdata(pdev); 573 574 edac_dbg(0, "\n"); 575 576 edac_device_del_device(&pdev->dev); 577 edac_device_free_ctl_info(edac_dev); 578 return 0; 579} 580 581static struct platform_driver mv64x60_cpu_err_driver = { 582 .probe = mv64x60_cpu_err_probe, 583 .remove = mv64x60_cpu_err_remove, 584 .driver = { 585 .name = "mv64x60_cpu_err", 586 } 587}; 588 589/*********************** DRAM err device **********************************/ 590 591static void mv64x60_mc_check(struct mem_ctl_info *mci) 592{ 593 struct mv64x60_mc_pdata *pdata = mci->pvt_info; 594 u32 reg; 595 u32 err_addr; 596 u32 sdram_ecc; 597 u32 comp_ecc; 598 u32 syndrome; 599 600 reg = in_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR); 601 if (!reg) 602 return; 603 604 err_addr = reg & ~0x3; 605 sdram_ecc = in_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_RCVD); 606 comp_ecc = in_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CALC); 607 syndrome = sdram_ecc ^ comp_ecc; 608 609 /* first bit clear in ECC Err Reg, 1 bit error, correctable by HW */ 610 if (!(reg & 0x1)) 611 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 612 err_addr >> PAGE_SHIFT, 613 err_addr & PAGE_MASK, syndrome, 614 0, 0, -1, 615 mci->ctl_name, ""); 616 else /* 2 bit error, UE */ 617 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 618 err_addr >> PAGE_SHIFT, 619 err_addr & PAGE_MASK, 0, 620 0, 0, -1, 621 mci->ctl_name, ""); 622 623 /* clear the error */ 624 out_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR, 0); 625} 626 627static irqreturn_t mv64x60_mc_isr(int irq, void *dev_id) 628{ 629 struct mem_ctl_info *mci = dev_id; 630 struct mv64x60_mc_pdata *pdata = mci->pvt_info; 631 u32 reg; 632 633 reg = in_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR); 634 if (!reg) 635 return IRQ_NONE; 636 637 /* writing 0's to the ECC err addr in check function clears irq */ 638 mv64x60_mc_check(mci); 639 640 return IRQ_HANDLED; 641} 642 643static void get_total_mem(struct mv64x60_mc_pdata *pdata) 644{ 645 struct device_node *np = NULL; 646 const unsigned int *reg; 647 648 np = of_find_node_by_type(NULL, "memory"); 649 if (!np) 650 return; 651 652 reg = of_get_property(np, "reg", NULL); 653 654 pdata->total_mem = reg[1]; 655} 656 657static void mv64x60_init_csrows(struct mem_ctl_info *mci, 658 struct mv64x60_mc_pdata *pdata) 659{ 660 struct csrow_info *csrow; 661 struct dimm_info *dimm; 662 663 u32 devtype; 664 u32 ctl; 665 666 get_total_mem(pdata); 667 668 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG); 669 670 csrow = mci->csrows[0]; 671 dimm = csrow->channels[0]->dimm; 672 673 dimm->nr_pages = pdata->total_mem >> PAGE_SHIFT; 674 dimm->grain = 8; 675 676 dimm->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR; 677 678 devtype = (ctl >> 20) & 0x3; 679 switch (devtype) { 680 case 0x0: 681 dimm->dtype = DEV_X32; 682 break; 683 case 0x2: /* could be X8 too, but no way to tell */ 684 dimm->dtype = DEV_X16; 685 break; 686 case 0x3: 687 dimm->dtype = DEV_X4; 688 break; 689 default: 690 dimm->dtype = DEV_UNKNOWN; 691 break; 692 } 693 694 dimm->edac_mode = EDAC_SECDED; 695} 696 697static int mv64x60_mc_err_probe(struct platform_device *pdev) 698{ 699 struct mem_ctl_info *mci; 700 struct edac_mc_layer layers[2]; 701 struct mv64x60_mc_pdata *pdata; 702 struct resource *r; 703 u32 ctl; 704 int res = 0; 705 706 if (!devres_open_group(&pdev->dev, mv64x60_mc_err_probe, GFP_KERNEL)) 707 return -ENOMEM; 708 709 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; 710 layers[0].size = 1; 711 layers[0].is_virt_csrow = true; 712 layers[1].type = EDAC_MC_LAYER_CHANNEL; 713 layers[1].size = 1; 714 layers[1].is_virt_csrow = false; 715 mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers, 716 sizeof(struct mv64x60_mc_pdata)); 717 if (!mci) { 718 printk(KERN_ERR "%s: No memory for CPU err\n", __func__); 719 devres_release_group(&pdev->dev, mv64x60_mc_err_probe); 720 return -ENOMEM; 721 } 722 723 pdata = mci->pvt_info; 724 mci->pdev = &pdev->dev; 725 platform_set_drvdata(pdev, mci); 726 pdata->name = "mv64x60_mc_err"; 727 mci->dev_name = dev_name(&pdev->dev); 728 pdata->edac_idx = edac_mc_idx++; 729 730 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 731 if (!r) { 732 printk(KERN_ERR "%s: Unable to get resource for " 733 "MC err regs\n", __func__); 734 res = -ENOENT; 735 goto err; 736 } 737 738 if (!devm_request_mem_region(&pdev->dev, 739 r->start, 740 resource_size(r), 741 pdata->name)) { 742 printk(KERN_ERR "%s: Error while requesting mem region\n", 743 __func__); 744 res = -EBUSY; 745 goto err; 746 } 747 748 pdata->mc_vbase = devm_ioremap(&pdev->dev, 749 r->start, 750 resource_size(r)); 751 if (!pdata->mc_vbase) { 752 printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__); 753 res = -ENOMEM; 754 goto err; 755 } 756 757 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG); 758 if (!(ctl & MV64X60_SDRAM_ECC)) { 759 /* Non-ECC RAM? */ 760 printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__); 761 res = -ENODEV; 762 goto err2; 763 } 764 765 edac_dbg(3, "init mci\n"); 766 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; 767 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; 768 mci->edac_cap = EDAC_FLAG_SECDED; 769 mci->mod_name = EDAC_MOD_STR; 770 mci->mod_ver = MV64x60_REVISION; 771 mci->ctl_name = mv64x60_ctl_name; 772 773 if (edac_op_state == EDAC_OPSTATE_POLL) 774 mci->edac_check = mv64x60_mc_check; 775 776 mci->ctl_page_to_phys = NULL; 777 778 mci->scrub_mode = SCRUB_SW_SRC; 779 780 mv64x60_init_csrows(mci, pdata); 781 782 /* setup MC registers */ 783 out_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR, 0); 784 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CNTL); 785 ctl = (ctl & 0xff00ffff) | 0x10000; 786 out_le32(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CNTL, ctl); 787 788 res = edac_mc_add_mc(mci); 789 if (res) { 790 edac_dbg(3, "failed edac_mc_add_mc()\n"); 791 goto err; 792 } 793 794 if (edac_op_state == EDAC_OPSTATE_INT) { 795 /* acquire interrupt that reports errors */ 796 pdata->irq = platform_get_irq(pdev, 0); 797 res = devm_request_irq(&pdev->dev, 798 pdata->irq, 799 mv64x60_mc_isr, 800 0, 801 "[EDAC] MC err", 802 mci); 803 if (res < 0) { 804 printk(KERN_ERR "%s: Unable to request irq %d for " 805 "MV64x60 DRAM ERR\n", __func__, pdata->irq); 806 res = -ENODEV; 807 goto err2; 808 } 809 810 printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for MC Err\n", 811 pdata->irq); 812 } 813 814 /* get this far and it's successful */ 815 edac_dbg(3, "success\n"); 816 817 return 0; 818 819err2: 820 edac_mc_del_mc(&pdev->dev); 821err: 822 devres_release_group(&pdev->dev, mv64x60_mc_err_probe); 823 edac_mc_free(mci); 824 return res; 825} 826 827static int mv64x60_mc_err_remove(struct platform_device *pdev) 828{ 829 struct mem_ctl_info *mci = platform_get_drvdata(pdev); 830 831 edac_dbg(0, "\n"); 832 833 edac_mc_del_mc(&pdev->dev); 834 edac_mc_free(mci); 835 return 0; 836} 837 838static struct platform_driver mv64x60_mc_err_driver = { 839 .probe = mv64x60_mc_err_probe, 840 .remove = mv64x60_mc_err_remove, 841 .driver = { 842 .name = "mv64x60_mc_err", 843 } 844}; 845 846static struct platform_driver * const drivers[] = { 847 &mv64x60_mc_err_driver, 848 &mv64x60_cpu_err_driver, 849 &mv64x60_sram_err_driver, 850#ifdef CONFIG_PCI 851 &mv64x60_pci_err_driver, 852#endif 853}; 854 855static int __init mv64x60_edac_init(void) 856{ 857 int ret = 0; 858 859 printk(KERN_INFO "Marvell MV64x60 EDAC driver " MV64x60_REVISION "\n"); 860 printk(KERN_INFO "\t(C) 2006-2007 MontaVista Software\n"); 861 /* make sure error reporting method is sane */ 862 switch (edac_op_state) { 863 case EDAC_OPSTATE_POLL: 864 case EDAC_OPSTATE_INT: 865 break; 866 default: 867 edac_op_state = EDAC_OPSTATE_INT; 868 break; 869 } 870 871 return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 872} 873module_init(mv64x60_edac_init); 874 875static void __exit mv64x60_edac_exit(void) 876{ 877 platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 878} 879module_exit(mv64x60_edac_exit); 880 881MODULE_LICENSE("GPL"); 882MODULE_AUTHOR("Montavista Software, Inc."); 883module_param(edac_op_state, int, 0444); 884MODULE_PARM_DESC(edac_op_state, 885 "EDAC Error Reporting state: 0=Poll, 2=Interrupt");