aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/mpc85xx_edac.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-07-29 20:11:05 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-29 20:11:05 -0400
commitc2078e4c9120e7b38b1a02cd9fc6dd4f792110bf (patch)
treea30b29c0bf8cf2288a32ceaeb75013cb0b5d5865 /drivers/edac/mpc85xx_edac.c
parent73bcc49959e4e40911dd0dd634bf1b353827df66 (diff)
parentf58d0dee07fe6328f775669eb6aa3a123efad6c2 (diff)
Merge branch 'devel'
* devel: (33 commits) edac i5000, i5400: fix pointer math in i5000_get_mc_regs() edac: allow specifying the error count with fake_inject edac: add support for Calxeda highbank L2 cache ecc edac: add support for Calxeda highbank memory controller edac: create top-level debugfs directory sb_edac: properly handle error count i7core_edac: properly handle error count edac: edac_mc_handle_error(): add an error_count parameter edac: remove arch-specific parameter for the error handler amd64_edac: Don't pass driver name as an error parameter edac_mc: check for allocation failure in edac_mc_alloc() edac: Increase version to 3.0.0 edac_mc: Cleanup per-dimm_info debug messages edac: Convert debugfX to edac_dbg(X, edac: Use more normal debugging macro style edac: Don't add __func__ or __FILE__ for debugf[0-9] msgs Edac: Add ABI Documentation for the new device nodes edac: move documentation ABI to ABI/testing/sysfs-devices-edac i7core_edac: change the mem allocation scheme to make Documentation/kobject.txt happy edac: change the mem allocation scheme to make Documentation/kobject.txt happy ...
Diffstat (limited to 'drivers/edac/mpc85xx_edac.c')
-rw-r--r--drivers/edac/mpc85xx_edac.c131
1 files changed, 74 insertions, 57 deletions
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 0e374625f6f8..a1e791ec25d3 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -49,34 +49,45 @@ static u32 orig_hid1[2];
49 49
50/************************ MC SYSFS parts ***********************************/ 50/************************ MC SYSFS parts ***********************************/
51 51
52static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci, 52#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
53
54static ssize_t mpc85xx_mc_inject_data_hi_show(struct device *dev,
55 struct device_attribute *mattr,
53 char *data) 56 char *data)
54{ 57{
58 struct mem_ctl_info *mci = to_mci(dev);
55 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 59 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
56 return sprintf(data, "0x%08x", 60 return sprintf(data, "0x%08x",
57 in_be32(pdata->mc_vbase + 61 in_be32(pdata->mc_vbase +
58 MPC85XX_MC_DATA_ERR_INJECT_HI)); 62 MPC85XX_MC_DATA_ERR_INJECT_HI));
59} 63}
60 64
61static ssize_t mpc85xx_mc_inject_data_lo_show(struct mem_ctl_info *mci, 65static ssize_t mpc85xx_mc_inject_data_lo_show(struct device *dev,
66 struct device_attribute *mattr,
62 char *data) 67 char *data)
63{ 68{
69 struct mem_ctl_info *mci = to_mci(dev);
64 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 70 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
65 return sprintf(data, "0x%08x", 71 return sprintf(data, "0x%08x",
66 in_be32(pdata->mc_vbase + 72 in_be32(pdata->mc_vbase +
67 MPC85XX_MC_DATA_ERR_INJECT_LO)); 73 MPC85XX_MC_DATA_ERR_INJECT_LO));
68} 74}
69 75
70static ssize_t mpc85xx_mc_inject_ctrl_show(struct mem_ctl_info *mci, char *data) 76static ssize_t mpc85xx_mc_inject_ctrl_show(struct device *dev,
77 struct device_attribute *mattr,
78 char *data)
71{ 79{
80 struct mem_ctl_info *mci = to_mci(dev);
72 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 81 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
73 return sprintf(data, "0x%08x", 82 return sprintf(data, "0x%08x",
74 in_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT)); 83 in_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT));
75} 84}
76 85
77static ssize_t mpc85xx_mc_inject_data_hi_store(struct mem_ctl_info *mci, 86static ssize_t mpc85xx_mc_inject_data_hi_store(struct device *dev,
87 struct device_attribute *mattr,
78 const char *data, size_t count) 88 const char *data, size_t count)
79{ 89{
90 struct mem_ctl_info *mci = to_mci(dev);
80 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 91 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
81 if (isdigit(*data)) { 92 if (isdigit(*data)) {
82 out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_HI, 93 out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_HI,
@@ -86,9 +97,11 @@ static ssize_t mpc85xx_mc_inject_data_hi_store(struct mem_ctl_info *mci,
86 return 0; 97 return 0;
87} 98}
88 99
89static ssize_t mpc85xx_mc_inject_data_lo_store(struct mem_ctl_info *mci, 100static ssize_t mpc85xx_mc_inject_data_lo_store(struct device *dev,
101 struct device_attribute *mattr,
90 const char *data, size_t count) 102 const char *data, size_t count)
91{ 103{
104 struct mem_ctl_info *mci = to_mci(dev);
92 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 105 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
93 if (isdigit(*data)) { 106 if (isdigit(*data)) {
94 out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_LO, 107 out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_LO,
@@ -98,9 +111,11 @@ static ssize_t mpc85xx_mc_inject_data_lo_store(struct mem_ctl_info *mci,
98 return 0; 111 return 0;
99} 112}
100 113
101static ssize_t mpc85xx_mc_inject_ctrl_store(struct mem_ctl_info *mci, 114static ssize_t mpc85xx_mc_inject_ctrl_store(struct device *dev,
102 const char *data, size_t count) 115 struct device_attribute *mattr,
116 const char *data, size_t count)
103{ 117{
118 struct mem_ctl_info *mci = to_mci(dev);
104 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 119 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
105 if (isdigit(*data)) { 120 if (isdigit(*data)) {
106 out_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT, 121 out_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT,
@@ -110,38 +125,35 @@ static ssize_t mpc85xx_mc_inject_ctrl_store(struct mem_ctl_info *mci,
110 return 0; 125 return 0;
111} 126}
112 127
113static struct mcidev_sysfs_attribute mpc85xx_mc_sysfs_attributes[] = { 128DEVICE_ATTR(inject_data_hi, S_IRUGO | S_IWUSR,
114 { 129 mpc85xx_mc_inject_data_hi_show, mpc85xx_mc_inject_data_hi_store);
115 .attr = { 130DEVICE_ATTR(inject_data_lo, S_IRUGO | S_IWUSR,
116 .name = "inject_data_hi", 131 mpc85xx_mc_inject_data_lo_show, mpc85xx_mc_inject_data_lo_store);
117 .mode = (S_IRUGO | S_IWUSR) 132DEVICE_ATTR(inject_ctrl, S_IRUGO | S_IWUSR,
118 }, 133 mpc85xx_mc_inject_ctrl_show, mpc85xx_mc_inject_ctrl_store);
119 .show = mpc85xx_mc_inject_data_hi_show,
120 .store = mpc85xx_mc_inject_data_hi_store},
121 {
122 .attr = {
123 .name = "inject_data_lo",
124 .mode = (S_IRUGO | S_IWUSR)
125 },
126 .show = mpc85xx_mc_inject_data_lo_show,
127 .store = mpc85xx_mc_inject_data_lo_store},
128 {
129 .attr = {
130 .name = "inject_ctrl",
131 .mode = (S_IRUGO | S_IWUSR)
132 },
133 .show = mpc85xx_mc_inject_ctrl_show,
134 .store = mpc85xx_mc_inject_ctrl_store},
135 134
136 /* End of list */ 135static int mpc85xx_create_sysfs_attributes(struct mem_ctl_info *mci)
137 { 136{
138 .attr = {.name = NULL} 137 int rc;
139 } 138
140}; 139 rc = device_create_file(&mci->dev, &dev_attr_inject_data_hi);
140 if (rc < 0)
141 return rc;
142 rc = device_create_file(&mci->dev, &dev_attr_inject_data_lo);
143 if (rc < 0)
144 return rc;
145 rc = device_create_file(&mci->dev, &dev_attr_inject_ctrl);
146 if (rc < 0)
147 return rc;
141 148
142static void mpc85xx_set_mc_sysfs_attributes(struct mem_ctl_info *mci) 149 return 0;
150}
151
152static void mpc85xx_remove_sysfs_attributes(struct mem_ctl_info *mci)
143{ 153{
144 mci->mc_driver_sysfs_attributes = mpc85xx_mc_sysfs_attributes; 154 device_remove_file(&mci->dev, &dev_attr_inject_data_hi);
155 device_remove_file(&mci->dev, &dev_attr_inject_data_lo);
156 device_remove_file(&mci->dev, &dev_attr_inject_ctrl);
145} 157}
146 158
147/**************************** PCI Err device ***************************/ 159/**************************** PCI Err device ***************************/
@@ -268,7 +280,7 @@ static int __devinit mpc85xx_pci_err_probe(struct platform_device *op)
268 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0); 280 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);
269 281
270 if (edac_pci_add_device(pci, pdata->edac_idx) > 0) { 282 if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
271 debugf3("%s(): failed edac_pci_add_device()\n", __func__); 283 edac_dbg(3, "failed edac_pci_add_device()\n");
272 goto err; 284 goto err;
273 } 285 }
274 286
@@ -291,7 +303,7 @@ static int __devinit mpc85xx_pci_err_probe(struct platform_device *op)
291 } 303 }
292 304
293 devres_remove_group(&op->dev, mpc85xx_pci_err_probe); 305 devres_remove_group(&op->dev, mpc85xx_pci_err_probe);
294 debugf3("%s(): success\n", __func__); 306 edac_dbg(3, "success\n");
295 printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n"); 307 printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n");
296 308
297 return 0; 309 return 0;
@@ -309,7 +321,7 @@ static int mpc85xx_pci_err_remove(struct platform_device *op)
309 struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev); 321 struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
310 struct mpc85xx_pci_pdata *pdata = pci->pvt_info; 322 struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
311 323
312 debugf0("%s()\n", __func__); 324 edac_dbg(0, "\n");
313 325
314 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 326 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR,
315 orig_pci_err_cap_dr); 327 orig_pci_err_cap_dr);
@@ -570,7 +582,7 @@ static int __devinit mpc85xx_l2_err_probe(struct platform_device *op)
570 pdata->edac_idx = edac_dev_idx++; 582 pdata->edac_idx = edac_dev_idx++;
571 583
572 if (edac_device_add_device(edac_dev) > 0) { 584 if (edac_device_add_device(edac_dev) > 0) {
573 debugf3("%s(): failed edac_device_add_device()\n", __func__); 585 edac_dbg(3, "failed edac_device_add_device()\n");
574 goto err; 586 goto err;
575 } 587 }
576 588
@@ -598,7 +610,7 @@ static int __devinit mpc85xx_l2_err_probe(struct platform_device *op)
598 610
599 devres_remove_group(&op->dev, mpc85xx_l2_err_probe); 611 devres_remove_group(&op->dev, mpc85xx_l2_err_probe);
600 612
601 debugf3("%s(): success\n", __func__); 613 edac_dbg(3, "success\n");
602 printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n"); 614 printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n");
603 615
604 return 0; 616 return 0;
@@ -616,7 +628,7 @@ static int mpc85xx_l2_err_remove(struct platform_device *op)
616 struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev); 628 struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
617 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info; 629 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
618 630
619 debugf0("%s()\n", __func__); 631 edac_dbg(0, "\n");
620 632
621 if (edac_op_state == EDAC_OPSTATE_INT) { 633 if (edac_op_state == EDAC_OPSTATE_INT) {
622 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0); 634 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0);
@@ -813,7 +825,7 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
813 pfn = err_addr >> PAGE_SHIFT; 825 pfn = err_addr >> PAGE_SHIFT;
814 826
815 for (row_index = 0; row_index < mci->nr_csrows; row_index++) { 827 for (row_index = 0; row_index < mci->nr_csrows; row_index++) {
816 csrow = &mci->csrows[row_index]; 828 csrow = mci->csrows[row_index];
817 if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page)) 829 if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page))
818 break; 830 break;
819 } 831 }
@@ -854,16 +866,16 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
854 mpc85xx_mc_printk(mci, KERN_ERR, "PFN out of range!\n"); 866 mpc85xx_mc_printk(mci, KERN_ERR, "PFN out of range!\n");
855 867
856 if (err_detect & DDR_EDE_SBE) 868 if (err_detect & DDR_EDE_SBE)
857 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 869 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
858 pfn, err_addr & ~PAGE_MASK, syndrome, 870 pfn, err_addr & ~PAGE_MASK, syndrome,
859 row_index, 0, -1, 871 row_index, 0, -1,
860 mci->ctl_name, "", NULL); 872 mci->ctl_name, "");
861 873
862 if (err_detect & DDR_EDE_MBE) 874 if (err_detect & DDR_EDE_MBE)
863 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 875 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
864 pfn, err_addr & ~PAGE_MASK, syndrome, 876 pfn, err_addr & ~PAGE_MASK, syndrome,
865 row_index, 0, -1, 877 row_index, 0, -1,
866 mci->ctl_name, "", NULL); 878 mci->ctl_name, "");
867 879
868 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, err_detect); 880 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, err_detect);
869} 881}
@@ -933,8 +945,8 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci)
933 u32 start; 945 u32 start;
934 u32 end; 946 u32 end;
935 947
936 csrow = &mci->csrows[index]; 948 csrow = mci->csrows[index];
937 dimm = csrow->channels[0].dimm; 949 dimm = csrow->channels[0]->dimm;
938 950
939 cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 + 951 cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +
940 (index * MPC85XX_MC_CS_BNDS_OFS)); 952 (index * MPC85XX_MC_CS_BNDS_OFS));
@@ -990,9 +1002,9 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op)
990 pdata = mci->pvt_info; 1002 pdata = mci->pvt_info;
991 pdata->name = "mpc85xx_mc_err"; 1003 pdata->name = "mpc85xx_mc_err";
992 pdata->irq = NO_IRQ; 1004 pdata->irq = NO_IRQ;
993 mci->dev = &op->dev; 1005 mci->pdev = &op->dev;
994 pdata->edac_idx = edac_mc_idx++; 1006 pdata->edac_idx = edac_mc_idx++;
995 dev_set_drvdata(mci->dev, mci); 1007 dev_set_drvdata(mci->pdev, mci);
996 mci->ctl_name = pdata->name; 1008 mci->ctl_name = pdata->name;
997 mci->dev_name = pdata->name; 1009 mci->dev_name = pdata->name;
998 1010
@@ -1026,7 +1038,7 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op)
1026 goto err; 1038 goto err;
1027 } 1039 }
1028 1040
1029 debugf3("%s(): init mci\n", __func__); 1041 edac_dbg(3, "init mci\n");
1030 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_RDDR2 | 1042 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_RDDR2 |
1031 MEM_FLAG_DDR | MEM_FLAG_DDR2; 1043 MEM_FLAG_DDR | MEM_FLAG_DDR2;
1032 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; 1044 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
@@ -1041,8 +1053,6 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op)
1041 1053
1042 mci->scrub_mode = SCRUB_SW_SRC; 1054 mci->scrub_mode = SCRUB_SW_SRC;
1043 1055
1044 mpc85xx_set_mc_sysfs_attributes(mci);
1045
1046 mpc85xx_init_csrows(mci); 1056 mpc85xx_init_csrows(mci);
1047 1057
1048 /* store the original error disable bits */ 1058 /* store the original error disable bits */
@@ -1054,7 +1064,13 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op)
1054 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0); 1064 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);
1055 1065
1056 if (edac_mc_add_mc(mci)) { 1066 if (edac_mc_add_mc(mci)) {
1057 debugf3("%s(): failed edac_mc_add_mc()\n", __func__); 1067 edac_dbg(3, "failed edac_mc_add_mc()\n");
1068 goto err;
1069 }
1070
1071 if (mpc85xx_create_sysfs_attributes(mci)) {
1072 edac_mc_del_mc(mci->pdev);
1073 edac_dbg(3, "failed edac_mc_add_mc()\n");
1058 goto err; 1074 goto err;
1059 } 1075 }
1060 1076
@@ -1088,7 +1104,7 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op)
1088 } 1104 }
1089 1105
1090 devres_remove_group(&op->dev, mpc85xx_mc_err_probe); 1106 devres_remove_group(&op->dev, mpc85xx_mc_err_probe);
1091 debugf3("%s(): success\n", __func__); 1107 edac_dbg(3, "success\n");
1092 printk(KERN_INFO EDAC_MOD_STR " MC err registered\n"); 1108 printk(KERN_INFO EDAC_MOD_STR " MC err registered\n");
1093 1109
1094 return 0; 1110 return 0;
@@ -1106,7 +1122,7 @@ static int mpc85xx_mc_err_remove(struct platform_device *op)
1106 struct mem_ctl_info *mci = dev_get_drvdata(&op->dev); 1122 struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
1107 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 1123 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
1108 1124
1109 debugf0("%s()\n", __func__); 1125 edac_dbg(0, "\n");
1110 1126
1111 if (edac_op_state == EDAC_OPSTATE_INT) { 1127 if (edac_op_state == EDAC_OPSTATE_INT) {
1112 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN, 0); 1128 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN, 0);
@@ -1117,6 +1133,7 @@ static int mpc85xx_mc_err_remove(struct platform_device *op)
1117 orig_ddr_err_disable); 1133 orig_ddr_err_disable);
1118 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe); 1134 out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe);
1119 1135
1136 mpc85xx_remove_sysfs_attributes(mci);
1120 edac_mc_del_mc(&op->dev); 1137 edac_mc_del_mc(&op->dev);
1121 edac_mc_free(mci); 1138 edac_mc_free(mci);
1122 return 0; 1139 return 0;