diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/acpi/apei/hest.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/acpi/apei/hest.c')
-rw-r--r-- | drivers/acpi/apei/hest.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 1a3508a7fe03..181bc2f7bb74 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
46 | 46 | ||
47 | /* HEST table parsing */ | 47 | /* HEST table parsing */ |
48 | 48 | ||
49 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *__read_mostly hest_tab; |
50 | 50 | ||
51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), | 54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), |
@@ -126,7 +126,7 @@ struct ghes_arr { | |||
126 | unsigned int count; | 126 | unsigned int count; |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | 129 | static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) |
130 | { | 130 | { |
131 | int *count = data; | 131 | int *count = data; |
132 | 132 | ||
@@ -135,17 +135,27 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
141 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
142 | int rc; | 142 | int rc, i; |
143 | 143 | ||
144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) |
145 | return 0; | 145 | return 0; |
146 | 146 | ||
147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) | 147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) |
148 | return 0; | 148 | return 0; |
149 | for (i = 0; i < ghes_arr->count; i++) { | ||
150 | struct acpi_hest_header *hdr; | ||
151 | ghes_dev = ghes_arr->ghes_devs[i]; | ||
152 | hdr = *(struct acpi_hest_header **)ghes_dev->dev.platform_data; | ||
153 | if (hdr->source_id == hest_hdr->source_id) { | ||
154 | pr_warning(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n", | ||
155 | hdr->source_id); | ||
156 | return -EIO; | ||
157 | } | ||
158 | } | ||
149 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | 159 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); |
150 | if (!ghes_dev) | 160 | if (!ghes_dev) |
151 | return -ENOMEM; | 161 | return -ENOMEM; |
@@ -165,7 +175,7 @@ err: | |||
165 | return rc; | 175 | return rc; |
166 | } | 176 | } |
167 | 177 | ||
168 | static int hest_ghes_dev_register(unsigned int ghes_count) | 178 | static int __init hest_ghes_dev_register(unsigned int ghes_count) |
169 | { | 179 | { |
170 | int rc, i; | 180 | int rc, i; |
171 | struct ghes_arr ghes_arr; | 181 | struct ghes_arr ghes_arr; |
@@ -195,24 +205,24 @@ static int __init setup_hest_disable(char *str) | |||
195 | 205 | ||
196 | __setup("hest_disable", setup_hest_disable); | 206 | __setup("hest_disable", setup_hest_disable); |
197 | 207 | ||
198 | static int __init hest_init(void) | 208 | void __init acpi_hest_init(void) |
199 | { | 209 | { |
200 | acpi_status status; | 210 | acpi_status status; |
201 | int rc = -ENODEV; | 211 | int rc = -ENODEV; |
202 | unsigned int ghes_count = 0; | 212 | unsigned int ghes_count = 0; |
203 | 213 | ||
204 | if (acpi_disabled) | ||
205 | goto err; | ||
206 | |||
207 | if (hest_disable) { | 214 | if (hest_disable) { |
208 | pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); | 215 | pr_info(HEST_PFX "Table parsing disabled.\n"); |
209 | goto err; | 216 | return; |
210 | } | 217 | } |
211 | 218 | ||
219 | if (acpi_disabled) | ||
220 | goto err; | ||
221 | |||
212 | status = acpi_get_table(ACPI_SIG_HEST, 0, | 222 | status = acpi_get_table(ACPI_SIG_HEST, 0, |
213 | (struct acpi_table_header **)&hest_tab); | 223 | (struct acpi_table_header **)&hest_tab); |
214 | if (status == AE_NOT_FOUND) { | 224 | if (status == AE_NOT_FOUND) { |
215 | pr_info(HEST_PFX "Table is not found!\n"); | 225 | pr_info(HEST_PFX "Table not found.\n"); |
216 | goto err; | 226 | goto err; |
217 | } else if (ACPI_FAILURE(status)) { | 227 | } else if (ACPI_FAILURE(status)) { |
218 | const char *msg = acpi_format_exception(status); | 228 | const char *msg = acpi_format_exception(status); |
@@ -226,15 +236,11 @@ static int __init hest_init(void) | |||
226 | goto err; | 236 | goto err; |
227 | 237 | ||
228 | rc = hest_ghes_dev_register(ghes_count); | 238 | rc = hest_ghes_dev_register(ghes_count); |
229 | if (rc) | 239 | if (!rc) { |
230 | goto err; | 240 | pr_info(HEST_PFX "Table parsing has been initialized.\n"); |
231 | 241 | return; | |
232 | pr_info(HEST_PFX "HEST table parsing is initialized.\n"); | 242 | } |
233 | 243 | ||
234 | return 0; | ||
235 | err: | 244 | err: |
236 | hest_disable = 1; | 245 | hest_disable = 1; |
237 | return rc; | ||
238 | } | 246 | } |
239 | |||
240 | subsys_initcall(hest_init); | ||