diff options
Diffstat (limited to 'drivers/edac/i3000_edac.c')
-rw-r--r-- | drivers/edac/i3000_edac.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c index 3ccf3b5eecc3..62d961e68973 100644 --- a/drivers/edac/i3000_edac.c +++ b/drivers/edac/i3000_edac.c | |||
@@ -42,11 +42,23 @@ | |||
42 | * 0 Error channel 0/1 | 42 | * 0 Error channel 0/1 |
43 | */ | 43 | */ |
44 | #define I3000_DEAP_GRAIN (1 << 7) | 44 | #define I3000_DEAP_GRAIN (1 << 7) |
45 | #define I3000_DEAP_PFN(edeap, deap) ((((edeap) & 1) << (32 - PAGE_SHIFT)) \ | 45 | |
46 | | ((deap) >> PAGE_SHIFT)) | 46 | static inline unsigned long deap_pfn(u8 edeap, u32 deap) |
47 | #define I3000_DEAP_OFFSET(deap) ((deap) & ~(I3000_DEAP_GRAIN-1) & \ | 47 | { |
48 | ~PAGE_MASK) | 48 | deap >>= PAGE_SHIFT; |
49 | #define I3000_DEAP_CHANNEL(deap) ((deap) & 1) | 49 | deap |= (edeap & 1) << (32 - PAGE_SHIFT); |
50 | return deap; | ||
51 | } | ||
52 | |||
53 | static inline unsigned long deap_offset(u32 deap) | ||
54 | { | ||
55 | return deap & ~(I3000_DEAP_GRAIN - 1) & ~PAGE_MASK; | ||
56 | } | ||
57 | |||
58 | static inline int deap_channel(u32 deap) | ||
59 | { | ||
60 | return deap & 1; | ||
61 | } | ||
50 | 62 | ||
51 | #define I3000_DERRSYN 0x5c /* DRAM Error Syndrome (8b) | 63 | #define I3000_DERRSYN 0x5c /* DRAM Error Syndrome (8b) |
52 | * | 64 | * |
@@ -116,8 +128,16 @@ | |||
116 | * Others: reserved | 128 | * Others: reserved |
117 | */ | 129 | */ |
118 | #define I3000_C1DRA 0x188 /* Channel 1 DRAM Rank Attribute (8b x 2) */ | 130 | #define I3000_C1DRA 0x188 /* Channel 1 DRAM Rank Attribute (8b x 2) */ |
119 | #define ODD_RANK_ATTRIB(dra) (((dra) & 0x70) >> 4) | 131 | |
120 | #define EVEN_RANK_ATTRIB(dra) ((dra) & 0x07) | 132 | static inline unsigned char odd_rank_attrib(unsigned char dra) |
133 | { | ||
134 | return (dra & 0x70) >> 4; | ||
135 | } | ||
136 | |||
137 | static inline unsigned char even_rank_attrib(unsigned char dra) | ||
138 | { | ||
139 | return dra & 0x07; | ||
140 | } | ||
121 | 141 | ||
122 | #define I3000_C0DRC0 0x120 /* DRAM Controller Mode 0 (32b) | 142 | #define I3000_C0DRC0 0x120 /* DRAM Controller Mode 0 (32b) |
123 | * | 143 | * |
@@ -206,8 +226,8 @@ static int i3000_process_error_info(struct mem_ctl_info *mci, | |||
206 | struct i3000_error_info *info, | 226 | struct i3000_error_info *info, |
207 | int handle_errors) | 227 | int handle_errors) |
208 | { | 228 | { |
209 | int row, multi_chan; | 229 | int row, multi_chan, channel; |
210 | int pfn, offset, channel; | 230 | unsigned long pfn, offset; |
211 | 231 | ||
212 | multi_chan = mci->csrows[0].nr_channels - 1; | 232 | multi_chan = mci->csrows[0].nr_channels - 1; |
213 | 233 | ||
@@ -222,9 +242,9 @@ static int i3000_process_error_info(struct mem_ctl_info *mci, | |||
222 | info->errsts = info->errsts2; | 242 | info->errsts = info->errsts2; |
223 | } | 243 | } |
224 | 244 | ||
225 | pfn = I3000_DEAP_PFN(info->edeap, info->deap); | 245 | pfn = deap_pfn(info->edeap, info->deap); |
226 | offset = I3000_DEAP_OFFSET(info->deap); | 246 | offset = deap_offset(info->deap); |
227 | channel = I3000_DEAP_CHANNEL(info->deap); | 247 | channel = deap_channel(info->deap); |
228 | 248 | ||
229 | row = edac_mc_find_csrow_by_page(mci, pfn); | 249 | row = edac_mc_find_csrow_by_page(mci, pfn); |
230 | 250 | ||
@@ -258,9 +278,9 @@ static int i3000_is_interleaved(const unsigned char *c0dra, | |||
258 | * we're not interleaved. | 278 | * we're not interleaved. |
259 | */ | 279 | */ |
260 | for (i = 0; i < I3000_RANKS_PER_CHANNEL / 2; i++) | 280 | for (i = 0; i < I3000_RANKS_PER_CHANNEL / 2; i++) |
261 | if (ODD_RANK_ATTRIB(c0dra[i]) != ODD_RANK_ATTRIB(c1dra[i]) || | 281 | if (odd_rank_attrib(c0dra[i]) != odd_rank_attrib(c1dra[i]) || |
262 | EVEN_RANK_ATTRIB(c0dra[i]) != | 282 | even_rank_attrib(c0dra[i]) != |
263 | EVEN_RANK_ATTRIB(c1dra[i])) | 283 | even_rank_attrib(c1dra[i])) |
264 | return 0; | 284 | return 0; |
265 | 285 | ||
266 | /* | 286 | /* |