Blame view

drivers/edac/r82600_edac.c 11.6 KB
2f768af73   Alan Cox   [PATCH] EDAC: dri...
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * Radisys 82600 Embedded chipset Memory Controller kernel module
   * (C) 2005 EADS Astrium
   * This file may be distributed under the terms of the
   * GNU General Public License.
   *
   * Written by Tim Small <tim@buttersideup.com>, based on work by Thayne
   * Harbaugh, Dan Hollis <goemon at anime dot net> and others.
   *
   * $Id: edac_r82600.c,v 1.1.2.6 2005/10/05 00:43:44 dsp_llnl Exp $
   *
   * Written with reference to 82600 High Integration Dual PCI System
   * Controller Data Book:
c4192705f   Dave Jiang   drivers/edac: add...
14
   * www.radisys.com/files/support_downloads/007-01277-0002.82600DataBook.pdf
2f768af73   Alan Cox   [PATCH] EDAC: dri...
15
16
   * references to this document given in []
   */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
17
18
  #include <linux/module.h>
  #include <linux/init.h>
2f768af73   Alan Cox   [PATCH] EDAC: dri...
19
20
  #include <linux/pci.h>
  #include <linux/pci_ids.h>
c3c52bce6   Hitoshi Mitake   edac: fix module ...
21
  #include <linux/edac.h>
20bcb7a81   Douglas Thompson   drivers/edac: mod...
22
  #include "edac_core.h"
2f768af73   Alan Cox   [PATCH] EDAC: dri...
23

152ba3942   Michal Marek   edac: Drop __DATE...
24
  #define R82600_REVISION	" Ver: 2.0.2"
929a40ec3   Doug Thompson   [PATCH] EDAC: fix...
25
  #define EDAC_MOD_STR	"r82600_edac"
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
26

537fba289   Dave Peterson   [PATCH] EDAC: pri...
27
  #define r82600_printk(level, fmt, arg...) \
e7ecd8910   Dave Peterson   [PATCH] EDAC: for...
28
  	edac_printk(level, "r82600", fmt, ##arg)
537fba289   Dave Peterson   [PATCH] EDAC: pri...
29
30
  
  #define r82600_mc_printk(mci, level, fmt, arg...) \
e7ecd8910   Dave Peterson   [PATCH] EDAC: for...
31
  	edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg)
537fba289   Dave Peterson   [PATCH] EDAC: pri...
32

2f768af73   Alan Cox   [PATCH] EDAC: dri...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  /* Radisys say "The 82600 integrates a main memory SDRAM controller that
   * supports up to four banks of memory. The four banks can support a mix of
   * sizes of 64 bit wide (72 bits with ECC) Synchronous DRAM (SDRAM) DIMMs,
   * each of which can be any size from 16MB to 512MB. Both registered (control
   * signals buffered) and unbuffered DIMM types are supported. Mixing of
   * registered and unbuffered DIMMs as well as mixing of ECC and non-ECC DIMMs
   * is not allowed. The 82600 SDRAM interface operates at the same frequency as
   * the CPU bus, 66MHz, 100MHz or 133MHz."
   */
  
  #define R82600_NR_CSROWS 4
  #define R82600_NR_CHANS  1
  #define R82600_NR_DIMMS  4
  
  #define R82600_BRIDGE_ID  0x8200
  
  /* Radisys 82600 register addresses - device 0 function 0 - PCI bridge */
  #define R82600_DRAMC	0x57	/* Various SDRAM related control bits
  				 * all bits are R/W
  				 *
  				 * 7    SDRAM ISA Hole Enable
  				 * 6    Flash Page Mode Enable
  				 * 5    ECC Enable: 1=ECC 0=noECC
  				 * 4    DRAM DIMM Type: 1=
  				 * 3    BIOS Alias Disable
  				 * 2    SDRAM BIOS Flash Write Enable
  				 * 1:0  SDRAM Refresh Rate: 00=Disabled
  				 *          01=7.8usec (256Mbit SDRAMs)
  				 *          10=15.6us 11=125usec
  				 */
  
  #define R82600_SDRAMC	0x76	/* "SDRAM Control Register"
  				 * More SDRAM related control bits
  				 * all bits are R/W
  				 *
  				 * 15:8 Reserved.
  				 *
  				 * 7:5  Special SDRAM Mode Select
  				 *
  				 * 4    Force ECC
  				 *
  				 *        1=Drive ECC bits to 0 during
  				 *          write cycles (i.e. ECC test mode)
  				 *
  				 *        0=Normal ECC functioning
  				 *
  				 * 3    Enhanced Paging Enable
  				 *
  				 * 2    CAS# Latency 0=3clks 1=2clks
  				 *
  				 * 1    RAS# to CAS# Delay 0=3 1=2
  				 *
  				 * 0    RAS# Precharge     0=3 1=2
  				 */
  
  #define R82600_EAP	0x80	/* ECC Error Address Pointer Register
  				 *
  				 * 31    Disable Hardware Scrubbing (RW)
  				 *        0=Scrub on corrected read
  				 *        1=Don't scrub on corrected read
  				 *
  				 * 30:12 Error Address Pointer (RO)
  				 *        Upper 19 bits of error address
  				 *
  				 * 11:4  Syndrome Bits (RO)
  				 *
  				 * 3     BSERR# on multibit error (RW)
  				 *        1=enable 0=disable
  				 *
  				 * 2     NMI on Single Bit Eror (RW)
  				 *        1=NMI triggered by SBE n.b. other
  				 *          prerequeists
  				 *        0=NMI not triggered
  				 *
  				 * 1     MBE (R/WC)
  				 *        read 1=MBE at EAP (see above)
  				 *        read 0=no MBE, or SBE occurred first
  				 *        write 1=Clear MBE status (must also
  				 *          clear SBE)
  				 *        write 0=NOP
  				 *
  				 * 1     SBE (R/WC)
  				 *        read 1=SBE at EAP (see above)
  				 *        read 0=no SBE, or MBE occurred first
  				 *        write 1=Clear SBE status (must also
  				 *          clear MBE)
  				 *        write 0=NOP
  				 */
25985edce   Lucas De Marchi   Fix common misspe...
121
  #define R82600_DRBA	0x60	/* + 0x60..0x63 SDRAM Row Boundary Address
2f768af73   Alan Cox   [PATCH] EDAC: dri...
122
123
124
125
126
127
128
129
130
  				 *  Registers
  				 *
  				 * 7:0  Address lines 30:24 - upper limit of
  				 * each row [p57]
  				 */
  
  struct r82600_error_info {
  	u32 eapr;
  };
f044091ca   Douglas Thompson   drivers/edac: rem...
131
  static unsigned int disable_hardware_scrub;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
132

456a2f955   Dave Jiang   drivers/edac: dri...
133
  static struct edac_pci_ctl_info *r82600_pci;
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
134
  static void r82600_get_error_info(struct mem_ctl_info *mci,
052dfb45c   Douglas Thompson   drivers/edac: cle...
135
  				struct r82600_error_info *info)
2f768af73   Alan Cox   [PATCH] EDAC: dri...
136
  {
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
137
138
139
140
  	struct pci_dev *pdev;
  
  	pdev = to_pci_dev(mci->dev);
  	pci_read_config_dword(pdev, R82600_EAP, &info->eapr);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
141
142
143
  
  	if (info->eapr & BIT(0))
  		/* Clear error to allow next error to be reported [p.62] */
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
144
  		pci_write_bits32(pdev, R82600_EAP,
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
145
146
  				 ((u32) BIT(0) & (u32) BIT(1)),
  				 ((u32) BIT(0) & (u32) BIT(1)));
2f768af73   Alan Cox   [PATCH] EDAC: dri...
147
148
149
  
  	if (info->eapr & BIT(1))
  		/* Clear error to allow next error to be reported [p.62] */
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
150
  		pci_write_bits32(pdev, R82600_EAP,
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
151
152
  				 ((u32) BIT(0) & (u32) BIT(1)),
  				 ((u32) BIT(0) & (u32) BIT(1)));
2f768af73   Alan Cox   [PATCH] EDAC: dri...
153
  }
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
154
  static int r82600_process_error_info(struct mem_ctl_info *mci,
052dfb45c   Douglas Thompson   drivers/edac: cle...
155
156
  				struct r82600_error_info *info,
  				int handle_errors)
2f768af73   Alan Cox   [PATCH] EDAC: dri...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  {
  	int error_found;
  	u32 eapaddr, page;
  	u32 syndrome;
  
  	error_found = 0;
  
  	/* bits 30:12 store the upper 19 bits of the 32 bit error address */
  	eapaddr = ((info->eapr >> 12) & 0x7FFF) << 13;
  	/* Syndrome in bits 11:4 [p.62]       */
  	syndrome = (info->eapr >> 4) & 0xFF;
  
  	/* the R82600 reports at less than page *
  	 * granularity (upper 19 bits only)     */
  	page = eapaddr >> PAGE_SHIFT;
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
172
  	if (info->eapr & BIT(0)) {	/* CE? */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
173
174
175
  		error_found = 1;
  
  		if (handle_errors)
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
176
  			edac_mc_handle_ce(mci, page, 0,	/* not avail */
052dfb45c   Douglas Thompson   drivers/edac: cle...
177
178
179
  					syndrome,
  					edac_mc_find_csrow_by_page(mci, page),
  					0, mci->ctl_name);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
180
  	}
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
181
  	if (info->eapr & BIT(1)) {	/* UE? */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
182
183
184
185
186
  		error_found = 1;
  
  		if (handle_errors)
  			/* 82600 doesn't give enough info */
  			edac_mc_handle_ue(mci, page, 0,
052dfb45c   Douglas Thompson   drivers/edac: cle...
187
188
  					edac_mc_find_csrow_by_page(mci, page),
  					mci->ctl_name);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
189
190
191
192
193
194
195
196
  	}
  
  	return error_found;
  }
  
  static void r82600_check(struct mem_ctl_info *mci)
  {
  	struct r82600_error_info info;
537fba289   Dave Peterson   [PATCH] EDAC: pri...
197
198
  	debugf1("MC%d: %s()
  ", mci->mc_idx, __func__);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
199
200
201
  	r82600_get_error_info(mci, &info);
  	r82600_process_error_info(mci, &info, 1);
  }
131895251   Doug Thompson   [PATCH] EDAC: pro...
202
  static inline int ecc_enabled(u8 dramcr)
2f768af73   Alan Cox   [PATCH] EDAC: dri...
203
  {
131895251   Doug Thompson   [PATCH] EDAC: pro...
204
205
206
207
  	return dramcr & BIT(5);
  }
  
  static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
052dfb45c   Douglas Thompson   drivers/edac: cle...
208
  			u8 dramcr)
131895251   Doug Thompson   [PATCH] EDAC: pro...
209
210
  {
  	struct csrow_info *csrow;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
211
  	int index;
25985edce   Lucas De Marchi   Fix common misspe...
212
  	u8 drbar;		/* SDRAM Row Boundary Address Register */
131895251   Doug Thompson   [PATCH] EDAC: pro...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  	u32 row_high_limit, row_high_limit_last;
  	u32 reg_sdram, ecc_on, row_base;
  
  	ecc_on = ecc_enabled(dramcr);
  	reg_sdram = dramcr & BIT(4);
  	row_high_limit_last = 0;
  
  	for (index = 0; index < mci->nr_csrows; index++) {
  		csrow = &mci->csrows[index];
  
  		/* find the DRAM Chip Select Base address and mask */
  		pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);
  
  		debugf1("%s() Row=%d DRBA = %#0x
  ", __func__, index, drbar);
  
  		row_high_limit = ((u32) drbar << 24);
  /*		row_high_limit = ((u32)drbar << 24) | 0xffffffUL; */
25985edce   Lucas De Marchi   Fix common misspe...
231
232
  		debugf1("%s() Row=%d, Boundary Address=%#0x, Last = %#0x
  ",
131895251   Doug Thompson   [PATCH] EDAC: pro...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  			__func__, index, row_high_limit, row_high_limit_last);
  
  		/* Empty row [p.57] */
  		if (row_high_limit == row_high_limit_last)
  			continue;
  
  		row_base = row_high_limit_last;
  
  		csrow->first_page = row_base >> PAGE_SHIFT;
  		csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
  		csrow->nr_pages = csrow->last_page - csrow->first_page + 1;
  		/* Error address is top 19 bits - so granularity is      *
  		 * 14 bits                                               */
  		csrow->grain = 1 << 14;
  		csrow->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
  		/* FIXME - check that this is unknowable with this chipset */
  		csrow->dtype = DEV_UNKNOWN;
  
  		/* Mode is global on 82600 */
  		csrow->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
  		row_high_limit_last = row_high_limit;
  	}
  }
  
  static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
  {
  	struct mem_ctl_info *mci;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
260
  	u8 dramcr;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
261
262
263
  	u32 eapr;
  	u32 scrub_disabled;
  	u32 sdram_refresh_rate;
749ede574   Dave Peterson   [PATCH] EDAC: cle...
264
  	struct r82600_error_info discard;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
265

537fba289   Dave Peterson   [PATCH] EDAC: pri...
266
267
  	debugf0("%s()
  ", __func__);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
268
269
  	pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
  	pci_read_config_dword(pdev, R82600_EAP, &eapr);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
270
271
  	scrub_disabled = eapr & BIT(31);
  	sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
537fba289   Dave Peterson   [PATCH] EDAC: pri...
272
273
274
  	debugf2("%s(): sdram refresh rate = %#0x
  ", __func__,
  		sdram_refresh_rate);
537fba289   Dave Peterson   [PATCH] EDAC: pri...
275
276
  	debugf2("%s(): DRAMC register = %#0x
  ", __func__, dramcr);
b8f6f9755   Doug Thompson   drivers/edac: fix...
277
  	mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS, 0);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
278

131895251   Doug Thompson   [PATCH] EDAC: pro...
279
280
  	if (mci == NULL)
  		return -ENOMEM;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
281

537fba289   Dave Peterson   [PATCH] EDAC: pri...
282
283
  	debugf0("%s(): mci = %p
  ", __func__, mci);
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
284
  	mci->dev = &pdev->dev;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
285
  	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
286
  	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
e7ecd8910   Dave Peterson   [PATCH] EDAC: for...
287
288
289
  	/* FIXME try to work out if the chip leads have been used for COM2
  	 * instead on this board? [MA6?] MAYBE:
  	 */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
290
291
292
293
294
295
  
  	/* On the R82600, the pins for memory bits 72:65 - i.e. the   *
  	 * EC bits are shared with the pins for COM2 (!), so if COM2  *
  	 * is enabled, we assume COM2 is wired up, and thus no EDAC   *
  	 * is possible.                                               */
  	mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
e7ecd8910   Dave Peterson   [PATCH] EDAC: for...
296

131895251   Doug Thompson   [PATCH] EDAC: pro...
297
  	if (ecc_enabled(dramcr)) {
2f768af73   Alan Cox   [PATCH] EDAC: dri...
298
  		if (scrub_disabled)
537fba289   Dave Peterson   [PATCH] EDAC: pri...
299
300
301
  			debugf3("%s(): mci = %p - Scrubbing disabled! EAP: "
  				"%#0x
  ", __func__, mci, eapr);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
302
303
  	} else
  		mci->edac_cap = EDAC_FLAG_NONE;
680cbbbb0   Dave Peterson   [PATCH] EDAC: nam...
304
  	mci->mod_name = EDAC_MOD_STR;
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
305
  	mci->mod_ver = R82600_REVISION;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
306
  	mci->ctl_name = "R82600";
c4192705f   Dave Jiang   drivers/edac: add...
307
  	mci->dev_name = pci_name(pdev);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
308
309
  	mci->edac_check = r82600_check;
  	mci->ctl_page_to_phys = NULL;
131895251   Doug Thompson   [PATCH] EDAC: pro...
310
  	r82600_init_csrows(mci, pdev, dramcr);
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
311
  	r82600_get_error_info(mci, &discard);	/* clear counters */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
312

2d7bbb91c   Doug Thompson   [PATCH] EDAC: mc ...
313
314
315
  	/* Here we assume that we will never see multiple instances of this
  	 * type of memory controller.  The ID is therefore hardcoded to 0.
  	 */
b8f6f9755   Doug Thompson   drivers/edac: fix...
316
  	if (edac_mc_add_mc(mci)) {
537fba289   Dave Peterson   [PATCH] EDAC: pri...
317
318
  		debugf3("%s(): failed edac_mc_add_mc()
  ", __func__);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
319
320
321
322
  		goto fail;
  	}
  
  	/* get this far and it's successful */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
323
  	if (disable_hardware_scrub) {
537fba289   Dave Peterson   [PATCH] EDAC: pri...
324
325
326
  		debugf3("%s(): Disabling Hardware Scrub (scrub on error)
  ",
  			__func__);
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
327
  		pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31));
2f768af73   Alan Cox   [PATCH] EDAC: dri...
328
  	}
456a2f955   Dave Jiang   drivers/edac: dri...
329
330
331
332
333
334
335
336
337
338
339
340
  	/* allocating generic PCI control info */
  	r82600_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
  	if (!r82600_pci) {
  		printk(KERN_WARNING
  			"%s(): Unable to create PCI control
  ",
  			__func__);
  		printk(KERN_WARNING
  			"%s(): PCI error report via EDAC not setup
  ",
  			__func__);
  	}
537fba289   Dave Peterson   [PATCH] EDAC: pri...
341
342
  	debugf3("%s(): success
  ", __func__);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
343
  	return 0;
052dfb45c   Douglas Thompson   drivers/edac: cle...
344
  fail:
131895251   Doug Thompson   [PATCH] EDAC: pro...
345
346
  	edac_mc_free(mci);
  	return -ENODEV;
2f768af73   Alan Cox   [PATCH] EDAC: dri...
347
348
349
350
  }
  
  /* returns count (>= 0), or negative on error */
  static int __devinit r82600_init_one(struct pci_dev *pdev,
052dfb45c   Douglas Thompson   drivers/edac: cle...
351
  				const struct pci_device_id *ent)
2f768af73   Alan Cox   [PATCH] EDAC: dri...
352
  {
537fba289   Dave Peterson   [PATCH] EDAC: pri...
353
354
  	debugf0("%s()
  ", __func__);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
355

ee6583f6e   Roman Fietze   PCI: fix typos pc...
356
  	/* don't need to call pci_enable_device() */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
357
358
  	return r82600_probe1(pdev, ent->driver_data);
  }
2f768af73   Alan Cox   [PATCH] EDAC: dri...
359
360
361
  static void __devexit r82600_remove_one(struct pci_dev *pdev)
  {
  	struct mem_ctl_info *mci;
537fba289   Dave Peterson   [PATCH] EDAC: pri...
362
363
  	debugf0("%s()
  ", __func__);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
364

456a2f955   Dave Jiang   drivers/edac: dri...
365
366
  	if (r82600_pci)
  		edac_pci_release_generic_ctl(r82600_pci);
37f04581a   Doug Thompson   [PATCH] EDAC: PCI...
367
  	if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
18dbc337a   Dave Peterson   [PATCH] EDAC: pro...
368
369
370
  		return;
  
  	edac_mc_free(mci);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
371
  }
2f768af73   Alan Cox   [PATCH] EDAC: dri...
372
  static const struct pci_device_id r82600_pci_tbl[] __devinitdata = {
e7ecd8910   Dave Peterson   [PATCH] EDAC: for...
373
  	{
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
374
375
  	 PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)
  	 },
e7ecd8910   Dave Peterson   [PATCH] EDAC: for...
376
  	{
cddbfcacf   Douglas Thompson   drivers/edac: Lin...
377
378
  	 0,
  	 }			/* 0 terminated list. */
2f768af73   Alan Cox   [PATCH] EDAC: dri...
379
380
381
  };
  
  MODULE_DEVICE_TABLE(pci, r82600_pci_tbl);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
382
  static struct pci_driver r82600_driver = {
680cbbbb0   Dave Peterson   [PATCH] EDAC: nam...
383
  	.name = EDAC_MOD_STR,
2f768af73   Alan Cox   [PATCH] EDAC: dri...
384
385
386
387
  	.probe = r82600_init_one,
  	.remove = __devexit_p(r82600_remove_one),
  	.id_table = r82600_pci_tbl,
  };
da9bb1d27   Alan Cox   [PATCH] EDAC: cor...
388
  static int __init r82600_init(void)
2f768af73   Alan Cox   [PATCH] EDAC: dri...
389
  {
c3c52bce6   Hitoshi Mitake   edac: fix module ...
390
391
         /* Ensure that the OPSTATE is set correctly for POLL or NMI */
         opstate_init();
2f768af73   Alan Cox   [PATCH] EDAC: dri...
392
393
  	return pci_register_driver(&r82600_driver);
  }
2f768af73   Alan Cox   [PATCH] EDAC: dri...
394
395
396
397
  static void __exit r82600_exit(void)
  {
  	pci_unregister_driver(&r82600_driver);
  }
2f768af73   Alan Cox   [PATCH] EDAC: dri...
398
399
  module_init(r82600_init);
  module_exit(r82600_exit);
2f768af73   Alan Cox   [PATCH] EDAC: dri...
400
401
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
052dfb45c   Douglas Thompson   drivers/edac: cle...
402
  		"on behalf of EADS Astrium");
2f768af73   Alan Cox   [PATCH] EDAC: dri...
403
404
405
406
407
  MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
  
  module_param(disable_hardware_scrub, bool, 0644);
  MODULE_PARM_DESC(disable_hardware_scrub,
  		 "If set, disable the chipset's automatic scrub for CEs");
c3c52bce6   Hitoshi Mitake   edac: fix module ...
408
409
410
  
  module_param(edac_op_state, int, 0444);
  MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");