Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/edac/amd8111_edac.c
15112 views
1
/*
2
* amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module
3
*
4
* Copyright (c) 2008 Wind River Systems, Inc.
5
*
6
* Authors: Cao Qingtao <[email protected]>
7
* Benjamin Walsh <[email protected]>
8
* Hu Yongqi <[email protected]>
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License version 2 as
12
* published by the Free Software Foundation.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
* See the GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
*/
23
24
#include <linux/module.h>
25
#include <linux/init.h>
26
#include <linux/interrupt.h>
27
#include <linux/bitops.h>
28
#include <linux/edac.h>
29
#include <linux/pci_ids.h>
30
#include <asm/io.h>
31
32
#include "edac_core.h"
33
#include "edac_module.h"
34
#include "amd8111_edac.h"
35
36
#define AMD8111_EDAC_REVISION " Ver: 1.0.0"
37
#define AMD8111_EDAC_MOD_STR "amd8111_edac"
38
39
#define PCI_DEVICE_ID_AMD_8111_PCI 0x7460
40
41
enum amd8111_edac_devs {
42
LPC_BRIDGE = 0,
43
};
44
45
enum amd8111_edac_pcis {
46
PCI_BRIDGE = 0,
47
};
48
49
/* Wrapper functions for accessing PCI configuration space */
50
static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
51
{
52
int ret;
53
54
ret = pci_read_config_dword(dev, reg, val32);
55
if (ret != 0)
56
printk(KERN_ERR AMD8111_EDAC_MOD_STR
57
" PCI Access Read Error at 0x%x\n", reg);
58
59
return ret;
60
}
61
62
static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8)
63
{
64
int ret;
65
66
ret = pci_read_config_byte(dev, reg, val8);
67
if (ret != 0)
68
printk(KERN_ERR AMD8111_EDAC_MOD_STR
69
" PCI Access Read Error at 0x%x\n", reg);
70
}
71
72
static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
73
{
74
int ret;
75
76
ret = pci_write_config_dword(dev, reg, val32);
77
if (ret != 0)
78
printk(KERN_ERR AMD8111_EDAC_MOD_STR
79
" PCI Access Write Error at 0x%x\n", reg);
80
}
81
82
static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8)
83
{
84
int ret;
85
86
ret = pci_write_config_byte(dev, reg, val8);
87
if (ret != 0)
88
printk(KERN_ERR AMD8111_EDAC_MOD_STR
89
" PCI Access Write Error at 0x%x\n", reg);
90
}
91
92
/*
93
* device-specific methods for amd8111 PCI Bridge Controller
94
*
95
* Error Reporting and Handling for amd8111 chipset could be found
96
* in its datasheet 3.1.2 section, P37
97
*/
98
static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info)
99
{
100
u32 val32;
101
struct pci_dev *dev = pci_info->dev;
102
103
/* First clear error detection flags on the host interface */
104
105
/* Clear SSE/SMA/STA flags in the global status register*/
106
edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
107
if (val32 & PCI_STSCMD_CLEAR_MASK)
108
edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
109
110
/* Clear CRC and Link Fail flags in HT Link Control reg */
111
edac_pci_read_dword(dev, REG_HT_LINK, &val32);
112
if (val32 & HT_LINK_CLEAR_MASK)
113
edac_pci_write_dword(dev, REG_HT_LINK, val32);
114
115
/* Second clear all fault on the secondary interface */
116
117
/* Clear error flags in the memory-base limit reg. */
118
edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
119
if (val32 & MEM_LIMIT_CLEAR_MASK)
120
edac_pci_write_dword(dev, REG_MEM_LIM, val32);
121
122
/* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */
123
edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
124
if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK)
125
edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
126
127
/* Last enable error detections */
128
if (edac_op_state == EDAC_OPSTATE_POLL) {
129
/* Enable System Error reporting in global status register */
130
edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
131
val32 |= PCI_STSCMD_SERREN;
132
edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
133
134
/* Enable CRC Sync flood packets to HyperTransport Link */
135
edac_pci_read_dword(dev, REG_HT_LINK, &val32);
136
val32 |= HT_LINK_CRCFEN;
137
edac_pci_write_dword(dev, REG_HT_LINK, val32);
138
139
/* Enable SSE reporting etc in Interrupt control reg */
140
edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
141
val32 |= PCI_INTBRG_CTRL_POLL_MASK;
142
edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
143
}
144
}
145
146
static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info)
147
{
148
u32 val32;
149
struct pci_dev *dev = pci_info->dev;
150
151
if (edac_op_state == EDAC_OPSTATE_POLL) {
152
/* Disable System Error reporting */
153
edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
154
val32 &= ~PCI_STSCMD_SERREN;
155
edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
156
157
/* Disable CRC flood packets */
158
edac_pci_read_dword(dev, REG_HT_LINK, &val32);
159
val32 &= ~HT_LINK_CRCFEN;
160
edac_pci_write_dword(dev, REG_HT_LINK, val32);
161
162
/* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */
163
edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
164
val32 &= ~PCI_INTBRG_CTRL_POLL_MASK;
165
edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
166
}
167
}
168
169
static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev)
170
{
171
struct amd8111_pci_info *pci_info = edac_dev->pvt_info;
172
struct pci_dev *dev = pci_info->dev;
173
u32 val32;
174
175
/* Check out PCI Bridge Status and Command Register */
176
edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
177
if (val32 & PCI_STSCMD_CLEAR_MASK) {
178
printk(KERN_INFO "Error(s) in PCI bridge status and command"
179
"register on device %s\n", pci_info->ctl_name);
180
printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n",
181
(val32 & PCI_STSCMD_SSE) != 0,
182
(val32 & PCI_STSCMD_RMA) != 0,
183
(val32 & PCI_STSCMD_RTA) != 0);
184
185
val32 |= PCI_STSCMD_CLEAR_MASK;
186
edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
187
188
edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
189
}
190
191
/* Check out HyperTransport Link Control Register */
192
edac_pci_read_dword(dev, REG_HT_LINK, &val32);
193
if (val32 & HT_LINK_LKFAIL) {
194
printk(KERN_INFO "Error(s) in hypertransport link control"
195
"register on device %s\n", pci_info->ctl_name);
196
printk(KERN_INFO "LKFAIL: %d\n",
197
(val32 & HT_LINK_LKFAIL) != 0);
198
199
val32 |= HT_LINK_LKFAIL;
200
edac_pci_write_dword(dev, REG_HT_LINK, val32);
201
202
edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
203
}
204
205
/* Check out PCI Interrupt and Bridge Control Register */
206
edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
207
if (val32 & PCI_INTBRG_CTRL_DTSTAT) {
208
printk(KERN_INFO "Error(s) in PCI interrupt and bridge control"
209
"register on device %s\n", pci_info->ctl_name);
210
printk(KERN_INFO "DTSTAT: %d\n",
211
(val32 & PCI_INTBRG_CTRL_DTSTAT) != 0);
212
213
val32 |= PCI_INTBRG_CTRL_DTSTAT;
214
edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
215
216
edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
217
}
218
219
/* Check out PCI Bridge Memory Base-Limit Register */
220
edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
221
if (val32 & MEM_LIMIT_CLEAR_MASK) {
222
printk(KERN_INFO
223
"Error(s) in mem limit register on %s device\n",
224
pci_info->ctl_name);
225
printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
226
"RTA: %d, STA: %d, MDPE: %d\n",
227
(val32 & MEM_LIMIT_DPE) != 0,
228
(val32 & MEM_LIMIT_RSE) != 0,
229
(val32 & MEM_LIMIT_RMA) != 0,
230
(val32 & MEM_LIMIT_RTA) != 0,
231
(val32 & MEM_LIMIT_STA) != 0,
232
(val32 & MEM_LIMIT_MDPE) != 0);
233
234
val32 |= MEM_LIMIT_CLEAR_MASK;
235
edac_pci_write_dword(dev, REG_MEM_LIM, val32);
236
237
edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
238
}
239
}
240
241
static struct resource *legacy_io_res;
242
static int at_compat_reg_broken;
243
#define LEGACY_NR_PORTS 1
244
245
/* device-specific methods for amd8111 LPC Bridge device */
246
static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info)
247
{
248
u8 val8;
249
struct pci_dev *dev = dev_info->dev;
250
251
/* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */
252
legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS,
253
AMD8111_EDAC_MOD_STR);
254
if (!legacy_io_res)
255
printk(KERN_INFO "%s: failed to request legacy I/O region "
256
"start %d, len %d\n", __func__,
257
REG_AT_COMPAT, LEGACY_NR_PORTS);
258
else {
259
val8 = __do_inb(REG_AT_COMPAT);
260
if (val8 == 0xff) { /* buggy port */
261
printk(KERN_INFO "%s: port %d is buggy, not supported"
262
" by hardware?\n", __func__, REG_AT_COMPAT);
263
at_compat_reg_broken = 1;
264
release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
265
legacy_io_res = NULL;
266
} else {
267
u8 out8 = 0;
268
if (val8 & AT_COMPAT_SERR)
269
out8 = AT_COMPAT_CLRSERR;
270
if (val8 & AT_COMPAT_IOCHK)
271
out8 |= AT_COMPAT_CLRIOCHK;
272
if (out8 > 0)
273
__do_outb(out8, REG_AT_COMPAT);
274
}
275
}
276
277
/* Second clear error flags on LPC bridge */
278
edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
279
if (val8 & IO_CTRL_1_CLEAR_MASK)
280
edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
281
}
282
283
static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info)
284
{
285
if (legacy_io_res)
286
release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
287
}
288
289
static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev)
290
{
291
struct amd8111_dev_info *dev_info = edac_dev->pvt_info;
292
struct pci_dev *dev = dev_info->dev;
293
u8 val8;
294
295
edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
296
if (val8 & IO_CTRL_1_CLEAR_MASK) {
297
printk(KERN_INFO
298
"Error(s) in IO control register on %s device\n",
299
dev_info->ctl_name);
300
printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n",
301
(val8 & IO_CTRL_1_LPC_ERR) != 0,
302
(val8 & IO_CTRL_1_PW2LPC) != 0);
303
304
val8 |= IO_CTRL_1_CLEAR_MASK;
305
edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
306
307
edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
308
}
309
310
if (at_compat_reg_broken == 0) {
311
u8 out8 = 0;
312
val8 = __do_inb(REG_AT_COMPAT);
313
if (val8 & AT_COMPAT_SERR)
314
out8 = AT_COMPAT_CLRSERR;
315
if (val8 & AT_COMPAT_IOCHK)
316
out8 |= AT_COMPAT_CLRIOCHK;
317
if (out8 > 0) {
318
__do_outb(out8, REG_AT_COMPAT);
319
edac_device_handle_ue(edac_dev, 0, 0,
320
edac_dev->ctl_name);
321
}
322
}
323
}
324
325
/* General devices represented by edac_device_ctl_info */
326
static struct amd8111_dev_info amd8111_devices[] = {
327
[LPC_BRIDGE] = {
328
.err_dev = PCI_DEVICE_ID_AMD_8111_LPC,
329
.ctl_name = "lpc",
330
.init = amd8111_lpc_bridge_init,
331
.exit = amd8111_lpc_bridge_exit,
332
.check = amd8111_lpc_bridge_check,
333
},
334
{0},
335
};
336
337
/* PCI controllers represented by edac_pci_ctl_info */
338
static struct amd8111_pci_info amd8111_pcis[] = {
339
[PCI_BRIDGE] = {
340
.err_dev = PCI_DEVICE_ID_AMD_8111_PCI,
341
.ctl_name = "AMD8111_PCI_Controller",
342
.init = amd8111_pci_bridge_init,
343
.exit = amd8111_pci_bridge_exit,
344
.check = amd8111_pci_bridge_check,
345
},
346
{0},
347
};
348
349
static int amd8111_dev_probe(struct pci_dev *dev,
350
const struct pci_device_id *id)
351
{
352
struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
353
354
dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
355
dev_info->err_dev, NULL);
356
357
if (!dev_info->dev) {
358
printk(KERN_ERR "EDAC device not found:"
359
"vendor %x, device %x, name %s\n",
360
PCI_VENDOR_ID_AMD, dev_info->err_dev,
361
dev_info->ctl_name);
362
return -ENODEV;
363
}
364
365
if (pci_enable_device(dev_info->dev)) {
366
pci_dev_put(dev_info->dev);
367
printk(KERN_ERR "failed to enable:"
368
"vendor %x, device %x, name %s\n",
369
PCI_VENDOR_ID_AMD, dev_info->err_dev,
370
dev_info->ctl_name);
371
return -ENODEV;
372
}
373
374
/*
375
* we do not allocate extra private structure for
376
* edac_device_ctl_info, but make use of existing
377
* one instead.
378
*/
379
dev_info->edac_idx = edac_device_alloc_index();
380
dev_info->edac_dev =
381
edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
382
NULL, 0, 0,
383
NULL, 0, dev_info->edac_idx);
384
if (!dev_info->edac_dev)
385
return -ENOMEM;
386
387
dev_info->edac_dev->pvt_info = dev_info;
388
dev_info->edac_dev->dev = &dev_info->dev->dev;
389
dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
390
dev_info->edac_dev->ctl_name = dev_info->ctl_name;
391
dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
392
393
if (edac_op_state == EDAC_OPSTATE_POLL)
394
dev_info->edac_dev->edac_check = dev_info->check;
395
396
if (dev_info->init)
397
dev_info->init(dev_info);
398
399
if (edac_device_add_device(dev_info->edac_dev) > 0) {
400
printk(KERN_ERR "failed to add edac_dev for %s\n",
401
dev_info->ctl_name);
402
edac_device_free_ctl_info(dev_info->edac_dev);
403
return -ENODEV;
404
}
405
406
printk(KERN_INFO "added one edac_dev on AMD8111 "
407
"vendor %x, device %x, name %s\n",
408
PCI_VENDOR_ID_AMD, dev_info->err_dev,
409
dev_info->ctl_name);
410
411
return 0;
412
}
413
414
static void amd8111_dev_remove(struct pci_dev *dev)
415
{
416
struct amd8111_dev_info *dev_info;
417
418
for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++)
419
if (dev_info->dev->device == dev->device)
420
break;
421
422
if (!dev_info->err_dev) /* should never happen */
423
return;
424
425
if (dev_info->edac_dev) {
426
edac_device_del_device(dev_info->edac_dev->dev);
427
edac_device_free_ctl_info(dev_info->edac_dev);
428
}
429
430
if (dev_info->exit)
431
dev_info->exit(dev_info);
432
433
pci_dev_put(dev_info->dev);
434
}
435
436
static int amd8111_pci_probe(struct pci_dev *dev,
437
const struct pci_device_id *id)
438
{
439
struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
440
441
pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
442
pci_info->err_dev, NULL);
443
444
if (!pci_info->dev) {
445
printk(KERN_ERR "EDAC device not found:"
446
"vendor %x, device %x, name %s\n",
447
PCI_VENDOR_ID_AMD, pci_info->err_dev,
448
pci_info->ctl_name);
449
return -ENODEV;
450
}
451
452
if (pci_enable_device(pci_info->dev)) {
453
pci_dev_put(pci_info->dev);
454
printk(KERN_ERR "failed to enable:"
455
"vendor %x, device %x, name %s\n",
456
PCI_VENDOR_ID_AMD, pci_info->err_dev,
457
pci_info->ctl_name);
458
return -ENODEV;
459
}
460
461
/*
462
* we do not allocate extra private structure for
463
* edac_pci_ctl_info, but make use of existing
464
* one instead.
465
*/
466
pci_info->edac_idx = edac_pci_alloc_index();
467
pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
468
if (!pci_info->edac_dev)
469
return -ENOMEM;
470
471
pci_info->edac_dev->pvt_info = pci_info;
472
pci_info->edac_dev->dev = &pci_info->dev->dev;
473
pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
474
pci_info->edac_dev->ctl_name = pci_info->ctl_name;
475
pci_info->edac_dev->dev_name = dev_name(&pci_info->dev->dev);
476
477
if (edac_op_state == EDAC_OPSTATE_POLL)
478
pci_info->edac_dev->edac_check = pci_info->check;
479
480
if (pci_info->init)
481
pci_info->init(pci_info);
482
483
if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
484
printk(KERN_ERR "failed to add edac_pci for %s\n",
485
pci_info->ctl_name);
486
edac_pci_free_ctl_info(pci_info->edac_dev);
487
return -ENODEV;
488
}
489
490
printk(KERN_INFO "added one edac_pci on AMD8111 "
491
"vendor %x, device %x, name %s\n",
492
PCI_VENDOR_ID_AMD, pci_info->err_dev,
493
pci_info->ctl_name);
494
495
return 0;
496
}
497
498
static void amd8111_pci_remove(struct pci_dev *dev)
499
{
500
struct amd8111_pci_info *pci_info;
501
502
for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++)
503
if (pci_info->dev->device == dev->device)
504
break;
505
506
if (!pci_info->err_dev) /* should never happen */
507
return;
508
509
if (pci_info->edac_dev) {
510
edac_pci_del_device(pci_info->edac_dev->dev);
511
edac_pci_free_ctl_info(pci_info->edac_dev);
512
}
513
514
if (pci_info->exit)
515
pci_info->exit(pci_info);
516
517
pci_dev_put(pci_info->dev);
518
}
519
520
/* PCI Device ID talbe for general EDAC device */
521
static const struct pci_device_id amd8111_edac_dev_tbl[] = {
522
{
523
PCI_VEND_DEV(AMD, 8111_LPC),
524
.subvendor = PCI_ANY_ID,
525
.subdevice = PCI_ANY_ID,
526
.class = 0,
527
.class_mask = 0,
528
.driver_data = LPC_BRIDGE,
529
},
530
{
531
0,
532
} /* table is NULL-terminated */
533
};
534
MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl);
535
536
static struct pci_driver amd8111_edac_dev_driver = {
537
.name = "AMD8111_EDAC_DEV",
538
.probe = amd8111_dev_probe,
539
.remove = amd8111_dev_remove,
540
.id_table = amd8111_edac_dev_tbl,
541
};
542
543
/* PCI Device ID table for EDAC PCI controller */
544
static const struct pci_device_id amd8111_edac_pci_tbl[] = {
545
{
546
PCI_VEND_DEV(AMD, 8111_PCI),
547
.subvendor = PCI_ANY_ID,
548
.subdevice = PCI_ANY_ID,
549
.class = 0,
550
.class_mask = 0,
551
.driver_data = PCI_BRIDGE,
552
},
553
{
554
0,
555
} /* table is NULL-terminated */
556
};
557
MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl);
558
559
static struct pci_driver amd8111_edac_pci_driver = {
560
.name = "AMD8111_EDAC_PCI",
561
.probe = amd8111_pci_probe,
562
.remove = amd8111_pci_remove,
563
.id_table = amd8111_edac_pci_tbl,
564
};
565
566
static int __init amd8111_edac_init(void)
567
{
568
int val;
569
570
printk(KERN_INFO "AMD8111 EDAC driver " AMD8111_EDAC_REVISION "\n");
571
printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
572
573
/* Only POLL mode supported so far */
574
edac_op_state = EDAC_OPSTATE_POLL;
575
576
val = pci_register_driver(&amd8111_edac_dev_driver);
577
val |= pci_register_driver(&amd8111_edac_pci_driver);
578
579
return val;
580
}
581
582
static void __exit amd8111_edac_exit(void)
583
{
584
pci_unregister_driver(&amd8111_edac_pci_driver);
585
pci_unregister_driver(&amd8111_edac_dev_driver);
586
}
587
588
589
module_init(amd8111_edac_init);
590
module_exit(amd8111_edac_exit);
591
592
MODULE_LICENSE("GPL");
593
MODULE_AUTHOR("Cao Qingtao <[email protected]>\n");
594
MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module");
595
596