diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-28 01:13:29 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-28 01:13:29 +0100 |
commit | 3f66c315f5929d0ad19d8e9d29c8001543aa9be2 (patch) | |
tree | 61a61a3d6558963d1dc6583e3ea67632560cf9c0 /drivers | |
parent | 5c2aae8355f7ec1341d5c473c500a77bbfa7f701 (diff) | |
parent | bee7f9c83e1d18af6fee06b97b6558cbd1cded45 (diff) | |
download | blackbird-op-linux-3f66c315f5929d0ad19d8e9d29c8001543aa9be2.tar.gz blackbird-op-linux-3f66c315f5929d0ad19d8e9d29c8001543aa9be2.zip |
Merge branch 'acpi-tables'
* acpi-tables:
ACPI / x86: Increase override tables number limit
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/osl.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e5f416c7f66e..88bb9d05b038 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -569,8 +569,10 @@ static const char * const table_sigs[] = { #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) -/* Must not increase 10 or needs code modification below */ -#define ACPI_OVERRIDE_TABLES 10 +#define ACPI_OVERRIDE_TABLES 64 +static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES]; + +#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT) void __init acpi_initrd_override(void *data, size_t size) { @@ -579,8 +581,6 @@ void __init acpi_initrd_override(void *data, size_t size) struct acpi_table_header *table; char cpio_path[32] = "kernel/firmware/acpi/"; struct cpio_data file; - struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES]; - char *p; if (data == NULL || size == 0) return; @@ -625,8 +625,8 @@ void __init acpi_initrd_override(void *data, size_t size) table->signature, cpio_path, file.name, table->length); all_tables_size += table->length; - early_initrd_files[table_nr].data = file.data; - early_initrd_files[table_nr].size = file.size; + acpi_initrd_files[table_nr].data = file.data; + acpi_initrd_files[table_nr].size = file.size; table_nr++; } if (table_nr == 0) @@ -652,14 +652,34 @@ void __init acpi_initrd_override(void *data, size_t size) memblock_reserve(acpi_tables_addr, all_tables_size); arch_reserve_mem_area(acpi_tables_addr, all_tables_size); - p = early_ioremap(acpi_tables_addr, all_tables_size); - + /* + * early_ioremap only can remap 256k one time. If we map all + * tables one time, we will hit the limit. Need to map chunks + * one by one during copying the same as that in relocate_initrd(). + */ for (no = 0; no < table_nr; no++) { - memcpy(p + total_offset, early_initrd_files[no].data, - early_initrd_files[no].size); - total_offset += early_initrd_files[no].size; + unsigned char *src_p = acpi_initrd_files[no].data; + phys_addr_t size = acpi_initrd_files[no].size; + phys_addr_t dest_addr = acpi_tables_addr + total_offset; + phys_addr_t slop, clen; + char *dest_p; + + total_offset += size; + + while (size) { + slop = dest_addr & ~PAGE_MASK; + clen = size; + if (clen > MAP_CHUNK_SIZE - slop) + clen = MAP_CHUNK_SIZE - slop; + dest_p = early_ioremap(dest_addr & PAGE_MASK, + clen + slop); + memcpy(dest_p + slop, src_p, clen); + early_iounmap(dest_p, clen + slop); + src_p += clen; + dest_addr += clen; + size -= clen; + } } - early_iounmap(p, all_tables_size); } #endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */ |