aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/cpc925_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/cpc925_edac.c')
-rw-r--r--drivers/edac/cpc925_edac.c67
1 files changed, 64 insertions, 3 deletions
diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c
index a687a0d16962..a774c0ddaf5b 100644
--- a/drivers/edac/cpc925_edac.c
+++ b/drivers/edac/cpc925_edac.c
@@ -90,6 +90,7 @@ enum apimask_bits {
90 ECC_MASK_ENABLE = (APIMASK_ECC_UE_H | APIMASK_ECC_CE_H | 90 ECC_MASK_ENABLE = (APIMASK_ECC_UE_H | APIMASK_ECC_CE_H |
91 APIMASK_ECC_UE_L | APIMASK_ECC_CE_L), 91 APIMASK_ECC_UE_L | APIMASK_ECC_CE_L),
92}; 92};
93#define APIMASK_ADI(n) CPC925_BIT(((n)+1))
93 94
94/************************************************************ 95/************************************************************
95 * Processor Interface Exception Register (APIEXCP) 96 * Processor Interface Exception Register (APIEXCP)
@@ -581,16 +582,73 @@ static void cpc925_mc_check(struct mem_ctl_info *mci)
581} 582}
582 583
583/******************** CPU err device********************************/ 584/******************** CPU err device********************************/
585static u32 cpc925_cpu_mask_disabled(void)
586{
587 struct device_node *cpus;
588 struct device_node *cpunode = NULL;
589 static u32 mask = 0;
590
591 /* use cached value if available */
592 if (mask != 0)
593 return mask;
594
595 mask = APIMASK_ADI0 | APIMASK_ADI1;
596
597 cpus = of_find_node_by_path("/cpus");
598 if (cpus == NULL) {
599 cpc925_printk(KERN_DEBUG, "No /cpus node !\n");
600 return 0;
601 }
602
603 while ((cpunode = of_get_next_child(cpus, cpunode)) != NULL) {
604 const u32 *reg = of_get_property(cpunode, "reg", NULL);
605
606 if (strcmp(cpunode->type, "cpu")) {
607 cpc925_printk(KERN_ERR, "Not a cpu node in /cpus: %s\n", cpunode->name);
608 continue;
609 }
610
611 if (reg == NULL || *reg > 2) {
612 cpc925_printk(KERN_ERR, "Bad reg value at %s\n", cpunode->full_name);
613 continue;
614 }
615
616 mask &= ~APIMASK_ADI(*reg);
617 }
618
619 if (mask != (APIMASK_ADI0 | APIMASK_ADI1)) {
620 /* We assume that each CPU sits on it's own PI and that
621 * for present CPUs the reg property equals to the PI
622 * interface id */
623 cpc925_printk(KERN_WARNING,
624 "Assuming PI id is equal to CPU MPIC id!\n");
625 }
626
627 of_node_put(cpunode);
628 of_node_put(cpus);
629
630 return mask;
631}
632
584/* Enable CPU Errors detection */ 633/* Enable CPU Errors detection */
585static void cpc925_cpu_init(struct cpc925_dev_info *dev_info) 634static void cpc925_cpu_init(struct cpc925_dev_info *dev_info)
586{ 635{
587 u32 apimask; 636 u32 apimask;
637 u32 cpumask;
588 638
589 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET); 639 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
590 if ((apimask & CPU_MASK_ENABLE) == 0) { 640
591 apimask |= CPU_MASK_ENABLE; 641 cpumask = cpc925_cpu_mask_disabled();
592 __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET); 642 if (apimask & cpumask) {
643 cpc925_printk(KERN_WARNING, "CPU(s) not present, "
644 "but enabled in APIMASK, disabling\n");
645 apimask &= ~cpumask;
593 } 646 }
647
648 if ((apimask & CPU_MASK_ENABLE) == 0)
649 apimask |= CPU_MASK_ENABLE;
650
651 __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET);
594} 652}
595 653
596/* Disable CPU Errors detection */ 654/* Disable CPU Errors detection */
@@ -622,6 +680,9 @@ static void cpc925_cpu_check(struct edac_device_ctl_info *edac_dev)
622 if ((apiexcp & CPU_EXCP_DETECTED) == 0) 680 if ((apiexcp & CPU_EXCP_DETECTED) == 0)
623 return; 681 return;
624 682
683 if ((apiexcp & ~cpc925_cpu_mask_disabled()) == 0)
684 return;
685
625 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET); 686 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
626 cpc925_printk(KERN_INFO, "Processor Interface Fault\n" 687 cpc925_printk(KERN_INFO, "Processor Interface Fault\n"
627 "Processor Interface register dump:\n"); 688 "Processor Interface register dump:\n");