From: Al Stone al.stone@linaro.org
Start to add ACPI initialisation calls to the arch/arm files.
This does not yet perform an actual ACPI initialisation.
Signed-off-by: Al Stone al.stone@linaro.org Signed-off-by: Graeme Gregory graeme.gregory@linaro.org --- drivers/acpi/bus.c | 4 +++ drivers/acpi/osl.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/of/fdt.c | 52 ++++++++++++++++++++++++++++++++++++++- include/linux/of_fdt.h | 4 +++ 4 files changed, 123 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 303c4ac..db6c0c6 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -79,6 +79,10 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = { }, {} }; +#else +static struct dmi_system_id dsdt_dmi_table[] __initdata = { + {} +}; #endif
/* -------------------------------------------------------------------------- diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index ab57f09..dc0987e 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -242,6 +242,65 @@ static int __init setup_acpi_rsdp(char *arg) early_param("acpi_rsdp", setup_acpi_rsdp); #endif
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +#include <asm/acpi.h> +#include <acpi/actbl.h> + +void acpi_find_arm_root_pointer(acpi_physical_address *pa) +{ + /* BOZO: temporarily clunky. + * What we do is, while using u-boot still, is use the values + * that have already been retrieved from the FDT node + * (/chosen/linux,acpi-start and /chosen/linux,acpi-len) which + * contain the address of the first byte of the RSDP after it + * has been loaded into RAM during u-boot (e.g., using something + * like fatload mmc 0:2 42008000 my.blob), and the size of the + * data in the complete ACPI blob. We only do this since we have + * to collaborate with FDT so we have to load FDT and the ACPI + * tables in but only have one address we can use via bootm. + * With UEFI, we should just be able to use the efi_enabled + * branch below in acpi_os_get_root_pointer(). + */ + + void *address; + struct acpi_table_rsdp *rp; + + if (!acpi_arm_rsdp_info.phys_address && !acpi_arm_rsdp_info.size) { + printk(KERN_ERR "(E) ACPI: failed to find rsdp info\n"); + *pa = (acpi_physical_address)NULL; + return; + } + + address = phys_to_virt(acpi_arm_rsdp_info.phys_address); + address += ACPI_BLOB_HEADER_SIZE; + *pa = (acpi_physical_address)address; + + rp = (struct acpi_table_rsdp *)address; + printk(KERN_DEBUG "(I) ACPI rsdp rp: 0x%08lx\n", (long unsigned int)rp); + if (rp) { + printk(KERN_DEBUG "(I) ACPI rsdp content:\n"); + printk(KERN_DEBUG "(I) signature: %.8s\n", rp->signature); + printk(KERN_DEBUG "(I) checksum: 0x%02x\n", rp->checksum); + printk(KERN_DEBUG "(I) oem_id: %.6s\n", rp->oem_id); + printk(KERN_DEBUG "(I) revision: %d\n", rp->revision); + printk(KERN_DEBUG "(I) rsdt: 0x%08lX\n", + (long unsigned int)rp->rsdt_physical_address); + printk(KERN_DEBUG "(I) length: %d\n", rp->length); + printk(KERN_DEBUG "(I) xsdt: 0x%016llX\n", + (u64)rp->xsdt_physical_address); + printk(KERN_DEBUG "(I) x_checksum: 0x%02x\n", + rp->extended_checksum); + + *pa = (acpi_physical_address)(virt_to_phys(rp)); + } else { + printk(KERN_ERR "(E) ACPI missing rsdp info\n"); + *pa = (acpi_physical_address)NULL; + } + + return; +} +#endif + acpi_physical_address __init acpi_os_get_root_pointer(void) { #ifdef CONFIG_KEXEC @@ -262,7 +321,11 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) } else { acpi_physical_address pa = 0;
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) + acpi_find_arm_root_pointer(&pa); +#else acpi_find_root_pointer(&pa); +#endif return pa; } } @@ -372,6 +435,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) return __acpi_map_table((unsigned long)phys, size);
mutex_lock(&acpi_ioremap_lock); + /* Check if there's a suitable mapping already. */ map = acpi_map_lookup(phys, size); if (map) { diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 808be06..0535169 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -696,6 +696,56 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, return 1; }
+#if (defined(CONFIG_ARM64) || defined (CONFIG_ARM)) && defined(CONFIG_ACPI) +#include <linux/memblock.h> +#include <linux/acpi.h> +#include <asm/acpi.h> +#include <acpi/actbl.h> + +int __init early_init_dt_scan_acpi(unsigned long node, const char *uname, + int depth, void *data) +{ + unsigned long l; + unsigned int *p; + struct acpi_arm_root *pinfo; + unsigned char *sig; + + pr_debug("search "chosen" for acpi info, depth: %d, uname: %s\n", + depth, uname); + + if (depth != 1 || !data || + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) + return 0; + + /* Retrieve acpi,address line */ + pinfo = (struct acpi_arm_root *)data; + p = of_get_flat_dt_prop(node, "linux,acpi-start", &l); + if (p != NULL && l > 0) + pinfo->phys_address = be32_to_cpu(*p); + + /* Retrieve acpi,size line */ + p = of_get_flat_dt_prop(node, "linux,acpi-len", &l); + if (p != NULL && l > 0) + pinfo->size = be32_to_cpu(*p); + + printk("acpi: start info is 0x%016llX, %lu bytes\n", + pinfo->phys_address, pinfo->size); + + memblock_reserve(pinfo->phys_address, pinfo->size); + + sig = phys_to_virt(pinfo->phys_address); + + printk("acpi: sig is "%c%c%c%c"\n", + sig[0], sig[1], sig[2], sig[3]); + printk("acpi: info is %02x %02x %02x %02x\n", + sig[4], sig[5], sig[6], sig[7]); + printk("acpi: first table is "%c%c%c%c"\n", + sig[8], sig[9], sig[10], sig[11]); + + return 1; +} +#endif + /** * unflatten_device_tree - create tree of device_nodes from flat blob * @@ -707,7 +757,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, void __init unflatten_device_tree(void) { __unflatten_device_tree(initial_boot_params, &of_allnodes, - early_init_dt_alloc_memory_arch); + early_init_dt_alloc_memory_arch);
/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */ of_alias_scan(early_init_dt_alloc_memory_arch); diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index ed136ad..98c1029 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -93,6 +93,10 @@ extern unsigned long of_get_flat_dt_root(void);
extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data); +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +extern int early_init_dt_scan_acpi(unsigned long node, const char *uname, + int depth, void *data); +#endif extern void early_init_dt_check_for_initrd(unsigned long node); extern int early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data);