Commit a2d2696c authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'acpi-config', 'acpi-osl', 'acpi-utils' and 'acpi-tables'

* acpi-config:
  ACPI / Kconfig: Remove redundant depends on ACPI

* acpi-osl:
  ACPI / OSL: Add IRQ handler flushing support in the OSL.
  ACPI / osl: speedup grace period in acpi_os_map_cleanup

* acpi-utils:
  ACPI: remove unnecessary sizeof(u8)

* acpi-tables:
  ACPI / table: Always count matched and successfully parsed entries
  ACPI / table: Add new function to get table entries
...@@ -360,7 +360,6 @@ config ACPI_BGRT ...@@ -360,7 +360,6 @@ config ACPI_BGRT
config ACPI_REDUCED_HARDWARE_ONLY config ACPI_REDUCED_HARDWARE_ONLY
bool "Hardware-reduced ACPI support only" if EXPERT bool "Hardware-reduced ACPI support only" if EXPERT
def_bool n def_bool n
depends on ACPI
help help
This config item changes the way the ACPI code is built. When this This config item changes the way the ACPI code is built. When this
option is selected, the kernel will use a specialized version of option is selected, the kernel will use a specialized version of
......
...@@ -436,7 +436,7 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map) ...@@ -436,7 +436,7 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
static void acpi_os_map_cleanup(struct acpi_ioremap *map) static void acpi_os_map_cleanup(struct acpi_ioremap *map)
{ {
if (!map->refcount) { if (!map->refcount) {
synchronize_rcu(); synchronize_rcu_expedited();
acpi_unmap(map->phys, map->virt); acpi_unmap(map->phys, map->virt);
kfree(map); kfree(map);
} }
...@@ -1188,6 +1188,12 @@ EXPORT_SYMBOL(acpi_os_execute); ...@@ -1188,6 +1188,12 @@ EXPORT_SYMBOL(acpi_os_execute);
void acpi_os_wait_events_complete(void) void acpi_os_wait_events_complete(void)
{ {
/*
* Make sure the GPE handler or the fixed event handler is not used
* on another CPU after removal.
*/
if (acpi_irq_handler)
synchronize_hardirq(acpi_gbl_FADT.sci_interrupt);
flush_workqueue(kacpid_wq); flush_workqueue(kacpid_wq);
flush_workqueue(kacpi_notify_wq); flush_workqueue(kacpi_notify_wq);
} }
......
...@@ -190,30 +190,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) ...@@ -190,30 +190,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
} }
} }
int __init int __init
acpi_table_parse_entries(char *id, acpi_parse_entries(char *id, unsigned long table_size,
unsigned long table_size,
int entry_id,
acpi_tbl_entry_handler handler, acpi_tbl_entry_handler handler,
unsigned int max_entries) struct acpi_table_header *table_header,
int entry_id, unsigned int max_entries)
{ {
struct acpi_table_header *table_header = NULL;
struct acpi_subtable_header *entry; struct acpi_subtable_header *entry;
unsigned int count = 0; int count = 0;
unsigned long table_end; unsigned long table_end;
acpi_size tbl_size;
if (acpi_disabled) if (acpi_disabled)
return -ENODEV; return -ENODEV;
if (!handler) if (!id || !handler)
return -EINVAL; return -EINVAL;
if (strncmp(id, ACPI_SIG_MADT, 4) == 0) if (!table_size)
acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); return -EINVAL;
else
acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
if (!table_header) { if (!table_header) {
pr_warn("%4.4s not present\n", id); pr_warn("%4.4s not present\n", id);
...@@ -230,9 +224,12 @@ acpi_table_parse_entries(char *id, ...@@ -230,9 +224,12 @@ acpi_table_parse_entries(char *id,
while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
table_end) { table_end) {
if (entry->type == entry_id if (entry->type == entry_id
&& (!max_entries || count++ < max_entries)) && (!max_entries || count < max_entries)) {
if (handler(entry, table_end)) if (handler(entry, table_end))
goto err; return -EINVAL;
count++;
}
/* /*
* If entry->length is 0, break from this loop to avoid * If entry->length is 0, break from this loop to avoid
...@@ -240,22 +237,53 @@ acpi_table_parse_entries(char *id, ...@@ -240,22 +237,53 @@ acpi_table_parse_entries(char *id,
*/ */
if (entry->length == 0) { if (entry->length == 0) {
pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
goto err; return -EINVAL;
} }
entry = (struct acpi_subtable_header *) entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length); ((unsigned long)entry + entry->length);
} }
if (max_entries && count > max_entries) { if (max_entries && count > max_entries) {
pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
id, entry_id, count - max_entries, count); id, entry_id, count - max_entries, count);
} }
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return count; return count;
err: }
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
int __init
acpi_table_parse_entries(char *id,
unsigned long table_size,
int entry_id,
acpi_tbl_entry_handler handler,
unsigned int max_entries)
{
struct acpi_table_header *table_header = NULL;
acpi_size tbl_size;
int count;
u32 instance = 0;
if (acpi_disabled)
return -ENODEV;
if (!id || !handler)
return -EINVAL; return -EINVAL;
if (!strncmp(id, ACPI_SIG_MADT, 4))
instance = acpi_apic_instance;
acpi_get_table_with_size(id, instance, &table_header, &tbl_size);
if (!table_header) {
pr_warn("%4.4s not present\n", id);
return -ENODEV;
}
count = acpi_parse_entries(id, table_size, handler, table_header,
entry_id, max_entries);
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return count;
} }
int __init int __init
......
...@@ -136,8 +136,7 @@ acpi_extract_package(union acpi_object *package, ...@@ -136,8 +136,7 @@ acpi_extract_package(union acpi_object *package,
break; break;
case 'B': case 'B':
size_required += size_required +=
sizeof(u8 *) + sizeof(u8 *) + element->buffer.length;
(element->buffer.length * sizeof(u8));
tail_offset += sizeof(u8 *); tail_offset += sizeof(u8 *);
break; break;
default: default:
...@@ -255,7 +254,7 @@ acpi_extract_package(union acpi_object *package, ...@@ -255,7 +254,7 @@ acpi_extract_package(union acpi_object *package,
memcpy(tail, element->buffer.pointer, memcpy(tail, element->buffer.pointer,
element->buffer.length); element->buffer.length);
head += sizeof(u8 *); head += sizeof(u8 *);
tail += element->buffer.length * sizeof(u8); tail += element->buffer.length;
break; break;
default: default:
/* Should never get here */ /* Should never get here */
......
...@@ -124,6 +124,10 @@ int acpi_numa_init (void); ...@@ -124,6 +124,10 @@ int acpi_numa_init (void);
int acpi_table_init (void); int acpi_table_init (void);
int acpi_table_parse(char *id, acpi_tbl_table_handler handler); int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
int __init acpi_parse_entries(char *id, unsigned long table_size,
acpi_tbl_entry_handler handler,
struct acpi_table_header *table_header,
int entry_id, unsigned int max_entries);
int __init acpi_table_parse_entries(char *id, unsigned long table_size, int __init acpi_table_parse_entries(char *id, unsigned long table_size,
int entry_id, int entry_id,
acpi_tbl_entry_handler handler, acpi_tbl_entry_handler handler,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment