diff options
author | Dave Jiang <djiang@mvista.com> | 2007-07-19 04:49:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:53 -0400 |
commit | c0d121720220584bba2876b032e58a076b843fa1 (patch) | |
tree | 13ba24c6d875ded1494e1560f336b8551c663ef1 /drivers/edac/edac_module.c | |
parent | 28f96eeafc89643d411d54c258788a8573576127 (diff) |
drivers/edac: add new nmi rescan
Provides a way for NMI reported errors on x86 to notify the EDAC
subsystem pending ECC errors by writing to a software state variable.
Here's the reworked patch. I added an EDAC stub to the kernel so we can
have variables that are in the kernel even if EDAC is a module. I also
implemented the idea of using the chip driver to select error detection
mode via module parameter and eliminate the kernel compile option.
Please review/test. Thx!
Also, I only made changes to some of the chipset drivers since I am
unfamiliar with the other ones. We can add similar changes as we go.
Signed-off-by: Dave Jiang <djiang@mvista.com>
Signed-off-by: Douglas Thompson <dougthompson@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/edac_module.c')
-rw-r--r-- | drivers/edac/edac_module.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c index 3cd3a236821c..89c96ecbf04e 100644 --- a/drivers/edac/edac_module.c +++ b/drivers/edac/edac_module.c | |||
@@ -1,6 +1,7 @@ | |||
1 | 1 | ||
2 | #include <linux/freezer.h> | 2 | #include <linux/freezer.h> |
3 | #include <linux/kthread.h> | 3 | #include <linux/kthread.h> |
4 | #include <linux/edac.h> | ||
4 | 5 | ||
5 | #include "edac_mc.h" | 6 | #include "edac_mc.h" |
6 | #include "edac_module.h" | 7 | #include "edac_module.h" |
@@ -102,6 +103,25 @@ static void do_edac_check(void) | |||
102 | } | 103 | } |
103 | 104 | ||
104 | /* | 105 | /* |
106 | * handler for EDAC to check if NMI type handler has asserted interrupt | ||
107 | */ | ||
108 | static int edac_assert_error_check_and_clear(void) | ||
109 | { | ||
110 | int vreg; | ||
111 | |||
112 | if(edac_op_state == EDAC_OPSTATE_POLL) | ||
113 | return 1; | ||
114 | |||
115 | vreg = atomic_read(&edac_err_assert); | ||
116 | if(vreg) { | ||
117 | atomic_set(&edac_err_assert, 0); | ||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* | ||
105 | * Action thread for EDAC to perform the POLL operations | 125 | * Action thread for EDAC to perform the POLL operations |
106 | */ | 126 | */ |
107 | static int edac_kernel_thread(void *arg) | 127 | static int edac_kernel_thread(void *arg) |
@@ -109,8 +129,8 @@ static int edac_kernel_thread(void *arg) | |||
109 | int msec; | 129 | int msec; |
110 | 130 | ||
111 | while (!kthread_should_stop()) { | 131 | while (!kthread_should_stop()) { |
112 | 132 | if(edac_assert_error_check_and_clear()) | |
113 | do_edac_check(); | 133 | do_edac_check(); |
114 | 134 | ||
115 | /* goto sleep for the interval */ | 135 | /* goto sleep for the interval */ |
116 | msec = (HZ * edac_get_poll_msec()) / 1000; | 136 | msec = (HZ * edac_get_poll_msec()) / 1000; |