aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/pasemi_edac.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/edac/pasemi_edac.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/edac/pasemi_edac.c')
-rw-r--r--drivers/edac/pasemi_edac.c65
1 files changed, 28 insertions, 37 deletions
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 9c971b57553..7f71ee43674 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -74,7 +74,7 @@ static int system_mmc_id;
74 74
75static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci) 75static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci)
76{ 76{
77 struct pci_dev *pdev = to_pci_dev(mci->pdev); 77 struct pci_dev *pdev = to_pci_dev(mci->dev);
78 u32 tmp; 78 u32 tmp;
79 79
80 pci_read_config_dword(pdev, MCDEBUG_ERRSTA, 80 pci_read_config_dword(pdev, MCDEBUG_ERRSTA,
@@ -95,7 +95,7 @@ static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci)
95 95
96static void pasemi_edac_process_error_info(struct mem_ctl_info *mci, u32 errsta) 96static void pasemi_edac_process_error_info(struct mem_ctl_info *mci, u32 errsta)
97{ 97{
98 struct pci_dev *pdev = to_pci_dev(mci->pdev); 98 struct pci_dev *pdev = to_pci_dev(mci->dev);
99 u32 errlog1a; 99 u32 errlog1a;
100 u32 cs; 100 u32 cs;
101 101
@@ -110,16 +110,15 @@ static void pasemi_edac_process_error_info(struct mem_ctl_info *mci, u32 errsta)
110 /* uncorrectable/multi-bit errors */ 110 /* uncorrectable/multi-bit errors */
111 if (errsta & (MCDEBUG_ERRSTA_MBE_STATUS | 111 if (errsta & (MCDEBUG_ERRSTA_MBE_STATUS |
112 MCDEBUG_ERRSTA_RFL_STATUS)) { 112 MCDEBUG_ERRSTA_RFL_STATUS)) {
113 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 113 edac_mc_handle_ue(mci, mci->csrows[cs].first_page, 0,
114 mci->csrows[cs]->first_page, 0, 0, 114 cs, mci->ctl_name);
115 cs, 0, -1, mci->ctl_name, "");
116 } 115 }
117 116
118 /* correctable/single-bit errors */ 117 /* correctable/single-bit errors */
119 if (errsta & MCDEBUG_ERRSTA_SBE_STATUS) 118 if (errsta & MCDEBUG_ERRSTA_SBE_STATUS) {
120 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 119 edac_mc_handle_ce(mci, mci->csrows[cs].first_page, 0,
121 mci->csrows[cs]->first_page, 0, 0, 120 0, cs, 0, mci->ctl_name);
122 cs, 0, -1, mci->ctl_name, ""); 121 }
123} 122}
124 123
125static void pasemi_edac_check(struct mem_ctl_info *mci) 124static void pasemi_edac_check(struct mem_ctl_info *mci)
@@ -136,13 +135,11 @@ static int pasemi_edac_init_csrows(struct mem_ctl_info *mci,
136 enum edac_type edac_mode) 135 enum edac_type edac_mode)
137{ 136{
138 struct csrow_info *csrow; 137 struct csrow_info *csrow;
139 struct dimm_info *dimm;
140 u32 rankcfg; 138 u32 rankcfg;
141 int index; 139 int index;
142 140
143 for (index = 0; index < mci->nr_csrows; index++) { 141 for (index = 0; index < mci->nr_csrows; index++) {
144 csrow = mci->csrows[index]; 142 csrow = &mci->csrows[index];
145 dimm = csrow->channels[0]->dimm;
146 143
147 pci_read_config_dword(pdev, 144 pci_read_config_dword(pdev,
148 MCDRAM_RANKCFG + (index * 12), 145 MCDRAM_RANKCFG + (index * 12),
@@ -154,20 +151,20 @@ static int pasemi_edac_init_csrows(struct mem_ctl_info *mci,
154 switch ((rankcfg & MCDRAM_RANKCFG_TYPE_SIZE_M) >> 151 switch ((rankcfg & MCDRAM_RANKCFG_TYPE_SIZE_M) >>
155 MCDRAM_RANKCFG_TYPE_SIZE_S) { 152 MCDRAM_RANKCFG_TYPE_SIZE_S) {
156 case 0: 153 case 0:
157 dimm->nr_pages = 128 << (20 - PAGE_SHIFT); 154 csrow->nr_pages = 128 << (20 - PAGE_SHIFT);
158 break; 155 break;
159 case 1: 156 case 1:
160 dimm->nr_pages = 256 << (20 - PAGE_SHIFT); 157 csrow->nr_pages = 256 << (20 - PAGE_SHIFT);
161 break; 158 break;
162 case 2: 159 case 2:
163 case 3: 160 case 3:
164 dimm->nr_pages = 512 << (20 - PAGE_SHIFT); 161 csrow->nr_pages = 512 << (20 - PAGE_SHIFT);
165 break; 162 break;
166 case 4: 163 case 4:
167 dimm->nr_pages = 1024 << (20 - PAGE_SHIFT); 164 csrow->nr_pages = 1024 << (20 - PAGE_SHIFT);
168 break; 165 break;
169 case 5: 166 case 5:
170 dimm->nr_pages = 2048 << (20 - PAGE_SHIFT); 167 csrow->nr_pages = 2048 << (20 - PAGE_SHIFT);
171 break; 168 break;
172 default: 169 default:
173 edac_mc_printk(mci, KERN_ERR, 170 edac_mc_printk(mci, KERN_ERR,
@@ -177,22 +174,21 @@ static int pasemi_edac_init_csrows(struct mem_ctl_info *mci,
177 } 174 }
178 175
179 csrow->first_page = last_page_in_mmc; 176 csrow->first_page = last_page_in_mmc;
180 csrow->last_page = csrow->first_page + dimm->nr_pages - 1; 177 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
181 last_page_in_mmc += dimm->nr_pages; 178 last_page_in_mmc += csrow->nr_pages;
182 csrow->page_mask = 0; 179 csrow->page_mask = 0;
183 dimm->grain = PASEMI_EDAC_ERROR_GRAIN; 180 csrow->grain = PASEMI_EDAC_ERROR_GRAIN;
184 dimm->mtype = MEM_DDR; 181 csrow->mtype = MEM_DDR;
185 dimm->dtype = DEV_UNKNOWN; 182 csrow->dtype = DEV_UNKNOWN;
186 dimm->edac_mode = edac_mode; 183 csrow->edac_mode = edac_mode;
187 } 184 }
188 return 0; 185 return 0;
189} 186}
190 187
191static int pasemi_edac_probe(struct pci_dev *pdev, 188static int __devinit pasemi_edac_probe(struct pci_dev *pdev,
192 const struct pci_device_id *ent) 189 const struct pci_device_id *ent)
193{ 190{
194 struct mem_ctl_info *mci = NULL; 191 struct mem_ctl_info *mci = NULL;
195 struct edac_mc_layer layers[2];
196 u32 errctl1, errcor, scrub, mcen; 192 u32 errctl1, errcor, scrub, mcen;
197 193
198 pci_read_config_dword(pdev, MCCFG_MCEN, &mcen); 194 pci_read_config_dword(pdev, MCCFG_MCEN, &mcen);
@@ -209,14 +205,9 @@ static int pasemi_edac_probe(struct pci_dev *pdev,
209 MCDEBUG_ERRCTL1_RFL_LOG_EN; 205 MCDEBUG_ERRCTL1_RFL_LOG_EN;
210 pci_write_config_dword(pdev, MCDEBUG_ERRCTL1, errctl1); 206 pci_write_config_dword(pdev, MCDEBUG_ERRCTL1, errctl1);
211 207
212 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; 208 mci = edac_mc_alloc(0, PASEMI_EDAC_NR_CSROWS, PASEMI_EDAC_NR_CHANS,
213 layers[0].size = PASEMI_EDAC_NR_CSROWS; 209 system_mmc_id++);
214 layers[0].is_virt_csrow = true; 210
215 layers[1].type = EDAC_MC_LAYER_CHANNEL;
216 layers[1].size = PASEMI_EDAC_NR_CHANS;
217 layers[1].is_virt_csrow = false;
218 mci = edac_mc_alloc(system_mmc_id++, ARRAY_SIZE(layers), layers,
219 0);
220 if (mci == NULL) 211 if (mci == NULL)
221 return -ENOMEM; 212 return -ENOMEM;
222 213
@@ -225,7 +216,7 @@ static int pasemi_edac_probe(struct pci_dev *pdev,
225 MCCFG_ERRCOR_ECC_GEN_EN | 216 MCCFG_ERRCOR_ECC_GEN_EN |
226 MCCFG_ERRCOR_ECC_CRR_EN; 217 MCCFG_ERRCOR_ECC_CRR_EN;
227 218
228 mci->pdev = &pdev->dev; 219 mci->dev = &pdev->dev;
229 mci->mtype_cap = MEM_FLAG_DDR | MEM_FLAG_RDDR; 220 mci->mtype_cap = MEM_FLAG_DDR | MEM_FLAG_RDDR;
230 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; 221 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
231 mci->edac_cap = (errcor & MCCFG_ERRCOR_ECC_GEN_EN) ? 222 mci->edac_cap = (errcor & MCCFG_ERRCOR_ECC_GEN_EN) ?
@@ -266,7 +257,7 @@ fail:
266 return -ENODEV; 257 return -ENODEV;
267} 258}
268 259
269static void pasemi_edac_remove(struct pci_dev *pdev) 260static void __devexit pasemi_edac_remove(struct pci_dev *pdev)
270{ 261{
271 struct mem_ctl_info *mci = edac_mc_del_mc(&pdev->dev); 262 struct mem_ctl_info *mci = edac_mc_del_mc(&pdev->dev);
272 263
@@ -287,7 +278,7 @@ MODULE_DEVICE_TABLE(pci, pasemi_edac_pci_tbl);
287static struct pci_driver pasemi_edac_driver = { 278static struct pci_driver pasemi_edac_driver = {
288 .name = MODULE_NAME, 279 .name = MODULE_NAME,
289 .probe = pasemi_edac_probe, 280 .probe = pasemi_edac_probe,
290 .remove = pasemi_edac_remove, 281 .remove = __devexit_p(pasemi_edac_remove),
291 .id_table = pasemi_edac_pci_tbl, 282 .id_table = pasemi_edac_pci_tbl,
292}; 283};
293 284