aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/Kconfig13
-rw-r--r--drivers/acpi/osl.c8
-rw-r--r--drivers/acpi/tables.c68
-rw-r--r--drivers/acpi/utils.c5
-rw-r--r--include/linux/acpi.h4
5 files changed, 67 insertions, 31 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index b23fe37f67c0..79078b8f5697 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -360,15 +360,14 @@ config ACPI_BGRT
360config ACPI_REDUCED_HARDWARE_ONLY 360config ACPI_REDUCED_HARDWARE_ONLY
361 bool "Hardware-reduced ACPI support only" if EXPERT 361 bool "Hardware-reduced ACPI support only" if EXPERT
362 def_bool n 362 def_bool n
363 depends on ACPI
364 help 363 help
365 This config item changes the way the ACPI code is built. When this 364 This config item changes the way the ACPI code is built. When this
366 option is selected, the kernel will use a specialized version of 365 option is selected, the kernel will use a specialized version of
367 ACPICA that ONLY supports the ACPI "reduced hardware" mode. The 366 ACPICA that ONLY supports the ACPI "reduced hardware" mode. The
368 resulting kernel will be smaller but it will also be restricted to 367 resulting kernel will be smaller but it will also be restricted to
369 running in ACPI reduced hardware mode ONLY. 368 running in ACPI reduced hardware mode ONLY.
370 369
371 If you are unsure what to do, do not enable this option. 370 If you are unsure what to do, do not enable this option.
372 371
373source "drivers/acpi/apei/Kconfig" 372source "drivers/acpi/apei/Kconfig"
374 373
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 9964f70be98d..f9eeae871593 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -436,7 +436,7 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
436static void acpi_os_map_cleanup(struct acpi_ioremap *map) 436static void acpi_os_map_cleanup(struct acpi_ioremap *map)
437{ 437{
438 if (!map->refcount) { 438 if (!map->refcount) {
439 synchronize_rcu(); 439 synchronize_rcu_expedited();
440 acpi_unmap(map->phys, map->virt); 440 acpi_unmap(map->phys, map->virt);
441 kfree(map); 441 kfree(map);
442 } 442 }
@@ -1188,6 +1188,12 @@ EXPORT_SYMBOL(acpi_os_execute);
1188 1188
1189void acpi_os_wait_events_complete(void) 1189void acpi_os_wait_events_complete(void)
1190{ 1190{
1191 /*
1192 * Make sure the GPE handler or the fixed event handler is not used
1193 * on another CPU after removal.
1194 */
1195 if (acpi_irq_handler)
1196 synchronize_hardirq(acpi_gbl_FADT.sci_interrupt);
1191 flush_workqueue(kacpid_wq); 1197 flush_workqueue(kacpid_wq);
1192 flush_workqueue(kacpi_notify_wq); 1198 flush_workqueue(kacpi_notify_wq);
1193} 1199}
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 6d5a6cda0734..93b81523a2fe 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -190,30 +190,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
190 } 190 }
191} 191}
192 192
193
194int __init 193int __init
195acpi_table_parse_entries(char *id, 194acpi_parse_entries(char *id, unsigned long table_size,
196 unsigned long table_size, 195 acpi_tbl_entry_handler handler,
197 int entry_id, 196 struct acpi_table_header *table_header,
198 acpi_tbl_entry_handler handler, 197 int entry_id, unsigned int max_entries)
199 unsigned int max_entries)
200{ 198{
201 struct acpi_table_header *table_header = NULL;
202 struct acpi_subtable_header *entry; 199 struct acpi_subtable_header *entry;
203 unsigned int count = 0; 200 int count = 0;
204 unsigned long table_end; 201 unsigned long table_end;
205 acpi_size tbl_size;
206 202
207 if (acpi_disabled) 203 if (acpi_disabled)
208 return -ENODEV; 204 return -ENODEV;
209 205
210 if (!handler) 206 if (!id || !handler)
211 return -EINVAL; 207 return -EINVAL;
212 208
213 if (strncmp(id, ACPI_SIG_MADT, 4) == 0) 209 if (!table_size)
214 acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); 210 return -EINVAL;
215 else
216 acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
217 211
218 if (!table_header) { 212 if (!table_header) {
219 pr_warn("%4.4s not present\n", id); 213 pr_warn("%4.4s not present\n", id);
@@ -230,9 +224,12 @@ acpi_table_parse_entries(char *id,
230 while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < 224 while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
231 table_end) { 225 table_end) {
232 if (entry->type == entry_id 226 if (entry->type == entry_id
233 && (!max_entries || count++ < max_entries)) 227 && (!max_entries || count < max_entries)) {
234 if (handler(entry, table_end)) 228 if (handler(entry, table_end))
235 goto err; 229 return -EINVAL;
230
231 count++;
232 }
236 233
237 /* 234 /*
238 * If entry->length is 0, break from this loop to avoid 235 * If entry->length is 0, break from this loop to avoid
@@ -240,22 +237,53 @@ acpi_table_parse_entries(char *id,
240 */ 237 */
241 if (entry->length == 0) { 238 if (entry->length == 0) {
242 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); 239 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
243 goto err; 240 return -EINVAL;
244 } 241 }
245 242
246 entry = (struct acpi_subtable_header *) 243 entry = (struct acpi_subtable_header *)
247 ((unsigned long)entry + entry->length); 244 ((unsigned long)entry + entry->length);
248 } 245 }
246
249 if (max_entries && count > max_entries) { 247 if (max_entries && count > max_entries) {
250 pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", 248 pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
251 id, entry_id, count - max_entries, count); 249 id, entry_id, count - max_entries, count);
252 } 250 }
253 251
254 early_acpi_os_unmap_memory((char *)table_header, tbl_size);
255 return count; 252 return count;
256err: 253}
254
255int __init
256acpi_table_parse_entries(char *id,
257 unsigned long table_size,
258 int entry_id,
259 acpi_tbl_entry_handler handler,
260 unsigned int max_entries)
261{
262 struct acpi_table_header *table_header = NULL;
263 acpi_size tbl_size;
264 int count;
265 u32 instance = 0;
266
267 if (acpi_disabled)
268 return -ENODEV;
269
270 if (!id || !handler)
271 return -EINVAL;
272
273 if (!strncmp(id, ACPI_SIG_MADT, 4))
274 instance = acpi_apic_instance;
275
276 acpi_get_table_with_size(id, instance, &table_header, &tbl_size);
277 if (!table_header) {
278 pr_warn("%4.4s not present\n", id);
279 return -ENODEV;
280 }
281
282 count = acpi_parse_entries(id, table_size, handler, table_header,
283 entry_id, max_entries);
284
257 early_acpi_os_unmap_memory((char *)table_header, tbl_size); 285 early_acpi_os_unmap_memory((char *)table_header, tbl_size);
258 return -EINVAL; 286 return count;
259} 287}
260 288
261int __init 289int __init
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 371ac12d25b1..dd8ff63ee2b4 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -136,8 +136,7 @@ acpi_extract_package(union acpi_object *package,
136 break; 136 break;
137 case 'B': 137 case 'B':
138 size_required += 138 size_required +=
139 sizeof(u8 *) + 139 sizeof(u8 *) + element->buffer.length;
140 (element->buffer.length * sizeof(u8));
141 tail_offset += sizeof(u8 *); 140 tail_offset += sizeof(u8 *);
142 break; 141 break;
143 default: 142 default:
@@ -255,7 +254,7 @@ acpi_extract_package(union acpi_object *package,
255 memcpy(tail, element->buffer.pointer, 254 memcpy(tail, element->buffer.pointer,
256 element->buffer.length); 255 element->buffer.length);
257 head += sizeof(u8 *); 256 head += sizeof(u8 *);
258 tail += element->buffer.length * sizeof(u8); 257 tail += element->buffer.length;
259 break; 258 break;
260 default: 259 default:
261 /* Should never get here */ 260 /* Should never get here */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 10f2ed95645c..0ccaa093010c 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -124,6 +124,10 @@ int acpi_numa_init (void);
124 124
125int acpi_table_init (void); 125int acpi_table_init (void);
126int acpi_table_parse(char *id, acpi_tbl_table_handler handler); 126int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
127int __init acpi_parse_entries(char *id, unsigned long table_size,
128 acpi_tbl_entry_handler handler,
129 struct acpi_table_header *table_header,
130 int entry_id, unsigned int max_entries);
127int __init acpi_table_parse_entries(char *id, unsigned long table_size, 131int __init acpi_table_parse_entries(char *id, unsigned long table_size,
128 int entry_id, 132 int entry_id,
129 acpi_tbl_entry_handler handler, 133 acpi_tbl_entry_handler handler,