aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/sb_edac.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 17:24:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 17:24:40 -0400
commitf0f3680e50352c57b6cfc5b0d44d63bb0aa20f80 (patch)
tree2005ec90f9d90f25ceeba147dfe09db8c8036fa6 /drivers/edac/sb_edac.c
parent61e5191c9d96268746bd57ed55d035678a1a2cf9 (diff)
parenta4b4be3fd7a76021f67380b03d8bccebf067db72 (diff)
Merge branch 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac
Pull EDAC fixes from Mauro Carvalho Chehab: "A series of EDAC driver fixes. It also has one core fix at the documentation, and a rename patch, fixing the name of the struct that contains the rank information." * 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac: edac: rename channel_info to rank_info i5400_edac: Avoid calling pci_put_device() twice edac: i5100 ack error detection register after each read edac: i5100 fix erroneous define for M1Err edac: sb_edac: Fix a wrong value setting for the previous value edac: sb_edac: Fix a INTERLEAVE_MODE() misuse edac: sb_edac: Let the driver depend on PCI_MMCONFIG edac: Improve the comments to better describe the memory concepts edac/ppc4xx_edac: Fix compilation Fix sb_edac compilation with 32 bits kernels
Diffstat (limited to 'drivers/edac/sb_edac.c')
-rw-r--r--drivers/edac/sb_edac.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 3a605f777712..a203536d90dd 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -20,6 +20,7 @@
20#include <linux/mmzone.h> 20#include <linux/mmzone.h>
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/bitmap.h> 22#include <linux/bitmap.h>
23#include <linux/math64.h>
23#include <asm/processor.h> 24#include <asm/processor.h>
24#include <asm/mce.h> 25#include <asm/mce.h>
25 26
@@ -670,6 +671,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
670 u32 reg; 671 u32 reg;
671 u64 limit, prv = 0; 672 u64 limit, prv = 0;
672 u64 tmp_mb; 673 u64 tmp_mb;
674 u32 mb, kb;
673 u32 rir_way; 675 u32 rir_way;
674 676
675 /* 677 /*
@@ -682,8 +684,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
682 pvt->tolm = GET_TOLM(reg); 684 pvt->tolm = GET_TOLM(reg);
683 tmp_mb = (1 + pvt->tolm) >> 20; 685 tmp_mb = (1 + pvt->tolm) >> 20;
684 686
685 debugf0("TOLM: %Lu.%03Lu GB (0x%016Lx)\n", 687 mb = div_u64_rem(tmp_mb, 1000, &kb);
686 tmp_mb / 1000, tmp_mb % 1000, (u64)pvt->tolm); 688 debugf0("TOLM: %u.%03u GB (0x%016Lx)\n",
689 mb, kb, (u64)pvt->tolm);
687 690
688 /* Address range is already 45:25 */ 691 /* Address range is already 45:25 */
689 pci_read_config_dword(pvt->pci_sad1, TOHM, 692 pci_read_config_dword(pvt->pci_sad1, TOHM,
@@ -691,8 +694,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
691 pvt->tohm = GET_TOHM(reg); 694 pvt->tohm = GET_TOHM(reg);
692 tmp_mb = (1 + pvt->tohm) >> 20; 695 tmp_mb = (1 + pvt->tohm) >> 20;
693 696
694 debugf0("TOHM: %Lu.%03Lu GB (0x%016Lx)", 697 mb = div_u64_rem(tmp_mb, 1000, &kb);
695 tmp_mb / 1000, tmp_mb % 1000, (u64)pvt->tohm); 698 debugf0("TOHM: %u.%03u GB (0x%016Lx)",
699 mb, kb, (u64)pvt->tohm);
696 700
697 /* 701 /*
698 * Step 2) Get SAD range and SAD Interleave list 702 * Step 2) Get SAD range and SAD Interleave list
@@ -714,10 +718,11 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
714 break; 718 break;
715 719
716 tmp_mb = (limit + 1) >> 20; 720 tmp_mb = (limit + 1) >> 20;
717 debugf0("SAD#%d %s up to %Lu.%03Lu GB (0x%016Lx) %s reg=0x%08x\n", 721 mb = div_u64_rem(tmp_mb, 1000, &kb);
722 debugf0("SAD#%d %s up to %u.%03u GB (0x%016Lx) %s reg=0x%08x\n",
718 n_sads, 723 n_sads,
719 get_dram_attr(reg), 724 get_dram_attr(reg),
720 tmp_mb / 1000, tmp_mb % 1000, 725 mb, kb,
721 ((u64)tmp_mb) << 20L, 726 ((u64)tmp_mb) << 20L,
722 INTERLEAVE_MODE(reg) ? "Interleave: 8:6" : "Interleave: [8:6]XOR[18:16]", 727 INTERLEAVE_MODE(reg) ? "Interleave: 8:6" : "Interleave: [8:6]XOR[18:16]",
723 reg); 728 reg);
@@ -747,8 +752,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
747 break; 752 break;
748 tmp_mb = (limit + 1) >> 20; 753 tmp_mb = (limit + 1) >> 20;
749 754
750 debugf0("TAD#%d: up to %Lu.%03Lu GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n", 755 mb = div_u64_rem(tmp_mb, 1000, &kb);
751 n_tads, tmp_mb / 1000, tmp_mb % 1000, 756 debugf0("TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
757 n_tads, mb, kb,
752 ((u64)tmp_mb) << 20L, 758 ((u64)tmp_mb) << 20L,
753 (u32)TAD_SOCK(reg), 759 (u32)TAD_SOCK(reg),
754 (u32)TAD_CH(reg), 760 (u32)TAD_CH(reg),
@@ -757,7 +763,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
757 (u32)TAD_TGT2(reg), 763 (u32)TAD_TGT2(reg),
758 (u32)TAD_TGT3(reg), 764 (u32)TAD_TGT3(reg),
759 reg); 765 reg);
760 prv = tmp_mb; 766 prv = limit;
761 } 767 }
762 768
763 /* 769 /*
@@ -771,9 +777,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
771 tad_ch_nilv_offset[j], 777 tad_ch_nilv_offset[j],
772 &reg); 778 &reg);
773 tmp_mb = TAD_OFFSET(reg) >> 20; 779 tmp_mb = TAD_OFFSET(reg) >> 20;
774 debugf0("TAD CH#%d, offset #%d: %Lu.%03Lu GB (0x%016Lx), reg=0x%08x\n", 780 mb = div_u64_rem(tmp_mb, 1000, &kb);
781 debugf0("TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n",
775 i, j, 782 i, j,
776 tmp_mb / 1000, tmp_mb % 1000, 783 mb, kb,
777 ((u64)tmp_mb) << 20L, 784 ((u64)tmp_mb) << 20L,
778 reg); 785 reg);
779 } 786 }
@@ -795,9 +802,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
795 802
796 tmp_mb = RIR_LIMIT(reg) >> 20; 803 tmp_mb = RIR_LIMIT(reg) >> 20;
797 rir_way = 1 << RIR_WAY(reg); 804 rir_way = 1 << RIR_WAY(reg);
798 debugf0("CH#%d RIR#%d, limit: %Lu.%03Lu GB (0x%016Lx), way: %d, reg=0x%08x\n", 805 mb = div_u64_rem(tmp_mb, 1000, &kb);
806 debugf0("CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n",
799 i, j, 807 i, j,
800 tmp_mb / 1000, tmp_mb % 1000, 808 mb, kb,
801 ((u64)tmp_mb) << 20L, 809 ((u64)tmp_mb) << 20L,
802 rir_way, 810 rir_way,
803 reg); 811 reg);
@@ -808,9 +816,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
808 &reg); 816 &reg);
809 tmp_mb = RIR_OFFSET(reg) << 6; 817 tmp_mb = RIR_OFFSET(reg) << 6;
810 818
811 debugf0("CH#%d RIR#%d INTL#%d, offset %Lu.%03Lu GB (0x%016Lx), tgt: %d, reg=0x%08x\n", 819 mb = div_u64_rem(tmp_mb, 1000, &kb);
820 debugf0("CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
812 i, j, k, 821 i, j, k,
813 tmp_mb / 1000, tmp_mb % 1000, 822 mb, kb,
814 ((u64)tmp_mb) << 20L, 823 ((u64)tmp_mb) << 20L,
815 (u32)RIR_RNK_TGT(reg), 824 (u32)RIR_RNK_TGT(reg),
816 reg); 825 reg);
@@ -848,6 +857,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
848 u8 ch_way,sck_way; 857 u8 ch_way,sck_way;
849 u32 tad_offset; 858 u32 tad_offset;
850 u32 rir_way; 859 u32 rir_way;
860 u32 mb, kb;
851 u64 ch_addr, offset, limit, prv = 0; 861 u64 ch_addr, offset, limit, prv = 0;
852 862
853 863
@@ -858,7 +868,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
858 * range (e. g. VGA addresses). It is unlikely, however, that the 868 * range (e. g. VGA addresses). It is unlikely, however, that the
859 * memory controller would generate an error on that range. 869 * memory controller would generate an error on that range.
860 */ 870 */
861 if ((addr > (u64) pvt->tolm) && (addr < (1L << 32))) { 871 if ((addr > (u64) pvt->tolm) && (addr < (1LL << 32))) {
862 sprintf(msg, "Error at TOLM area, on addr 0x%08Lx", addr); 872 sprintf(msg, "Error at TOLM area, on addr 0x%08Lx", addr);
863 edac_mc_handle_ce_no_info(mci, msg); 873 edac_mc_handle_ce_no_info(mci, msg);
864 return -EINVAL; 874 return -EINVAL;
@@ -913,7 +923,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
913 addr, 923 addr,
914 limit, 924 limit,
915 sad_way + 7, 925 sad_way + 7,
916 INTERLEAVE_MODE(reg) ? "" : "XOR[18:16]"); 926 interleave_mode ? "" : "XOR[18:16]");
917 if (interleave_mode) 927 if (interleave_mode)
918 idx = ((addr >> 6) ^ (addr >> 16)) & 7; 928 idx = ((addr >> 6) ^ (addr >> 16)) & 7;
919 else 929 else
@@ -1053,7 +1063,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
1053 ch_addr = addr & 0x7f; 1063 ch_addr = addr & 0x7f;
1054 /* Remove socket wayness and remove 6 bits */ 1064 /* Remove socket wayness and remove 6 bits */
1055 addr >>= 6; 1065 addr >>= 6;
1056 addr /= sck_xch; 1066 addr = div_u64(addr, sck_xch);
1057#if 0 1067#if 0
1058 /* Divide by channel way */ 1068 /* Divide by channel way */
1059 addr = addr / ch_way; 1069 addr = addr / ch_way;
@@ -1073,10 +1083,10 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
1073 continue; 1083 continue;
1074 1084
1075 limit = RIR_LIMIT(reg); 1085 limit = RIR_LIMIT(reg);
1076 1086 mb = div_u64_rem(limit >> 20, 1000, &kb);
1077 debugf0("RIR#%d, limit: %Lu.%03Lu GB (0x%016Lx), way: %d\n", 1087 debugf0("RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n",
1078 n_rir, 1088 n_rir,
1079 (limit >> 20) / 1000, (limit >> 20) % 1000, 1089 mb, kb,
1080 limit, 1090 limit,
1081 1 << RIR_WAY(reg)); 1091 1 << RIR_WAY(reg));
1082 if (ch_addr <= limit) 1092 if (ch_addr <= limit)