diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/edac/pasemi_edac.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/edac/pasemi_edac.c')
-rw-r--r-- | drivers/edac/pasemi_edac.c | 65 |
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 | ||
75 | static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci) | 75 | static 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 | ||
96 | static void pasemi_edac_process_error_info(struct mem_ctl_info *mci, u32 errsta) | 96 | static 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 | ||
125 | static void pasemi_edac_check(struct mem_ctl_info *mci) | 124 | static 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 | ||
191 | static int pasemi_edac_probe(struct pci_dev *pdev, | 188 | static 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 | ||
269 | static void pasemi_edac_remove(struct pci_dev *pdev) | 260 | static 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); | |||
287 | static struct pci_driver pasemi_edac_driver = { | 278 | static 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 | ||