aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/amd64_edac.h17
-rw-r--r--drivers/edac/amd64_edac_inj.c112
2 files changed, 60 insertions, 69 deletions
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 8c4139647efc..19a12a4fbf45 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -267,18 +267,19 @@
267#define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7) 267#define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7)
268 268
269#define F10_NB_ARRAY_ADDR 0xB8 269#define F10_NB_ARRAY_ADDR 0xB8
270#define F10_NB_ARRAY_DRAM_ECC BIT(31) 270#define F10_NB_ARRAY_DRAM BIT(31)
271 271
272/* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */ 272/* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */
273#define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1) 273#define SET_NB_ARRAY_ADDR(section) (((section) & 0x3) << 1)
274 274
275#define F10_NB_ARRAY_DATA 0xBC 275#define F10_NB_ARRAY_DATA 0xBC
276#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \ 276#define SET_NB_DRAM_INJECTION_WRITE(inj) \
277 (BIT(((word) & 0xF) + 20) | \ 277 (BIT(((inj.word) & 0xF) + 20) | \
278 BIT(17) | bits) 278 BIT(17) | inj.bit_map)
279#define SET_NB_DRAM_INJECTION_READ(word, bits) \ 279#define SET_NB_DRAM_INJECTION_READ(inj) \
280 (BIT(((word) & 0xF) + 20) | \ 280 (BIT(((inj.word) & 0xF) + 20) | \
281 BIT(16) | bits) 281 BIT(16) | inj.bit_map)
282
282 283
283#define NBCAP 0xE8 284#define NBCAP 0xE8
284#define NBCAP_CHIPKILL BIT(4) 285#define NBCAP_CHIPKILL BIT(4)
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index 53d972e00dfb..8977e2fa61da 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -22,20 +22,19 @@ static ssize_t amd64_inject_section_store(struct device *dev,
22 struct mem_ctl_info *mci = to_mci(dev); 22 struct mem_ctl_info *mci = to_mci(dev);
23 struct amd64_pvt *pvt = mci->pvt_info; 23 struct amd64_pvt *pvt = mci->pvt_info;
24 unsigned long value; 24 unsigned long value;
25 int ret = 0; 25 int ret;
26 26
27 ret = strict_strtoul(data, 10, &value); 27 ret = strict_strtoul(data, 10, &value);
28 if (ret != -EINVAL) { 28 if (ret < 0)
29 return ret;
29 30
30 if (value > 3) { 31 if (value > 3) {
31 amd64_warn("%s: invalid section 0x%lx\n", __func__, value); 32 amd64_warn("%s: invalid section 0x%lx\n", __func__, value);
32 return -EINVAL; 33 return -EINVAL;
33 }
34
35 pvt->injection.section = (u32) value;
36 return count;
37 } 34 }
38 return ret; 35
36 pvt->injection.section = (u32) value;
37 return count;
39} 38}
40 39
41static ssize_t amd64_inject_word_show(struct device *dev, 40static ssize_t amd64_inject_word_show(struct device *dev,
@@ -60,20 +59,19 @@ static ssize_t amd64_inject_word_store(struct device *dev,
60 struct mem_ctl_info *mci = to_mci(dev); 59 struct mem_ctl_info *mci = to_mci(dev);
61 struct amd64_pvt *pvt = mci->pvt_info; 60 struct amd64_pvt *pvt = mci->pvt_info;
62 unsigned long value; 61 unsigned long value;
63 int ret = 0; 62 int ret;
64 63
65 ret = strict_strtoul(data, 10, &value); 64 ret = strict_strtoul(data, 10, &value);
66 if (ret != -EINVAL) { 65 if (ret < 0)
67 66 return ret;
68 if (value > 8) {
69 amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
70 return -EINVAL;
71 }
72 67
73 pvt->injection.word = (u32) value; 68 if (value > 8) {
74 return count; 69 amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
70 return -EINVAL;
75 } 71 }
76 return ret; 72
73 pvt->injection.word = (u32) value;
74 return count;
77} 75}
78 76
79static ssize_t amd64_inject_ecc_vector_show(struct device *dev, 77static ssize_t amd64_inject_ecc_vector_show(struct device *dev,
@@ -97,21 +95,19 @@ static ssize_t amd64_inject_ecc_vector_store(struct device *dev,
97 struct mem_ctl_info *mci = to_mci(dev); 95 struct mem_ctl_info *mci = to_mci(dev);
98 struct amd64_pvt *pvt = mci->pvt_info; 96 struct amd64_pvt *pvt = mci->pvt_info;
99 unsigned long value; 97 unsigned long value;
100 int ret = 0; 98 int ret;
101 99
102 ret = strict_strtoul(data, 16, &value); 100 ret = strict_strtoul(data, 16, &value);
103 if (ret != -EINVAL) { 101 if (ret < 0)
104 102 return ret;
105 if (value & 0xFFFF0000) {
106 amd64_warn("%s: invalid EccVector: 0x%lx\n",
107 __func__, value);
108 return -EINVAL;
109 }
110 103
111 pvt->injection.bit_map = (u32) value; 104 if (value & 0xFFFF0000) {
112 return count; 105 amd64_warn("%s: invalid EccVector: 0x%lx\n", __func__, value);
106 return -EINVAL;
113 } 107 }
114 return ret; 108
109 pvt->injection.bit_map = (u32) value;
110 return count;
115} 111}
116 112
117/* 113/*
@@ -126,28 +122,25 @@ static ssize_t amd64_inject_read_store(struct device *dev,
126 struct amd64_pvt *pvt = mci->pvt_info; 122 struct amd64_pvt *pvt = mci->pvt_info;
127 unsigned long value; 123 unsigned long value;
128 u32 section, word_bits; 124 u32 section, word_bits;
129 int ret = 0; 125 int ret;
130 126
131 ret = strict_strtoul(data, 10, &value); 127 ret = strict_strtoul(data, 10, &value);
132 if (ret != -EINVAL) { 128 if (ret < 0)
129 return ret;
133 130
134 /* Form value to choose 16-byte section of cacheline */ 131 /* Form value to choose 16-byte section of cacheline */
135 section = F10_NB_ARRAY_DRAM_ECC | 132 section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section);
136 SET_NB_ARRAY_ADDRESS(pvt->injection.section);
137 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
138 133
139 word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word, 134 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
140 pvt->injection.bit_map);
141 135
142 /* Issue 'word' and 'bit' along with the READ request */ 136 word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection);
143 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
144 137
145 edac_dbg(0, "section=0x%x word_bits=0x%x\n", 138 /* Issue 'word' and 'bit' along with the READ request */
146 section, word_bits); 139 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
147 140
148 return count; 141 edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits);
149 } 142
150 return ret; 143 return count;
151} 144}
152 145
153/* 146/*
@@ -162,28 +155,25 @@ static ssize_t amd64_inject_write_store(struct device *dev,
162 struct amd64_pvt *pvt = mci->pvt_info; 155 struct amd64_pvt *pvt = mci->pvt_info;
163 unsigned long value; 156 unsigned long value;
164 u32 section, word_bits; 157 u32 section, word_bits;
165 int ret = 0; 158 int ret;
166 159
167 ret = strict_strtoul(data, 10, &value); 160 ret = strict_strtoul(data, 10, &value);
168 if (ret != -EINVAL) { 161 if (ret < 0)
162 return ret;
169 163
170 /* Form value to choose 16-byte section of cacheline */ 164 /* Form value to choose 16-byte section of cacheline */
171 section = F10_NB_ARRAY_DRAM_ECC | 165 section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section);
172 SET_NB_ARRAY_ADDRESS(pvt->injection.section);
173 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
174 166
175 word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word, 167 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
176 pvt->injection.bit_map);
177 168
178 /* Issue 'word' and 'bit' along with the READ request */ 169 word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection);
179 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
180 170
181 edac_dbg(0, "section=0x%x word_bits=0x%x\n", 171 /* Issue 'word' and 'bit' along with the READ request */
182 section, word_bits); 172 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
183 173
184 return count; 174 edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits);
185 } 175
186 return ret; 176 return count;
187} 177}
188 178
189/* 179/*