aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/cpc925_edac.c
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2011-06-16 22:51:47 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-01 02:00:18 -0400
commitce395088832bfd56bd28824b31a6a3685f3fd339 (patch)
tree9722b76bb97fa5ed5f06cd69f2b9e7d2ca33484c /drivers/edac/cpc925_edac.c
parent7bfb40b048aa709bb88a00a1acbadbd9f7a645ee (diff)
cpc925_edac: Support single-processor configurations
If second CPU is not enabled, CPC925 EDAC driver will spill out warnings about errors on second Processor Interface. Support masking that out, by detecting at runtime which CPUs are present in device tree. Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Cc: Harry Ciao <qingtao.cao@windriver.com> Cc: Doug Thompson <dougthompson@xmission.com> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
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");