aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/amd64_edac.c43
-rw-r--r--drivers/edac/amd64_edac.h29
-rw-r--r--drivers/edac/amd64_edac_dbg.c89
-rw-r--r--drivers/edac/amd64_edac_inj.c128
4 files changed, 167 insertions, 122 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 821bc2cdd2de..9905834b560f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2463,26 +2463,29 @@ static bool ecc_enabled(struct pci_dev *F3, u8 nid)
2463 return true; 2463 return true;
2464} 2464}
2465 2465
2466struct mcidev_sysfs_attribute sysfs_attrs[ARRAY_SIZE(amd64_dbg_attrs) + 2466static int set_mc_sysfs_attrs(struct mem_ctl_info *mci)
2467 ARRAY_SIZE(amd64_inj_attrs) +
2468 1];
2469
2470struct mcidev_sysfs_attribute terminator = { .attr = { .name = NULL } };
2471
2472static void set_mc_sysfs_attrs(struct mem_ctl_info *mci)
2473{ 2467{
2474 unsigned int i = 0, j = 0; 2468 int rc;
2475 2469
2476 for (; i < ARRAY_SIZE(amd64_dbg_attrs); i++) 2470 rc = amd64_create_sysfs_dbg_files(mci);
2477 sysfs_attrs[i] = amd64_dbg_attrs[i]; 2471 if (rc < 0)
2472 return rc;
2478 2473
2479 if (boot_cpu_data.x86 >= 0x10) 2474 if (boot_cpu_data.x86 >= 0x10) {
2480 for (j = 0; j < ARRAY_SIZE(amd64_inj_attrs); j++, i++) 2475 rc = amd64_create_sysfs_inject_files(mci);
2481 sysfs_attrs[i] = amd64_inj_attrs[j]; 2476 if (rc < 0)
2477 return rc;
2478 }
2479
2480 return 0;
2481}
2482 2482
2483 sysfs_attrs[i] = terminator; 2483static void del_mc_sysfs_attrs(struct mem_ctl_info *mci)
2484{
2485 amd64_remove_sysfs_dbg_files(mci);
2484 2486
2485 mci->mc_driver_sysfs_attributes = sysfs_attrs; 2487 if (boot_cpu_data.x86 >= 0x10)
2488 amd64_remove_sysfs_inject_files(mci);
2486} 2489}
2487 2490
2488static void setup_mci_misc_attrs(struct mem_ctl_info *mci, 2491static void setup_mci_misc_attrs(struct mem_ctl_info *mci,
@@ -2608,13 +2611,15 @@ static int amd64_init_one_instance(struct pci_dev *F2)
2608 if (init_csrows(mci)) 2611 if (init_csrows(mci))
2609 mci->edac_cap = EDAC_FLAG_NONE; 2612 mci->edac_cap = EDAC_FLAG_NONE;
2610 2613
2611 set_mc_sysfs_attrs(mci);
2612
2613 ret = -ENODEV; 2614 ret = -ENODEV;
2614 if (edac_mc_add_mc(mci)) { 2615 if (edac_mc_add_mc(mci)) {
2615 debugf1("failed edac_mc_add_mc()\n"); 2616 debugf1("failed edac_mc_add_mc()\n");
2616 goto err_add_mc; 2617 goto err_add_mc;
2617 } 2618 }
2619 if (set_mc_sysfs_attrs(mci)) {
2620 debugf1("failed edac_mc_add_mc()\n");
2621 goto err_add_sysfs;
2622 }
2618 2623
2619 /* register stuff with EDAC MCE */ 2624 /* register stuff with EDAC MCE */
2620 if (report_gart_errors) 2625 if (report_gart_errors)
@@ -2628,6 +2633,8 @@ static int amd64_init_one_instance(struct pci_dev *F2)
2628 2633
2629 return 0; 2634 return 0;
2630 2635
2636err_add_sysfs:
2637 edac_mc_del_mc(mci->pdev);
2631err_add_mc: 2638err_add_mc:
2632 edac_mc_free(mci); 2639 edac_mc_free(mci);
2633 2640
@@ -2698,6 +2705,8 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev)
2698 struct pci_dev *F3 = node_to_amd_nb(nid)->misc; 2705 struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
2699 struct ecc_settings *s = ecc_stngs[nid]; 2706 struct ecc_settings *s = ecc_stngs[nid];
2700 2707
2708 mci = find_mci_by_dev(&pdev->dev);
2709 del_mc_sysfs_attrs(mci);
2701 /* Remove from EDAC CORE tracking list */ 2710 /* Remove from EDAC CORE tracking list */
2702 mci = edac_mc_del_mc(&pdev->dev); 2711 mci = edac_mc_del_mc(&pdev->dev);
2703 if (!mci) 2712 if (!mci)
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 9a666cb985b2..8d4804732bac 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -413,20 +413,33 @@ struct ecc_settings {
413}; 413};
414 414
415#ifdef CONFIG_EDAC_DEBUG 415#ifdef CONFIG_EDAC_DEBUG
416#define NUM_DBG_ATTRS 5 416int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci);
417void amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci);
418
417#else 419#else
418#define NUM_DBG_ATTRS 0 420static inline int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci)
421{
422 return 0;
423}
424static void inline amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci)
425{
426}
419#endif 427#endif
420 428
421#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION 429#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION
422#define NUM_INJ_ATTRS 5 430int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci);
431void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci);
432
423#else 433#else
424#define NUM_INJ_ATTRS 0 434static inline int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci)
435{
436 return 0;
437}
438static inline void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci)
439{
440}
425#endif 441#endif
426 442
427extern struct mcidev_sysfs_attribute amd64_dbg_attrs[NUM_DBG_ATTRS],
428 amd64_inj_attrs[NUM_INJ_ATTRS];
429
430/* 443/*
431 * Each of the PCI Device IDs types have their own set of hardware accessor 444 * Each of the PCI Device IDs types have their own set of hardware accessor
432 * functions and per device encoding/decoding logic. 445 * functions and per device encoding/decoding logic.
@@ -460,3 +473,5 @@ int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
460 473
461int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base, 474int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
462 u64 *hole_offset, u64 *hole_size); 475 u64 *hole_offset, u64 *hole_size);
476
477#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
diff --git a/drivers/edac/amd64_edac_dbg.c b/drivers/edac/amd64_edac_dbg.c
index e3562288f4ce..2c1bbf740605 100644
--- a/drivers/edac/amd64_edac_dbg.c
+++ b/drivers/edac/amd64_edac_dbg.c
@@ -1,8 +1,11 @@
1#include "amd64_edac.h" 1#include "amd64_edac.h"
2 2
3#define EDAC_DCT_ATTR_SHOW(reg) \ 3#define EDAC_DCT_ATTR_SHOW(reg) \
4static ssize_t amd64_##reg##_show(struct mem_ctl_info *mci, char *data) \ 4static ssize_t amd64_##reg##_show(struct device *dev, \
5 struct device_attribute *mattr, \
6 char *data) \
5{ \ 7{ \
8 struct mem_ctl_info *mci = to_mci(dev); \
6 struct amd64_pvt *pvt = mci->pvt_info; \ 9 struct amd64_pvt *pvt = mci->pvt_info; \
7 return sprintf(data, "0x%016llx\n", (u64)pvt->reg); \ 10 return sprintf(data, "0x%016llx\n", (u64)pvt->reg); \
8} 11}
@@ -12,8 +15,12 @@ EDAC_DCT_ATTR_SHOW(dbam0);
12EDAC_DCT_ATTR_SHOW(top_mem); 15EDAC_DCT_ATTR_SHOW(top_mem);
13EDAC_DCT_ATTR_SHOW(top_mem2); 16EDAC_DCT_ATTR_SHOW(top_mem2);
14 17
15static ssize_t amd64_hole_show(struct mem_ctl_info *mci, char *data) 18static ssize_t amd64_hole_show(struct device *dev,
19 struct device_attribute *mattr,
20 char *data)
16{ 21{
22 struct mem_ctl_info *mci = to_mci(dev);
23
17 u64 hole_base = 0; 24 u64 hole_base = 0;
18 u64 hole_offset = 0; 25 u64 hole_offset = 0;
19 u64 hole_size = 0; 26 u64 hole_size = 0;
@@ -27,46 +34,40 @@ static ssize_t amd64_hole_show(struct mem_ctl_info *mci, char *data)
27/* 34/*
28 * update NUM_DBG_ATTRS in case you add new members 35 * update NUM_DBG_ATTRS in case you add new members
29 */ 36 */
30struct mcidev_sysfs_attribute amd64_dbg_attrs[] = { 37static DEVICE_ATTR(dhar, S_IRUGO, amd64_dhar_show, NULL);
38static DEVICE_ATTR(dbam, S_IRUGO, amd64_dbam0_show, NULL);
39static DEVICE_ATTR(topmem, S_IRUGO, amd64_top_mem_show, NULL);
40static DEVICE_ATTR(topmem2, S_IRUGO, amd64_top_mem2_show, NULL);
41static DEVICE_ATTR(dram_hole, S_IRUGO, amd64_hole_show, NULL);
42
43int amd64_create_sysfs_dbg_files(struct mem_ctl_info *mci)
44{
45 int rc;
46
47 rc = device_create_file(&mci->dev, &dev_attr_dhar);
48 if (rc < 0)
49 return rc;
50 rc = device_create_file(&mci->dev, &dev_attr_dbam);
51 if (rc < 0)
52 return rc;
53 rc = device_create_file(&mci->dev, &dev_attr_topmem);
54 if (rc < 0)
55 return rc;
56 rc = device_create_file(&mci->dev, &dev_attr_topmem2);
57 if (rc < 0)
58 return rc;
59 rc = device_create_file(&mci->dev, &dev_attr_dram_hole);
60 if (rc < 0)
61 return rc;
31 62
32 { 63 return 0;
33 .attr = { 64}
34 .name = "dhar", 65
35 .mode = (S_IRUGO) 66void amd64_remove_sysfs_dbg_files(struct mem_ctl_info *mci)
36 }, 67{
37 .show = amd64_dhar_show, 68 device_remove_file(&mci->dev, &dev_attr_dhar);
38 .store = NULL, 69 device_remove_file(&mci->dev, &dev_attr_dbam);
39 }, 70 device_remove_file(&mci->dev, &dev_attr_topmem);
40 { 71 device_remove_file(&mci->dev, &dev_attr_topmem2);
41 .attr = { 72 device_remove_file(&mci->dev, &dev_attr_dram_hole);
42 .name = "dbam", 73}
43 .mode = (S_IRUGO)
44 },
45 .show = amd64_dbam0_show,
46 .store = NULL,
47 },
48 {
49 .attr = {
50 .name = "topmem",
51 .mode = (S_IRUGO)
52 },
53 .show = amd64_top_mem_show,
54 .store = NULL,
55 },
56 {
57 .attr = {
58 .name = "topmem2",
59 .mode = (S_IRUGO)
60 },
61 .show = amd64_top_mem2_show,
62 .store = NULL,
63 },
64 {
65 .attr = {
66 .name = "dram_hole",
67 .mode = (S_IRUGO)
68 },
69 .show = amd64_hole_show,
70 .store = NULL,
71 },
72};
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index 303f10e03dda..ef1ff4ea9576 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -1,7 +1,10 @@
1#include "amd64_edac.h" 1#include "amd64_edac.h"
2 2
3static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf) 3static ssize_t amd64_inject_section_show(struct device *dev,
4 struct device_attribute *mattr,
5 char *buf)
4{ 6{
7 struct mem_ctl_info *mci = to_mci(dev);
5 struct amd64_pvt *pvt = mci->pvt_info; 8 struct amd64_pvt *pvt = mci->pvt_info;
6 return sprintf(buf, "0x%x\n", pvt->injection.section); 9 return sprintf(buf, "0x%x\n", pvt->injection.section);
7} 10}
@@ -12,9 +15,11 @@ static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf)
12 * 15 *
13 * range: 0..3 16 * range: 0..3
14 */ 17 */
15static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci, 18static ssize_t amd64_inject_section_store(struct device *dev,
19 struct device_attribute *mattr,
16 const char *data, size_t count) 20 const char *data, size_t count)
17{ 21{
22 struct mem_ctl_info *mci = to_mci(dev);
18 struct amd64_pvt *pvt = mci->pvt_info; 23 struct amd64_pvt *pvt = mci->pvt_info;
19 unsigned long value; 24 unsigned long value;
20 int ret = 0; 25 int ret = 0;
@@ -33,8 +38,11 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
33 return ret; 38 return ret;
34} 39}
35 40
36static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf) 41static ssize_t amd64_inject_word_show(struct device *dev,
42 struct device_attribute *mattr,
43 char *buf)
37{ 44{
45 struct mem_ctl_info *mci = to_mci(dev);
38 struct amd64_pvt *pvt = mci->pvt_info; 46 struct amd64_pvt *pvt = mci->pvt_info;
39 return sprintf(buf, "0x%x\n", pvt->injection.word); 47 return sprintf(buf, "0x%x\n", pvt->injection.word);
40} 48}
@@ -45,9 +53,11 @@ static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf)
45 * 53 *
46 * range: 0..8 54 * range: 0..8
47 */ 55 */
48static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci, 56static ssize_t amd64_inject_word_store(struct device *dev,
49 const char *data, size_t count) 57 struct device_attribute *mattr,
58 const char *data, size_t count)
50{ 59{
60 struct mem_ctl_info *mci = to_mci(dev);
51 struct amd64_pvt *pvt = mci->pvt_info; 61 struct amd64_pvt *pvt = mci->pvt_info;
52 unsigned long value; 62 unsigned long value;
53 int ret = 0; 63 int ret = 0;
@@ -66,8 +76,11 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
66 return ret; 76 return ret;
67} 77}
68 78
69static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf) 79static ssize_t amd64_inject_ecc_vector_show(struct device *dev,
80 struct device_attribute *mattr,
81 char *buf)
70{ 82{
83 struct mem_ctl_info *mci = to_mci(dev);
71 struct amd64_pvt *pvt = mci->pvt_info; 84 struct amd64_pvt *pvt = mci->pvt_info;
72 return sprintf(buf, "0x%x\n", pvt->injection.bit_map); 85 return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
73} 86}
@@ -77,9 +90,11 @@ static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf)
77 * corresponding bit within the error injection word above. When used during a 90 * corresponding bit within the error injection word above. When used during a
78 * DRAM ECC read, it holds the contents of the of the DRAM ECC bits. 91 * DRAM ECC read, it holds the contents of the of the DRAM ECC bits.
79 */ 92 */
80static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci, 93static ssize_t amd64_inject_ecc_vector_store(struct device *dev,
81 const char *data, size_t count) 94 struct device_attribute *mattr,
95 const char *data, size_t count)
82{ 96{
97 struct mem_ctl_info *mci = to_mci(dev);
83 struct amd64_pvt *pvt = mci->pvt_info; 98 struct amd64_pvt *pvt = mci->pvt_info;
84 unsigned long value; 99 unsigned long value;
85 int ret = 0; 100 int ret = 0;
@@ -103,9 +118,11 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
103 * Do a DRAM ECC read. Assemble staged values in the pvt area, format into 118 * Do a DRAM ECC read. Assemble staged values in the pvt area, format into
104 * fields needed by the injection registers and read the NB Array Data Port. 119 * fields needed by the injection registers and read the NB Array Data Port.
105 */ 120 */
106static ssize_t amd64_inject_read_store(struct mem_ctl_info *mci, 121static ssize_t amd64_inject_read_store(struct device *dev,
107 const char *data, size_t count) 122 struct device_attribute *mattr,
123 const char *data, size_t count)
108{ 124{
125 struct mem_ctl_info *mci = to_mci(dev);
109 struct amd64_pvt *pvt = mci->pvt_info; 126 struct amd64_pvt *pvt = mci->pvt_info;
110 unsigned long value; 127 unsigned long value;
111 u32 section, word_bits; 128 u32 section, word_bits;
@@ -136,9 +153,11 @@ static ssize_t amd64_inject_read_store(struct mem_ctl_info *mci,
136 * Do a DRAM ECC write. Assemble staged values in the pvt area and format into 153 * Do a DRAM ECC write. Assemble staged values in the pvt area and format into
137 * fields needed by the injection registers. 154 * fields needed by the injection registers.
138 */ 155 */
139static ssize_t amd64_inject_write_store(struct mem_ctl_info *mci, 156static ssize_t amd64_inject_write_store(struct device *dev,
157 struct device_attribute *mattr,
140 const char *data, size_t count) 158 const char *data, size_t count)
141{ 159{
160 struct mem_ctl_info *mci = to_mci(dev);
142 struct amd64_pvt *pvt = mci->pvt_info; 161 struct amd64_pvt *pvt = mci->pvt_info;
143 unsigned long value; 162 unsigned long value;
144 u32 section, word_bits; 163 u32 section, word_bits;
@@ -168,46 +187,47 @@ static ssize_t amd64_inject_write_store(struct mem_ctl_info *mci,
168/* 187/*
169 * update NUM_INJ_ATTRS in case you add new members 188 * update NUM_INJ_ATTRS in case you add new members
170 */ 189 */
171struct mcidev_sysfs_attribute amd64_inj_attrs[] = { 190
172 191static DEVICE_ATTR(inject_section, S_IRUGO | S_IWUSR,
173 { 192 amd64_inject_section_show, amd64_inject_section_store);
174 .attr = { 193static DEVICE_ATTR(inject_word, S_IRUGO | S_IWUSR,
175 .name = "inject_section", 194 amd64_inject_word_show, amd64_inject_word_store);
176 .mode = (S_IRUGO | S_IWUSR) 195static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR,
177 }, 196 amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store);
178 .show = amd64_inject_section_show, 197static DEVICE_ATTR(inject_write, S_IRUGO | S_IWUSR,
179 .store = amd64_inject_section_store, 198 NULL, amd64_inject_write_store);
180 }, 199static DEVICE_ATTR(inject_read, S_IRUGO | S_IWUSR,
181 { 200 NULL, amd64_inject_read_store);
182 .attr = { 201
183 .name = "inject_word", 202
184 .mode = (S_IRUGO | S_IWUSR) 203int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci)
185 }, 204{
186 .show = amd64_inject_word_show, 205 int rc;
187 .store = amd64_inject_word_store, 206
188 }, 207 rc = device_create_file(&mci->dev, &dev_attr_inject_section);
189 { 208 if (rc < 0)
190 .attr = { 209 return rc;
191 .name = "inject_ecc_vector", 210 rc = device_create_file(&mci->dev, &dev_attr_inject_word);
192 .mode = (S_IRUGO | S_IWUSR) 211 if (rc < 0)
193 }, 212 return rc;
194 .show = amd64_inject_ecc_vector_show, 213 rc = device_create_file(&mci->dev, &dev_attr_inject_ecc_vector);
195 .store = amd64_inject_ecc_vector_store, 214 if (rc < 0)
196 }, 215 return rc;
197 { 216 rc = device_create_file(&mci->dev, &dev_attr_inject_write);
198 .attr = { 217 if (rc < 0)
199 .name = "inject_write", 218 return rc;
200 .mode = (S_IRUGO | S_IWUSR) 219 rc = device_create_file(&mci->dev, &dev_attr_inject_read);
201 }, 220 if (rc < 0)
202 .show = NULL, 221 return rc;
203 .store = amd64_inject_write_store, 222
204 }, 223 return 0;
205 { 224}
206 .attr = { 225
207 .name = "inject_read", 226void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci)
208 .mode = (S_IRUGO | S_IWUSR) 227{
209 }, 228 device_remove_file(&mci->dev, &dev_attr_inject_section);
210 .show = NULL, 229 device_remove_file(&mci->dev, &dev_attr_inject_word);
211 .store = amd64_inject_read_store, 230 device_remove_file(&mci->dev, &dev_attr_inject_ecc_vector);
212 }, 231 device_remove_file(&mci->dev, &dev_attr_inject_write);
213}; 232 device_remove_file(&mci->dev, &dev_attr_inject_read);
233}