mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-19 21:21:09 +00:00
Merge branches 'acpi-scan', 'acpi-osl' and 'acpi-apei'
* acpi-scan: ACPI / scan: AMBA bus probing support ACPI: introduce a function to find the first physical device * acpi-osl: ACPI / OSL: Add support to install tables via initrd ACPI / OSL: Clean up initrd table override code * acpi-apei: ACPI / APEI: ERST: Fixed leaked resources in erst_init ACPI / APEI: Fix leaked resources
This commit is contained in:
commit
caf5aa19f7
10 changed files with 275 additions and 100 deletions
|
@ -43,6 +43,7 @@ acpi-y += pci_root.o pci_link.o pci_irq.o
|
||||||
acpi-y += acpi_lpss.o acpi_apd.o
|
acpi-y += acpi_lpss.o acpi_apd.o
|
||||||
acpi-y += acpi_platform.o
|
acpi-y += acpi_platform.o
|
||||||
acpi-y += acpi_pnp.o
|
acpi-y += acpi_pnp.o
|
||||||
|
acpi-$(CONFIG_ARM_AMBA) += acpi_amba.o
|
||||||
acpi-y += int340x_thermal.o
|
acpi-y += int340x_thermal.o
|
||||||
acpi-y += power.o
|
acpi-y += power.o
|
||||||
acpi-y += event.o
|
acpi-y += event.o
|
||||||
|
|
122
drivers/acpi/acpi_amba.c
Normal file
122
drivers/acpi/acpi_amba.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACPI support for platform bus type.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015, Linaro Ltd
|
||||||
|
* Author: Graeme Gregory <graeme.gregory@linaro.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/amba/bus.h>
|
||||||
|
#include <linux/clkdev.h>
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
static const struct acpi_device_id amba_id_list[] = {
|
||||||
|
{"ARMH0061", 0}, /* PL061 GPIO Device */
|
||||||
|
{"", 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void amba_register_dummy_clk(void)
|
||||||
|
{
|
||||||
|
static struct clk *amba_dummy_clk;
|
||||||
|
|
||||||
|
/* If clock already registered */
|
||||||
|
if (amba_dummy_clk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL,
|
||||||
|
CLK_IS_ROOT, 0);
|
||||||
|
clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amba_handler_attach(struct acpi_device *adev,
|
||||||
|
const struct acpi_device_id *id)
|
||||||
|
{
|
||||||
|
struct amba_device *dev;
|
||||||
|
struct resource_entry *rentry;
|
||||||
|
struct list_head resource_list;
|
||||||
|
bool address_found = false;
|
||||||
|
int irq_no = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* If the ACPI node already has a physical device attached, skip it. */
|
||||||
|
if (adev->physical_node_count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev = amba_device_alloc(dev_name(&adev->dev), 0, 0);
|
||||||
|
if (!dev) {
|
||||||
|
dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n",
|
||||||
|
__func__);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&resource_list);
|
||||||
|
ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
list_for_each_entry(rentry, &resource_list, node) {
|
||||||
|
switch (resource_type(rentry->res)) {
|
||||||
|
case IORESOURCE_MEM:
|
||||||
|
if (!address_found) {
|
||||||
|
dev->res = *rentry->res;
|
||||||
|
address_found = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IORESOURCE_IRQ:
|
||||||
|
if (irq_no < AMBA_NR_IRQS)
|
||||||
|
dev->irq[irq_no++] = rentry->res->start;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(&adev->dev, "Invalid resource\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_dev_free_resource_list(&resource_list);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the ACPI node has a parent and that parent has a physical device
|
||||||
|
* attached to it, that physical device should be the parent of
|
||||||
|
* the amba device we are about to create.
|
||||||
|
*/
|
||||||
|
if (adev->parent)
|
||||||
|
dev->dev.parent = acpi_get_first_physical_node(adev->parent);
|
||||||
|
|
||||||
|
ACPI_COMPANION_SET(&dev->dev, adev);
|
||||||
|
|
||||||
|
ret = amba_device_add(dev, &iomem_resource);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&adev->dev, "%s(): amba_device_add() failed (%d)\n",
|
||||||
|
__func__, ret);
|
||||||
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
err_free:
|
||||||
|
amba_device_put(dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct acpi_scan_handler amba_handler = {
|
||||||
|
.ids = amba_id_list,
|
||||||
|
.attach = amba_handler_attach,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init acpi_amba_init(void)
|
||||||
|
{
|
||||||
|
amba_register_dummy_clk();
|
||||||
|
acpi_scan_add_handler(&amba_handler);
|
||||||
|
}
|
|
@ -43,7 +43,6 @@ static const struct acpi_device_id forbidden_id_list[] = {
|
||||||
struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
|
struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = NULL;
|
struct platform_device *pdev = NULL;
|
||||||
struct acpi_device *acpi_parent;
|
|
||||||
struct platform_device_info pdevinfo;
|
struct platform_device_info pdevinfo;
|
||||||
struct resource_entry *rentry;
|
struct resource_entry *rentry;
|
||||||
struct list_head resource_list;
|
struct list_head resource_list;
|
||||||
|
@ -82,22 +81,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
|
||||||
* attached to it, that physical device should be the parent of the
|
* attached to it, that physical device should be the parent of the
|
||||||
* platform device we are about to create.
|
* platform device we are about to create.
|
||||||
*/
|
*/
|
||||||
pdevinfo.parent = NULL;
|
pdevinfo.parent = adev->parent ?
|
||||||
acpi_parent = adev->parent;
|
acpi_get_first_physical_node(adev->parent) : NULL;
|
||||||
if (acpi_parent) {
|
|
||||||
struct acpi_device_physical_node *entry;
|
|
||||||
struct list_head *list;
|
|
||||||
|
|
||||||
mutex_lock(&acpi_parent->physical_node_lock);
|
|
||||||
list = &acpi_parent->physical_node_list;
|
|
||||||
if (!list_empty(list)) {
|
|
||||||
entry = list_first_entry(list,
|
|
||||||
struct acpi_device_physical_node,
|
|
||||||
node);
|
|
||||||
pdevinfo.parent = entry->dev;
|
|
||||||
}
|
|
||||||
mutex_unlock(&acpi_parent->physical_node_lock);
|
|
||||||
}
|
|
||||||
pdevinfo.name = dev_name(&adev->dev);
|
pdevinfo.name = dev_name(&adev->dev);
|
||||||
pdevinfo.id = -1;
|
pdevinfo.id = -1;
|
||||||
pdevinfo.res = resources;
|
pdevinfo.res = resources;
|
||||||
|
|
|
@ -536,7 +536,8 @@ int apei_resources_request(struct apei_resources *resources,
|
||||||
goto err_unmap_ioport;
|
goto err_unmap_ioport;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
goto arch_res_fini;
|
||||||
|
|
||||||
err_unmap_ioport:
|
err_unmap_ioport:
|
||||||
list_for_each_entry(res, &resources->ioport, list) {
|
list_for_each_entry(res, &resources->ioport, list) {
|
||||||
if (res == res_bak)
|
if (res == res_bak)
|
||||||
|
@ -551,6 +552,7 @@ err_unmap_iomem:
|
||||||
release_mem_region(res->start, res->end - res->start);
|
release_mem_region(res->start, res->end - res->start);
|
||||||
}
|
}
|
||||||
arch_res_fini:
|
arch_res_fini:
|
||||||
|
if (arch_apei_filter_addr)
|
||||||
apei_resources_fini(&arch_res);
|
apei_resources_fini(&arch_res);
|
||||||
nvs_res_fini:
|
nvs_res_fini:
|
||||||
apei_resources_fini(&nvs_resources);
|
apei_resources_fini(&nvs_resources);
|
||||||
|
|
|
@ -1207,6 +1207,9 @@ static int __init erst_init(void)
|
||||||
"Failed to allocate %lld bytes for persistent store error log.\n",
|
"Failed to allocate %lld bytes for persistent store error log.\n",
|
||||||
erst_erange.size);
|
erst_erange.size);
|
||||||
|
|
||||||
|
/* Cleanup ERST Resources */
|
||||||
|
apei_resources_fini(&erst_resources);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_release_erange:
|
err_release_erange:
|
||||||
|
|
|
@ -479,24 +479,38 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
|
||||||
Device Matching
|
Device Matching
|
||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static struct acpi_device *acpi_primary_dev_companion(struct acpi_device *adev,
|
/**
|
||||||
const struct device *dev)
|
* acpi_get_first_physical_node - Get first physical node of an ACPI device
|
||||||
|
* @adev: ACPI device in question
|
||||||
|
*
|
||||||
|
* Return: First physical node of ACPI device @adev
|
||||||
|
*/
|
||||||
|
struct device *acpi_get_first_physical_node(struct acpi_device *adev)
|
||||||
{
|
{
|
||||||
struct mutex *physical_node_lock = &adev->physical_node_lock;
|
struct mutex *physical_node_lock = &adev->physical_node_lock;
|
||||||
|
struct device *phys_dev;
|
||||||
|
|
||||||
mutex_lock(physical_node_lock);
|
mutex_lock(physical_node_lock);
|
||||||
if (list_empty(&adev->physical_node_list)) {
|
if (list_empty(&adev->physical_node_list)) {
|
||||||
adev = NULL;
|
phys_dev = NULL;
|
||||||
} else {
|
} else {
|
||||||
const struct acpi_device_physical_node *node;
|
const struct acpi_device_physical_node *node;
|
||||||
|
|
||||||
node = list_first_entry(&adev->physical_node_list,
|
node = list_first_entry(&adev->physical_node_list,
|
||||||
struct acpi_device_physical_node, node);
|
struct acpi_device_physical_node, node);
|
||||||
if (node->dev != dev)
|
|
||||||
adev = NULL;
|
phys_dev = node->dev;
|
||||||
}
|
}
|
||||||
mutex_unlock(physical_node_lock);
|
mutex_unlock(physical_node_lock);
|
||||||
return adev;
|
return phys_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct acpi_device *acpi_primary_dev_companion(struct acpi_device *adev,
|
||||||
|
const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct device *phys_dev = acpi_get_first_physical_node(adev);
|
||||||
|
|
||||||
|
return phys_dev && phys_dev == dev ? adev : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#define PREFIX "ACPI: "
|
#define PREFIX "ACPI: "
|
||||||
|
|
||||||
|
void acpi_initrd_initialize_tables(void);
|
||||||
acpi_status acpi_os_initialize1(void);
|
acpi_status acpi_os_initialize1(void);
|
||||||
void init_acpi_device_notify(void);
|
void init_acpi_device_notify(void);
|
||||||
int acpi_scan_init(void);
|
int acpi_scan_init(void);
|
||||||
|
@ -29,6 +30,11 @@ void acpi_processor_init(void);
|
||||||
void acpi_platform_init(void);
|
void acpi_platform_init(void);
|
||||||
void acpi_pnp_init(void);
|
void acpi_pnp_init(void);
|
||||||
void acpi_int340x_thermal_init(void);
|
void acpi_int340x_thermal_init(void);
|
||||||
|
#ifdef CONFIG_ARM_AMBA
|
||||||
|
void acpi_amba_init(void);
|
||||||
|
#else
|
||||||
|
static inline void acpi_amba_init(void) {}
|
||||||
|
#endif
|
||||||
int acpi_sysfs_init(void);
|
int acpi_sysfs_init(void);
|
||||||
void acpi_container_init(void);
|
void acpi_container_init(void);
|
||||||
void acpi_memory_hotplug_init(void);
|
void acpi_memory_hotplug_init(void);
|
||||||
|
@ -106,6 +112,7 @@ bool acpi_device_is_present(struct acpi_device *adev);
|
||||||
bool acpi_device_is_battery(struct acpi_device *adev);
|
bool acpi_device_is_battery(struct acpi_device *adev);
|
||||||
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
|
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
|
||||||
const struct device *dev);
|
const struct device *dev);
|
||||||
|
struct device *acpi_get_first_physical_node(struct acpi_device *adev);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
Device Matching and Notification
|
Device Matching and Notification
|
||||||
|
|
|
@ -602,6 +602,14 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void acpi_table_taint(struct acpi_table_header *table)
|
||||||
|
{
|
||||||
|
pr_warn(PREFIX
|
||||||
|
"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
|
||||||
|
table->signature, table->oem_table_id);
|
||||||
|
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
|
#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
|
||||||
#include <linux/earlycpio.h>
|
#include <linux/earlycpio.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
|
@ -636,6 +644,7 @@ static const char * const table_sigs[] = {
|
||||||
|
|
||||||
#define ACPI_OVERRIDE_TABLES 64
|
#define ACPI_OVERRIDE_TABLES 64
|
||||||
static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
|
static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
|
||||||
|
static DECLARE_BITMAP(acpi_initrd_installed, ACPI_OVERRIDE_TABLES);
|
||||||
|
|
||||||
#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
|
#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
|
||||||
|
|
||||||
|
@ -746,20 +755,112 @@ void __init acpi_initrd_override(void *data, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
|
|
||||||
|
|
||||||
static void acpi_table_taint(struct acpi_table_header *table)
|
|
||||||
{
|
|
||||||
pr_warn(PREFIX
|
|
||||||
"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
|
|
||||||
table->signature, table->oem_table_id);
|
|
||||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_os_table_override(struct acpi_table_header * existing_table,
|
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
|
||||||
struct acpi_table_header ** new_table)
|
acpi_physical_address *address, u32 *length)
|
||||||
|
{
|
||||||
|
int table_offset = 0;
|
||||||
|
int table_index = 0;
|
||||||
|
struct acpi_table_header *table;
|
||||||
|
u32 table_length;
|
||||||
|
|
||||||
|
*length = 0;
|
||||||
|
*address = 0;
|
||||||
|
if (!acpi_tables_addr)
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
|
||||||
|
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
|
||||||
|
ACPI_HEADER_SIZE);
|
||||||
|
if (table_offset + table->length > all_tables_size) {
|
||||||
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
|
WARN_ON(1);
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
table_length = table->length;
|
||||||
|
|
||||||
|
/* Only override tables matched */
|
||||||
|
if (test_bit(table_index, acpi_initrd_installed) ||
|
||||||
|
memcmp(existing_table->signature, table->signature, 4) ||
|
||||||
|
memcmp(table->oem_table_id, existing_table->oem_table_id,
|
||||||
|
ACPI_OEM_TABLE_ID_SIZE)) {
|
||||||
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
|
goto next_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
*length = table_length;
|
||||||
|
*address = acpi_tables_addr + table_offset;
|
||||||
|
acpi_table_taint(existing_table);
|
||||||
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
|
set_bit(table_index, acpi_initrd_installed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
next_table:
|
||||||
|
table_offset += table_length;
|
||||||
|
table_index++;
|
||||||
|
}
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init acpi_initrd_initialize_tables(void)
|
||||||
|
{
|
||||||
|
int table_offset = 0;
|
||||||
|
int table_index = 0;
|
||||||
|
u32 table_length;
|
||||||
|
struct acpi_table_header *table;
|
||||||
|
|
||||||
|
if (!acpi_tables_addr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
|
||||||
|
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
|
||||||
|
ACPI_HEADER_SIZE);
|
||||||
|
if (table_offset + table->length > all_tables_size) {
|
||||||
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
|
WARN_ON(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
table_length = table->length;
|
||||||
|
|
||||||
|
/* Skip RSDT/XSDT which should only be used for override */
|
||||||
|
if (test_bit(table_index, acpi_initrd_installed) ||
|
||||||
|
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) ||
|
||||||
|
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) {
|
||||||
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
|
goto next_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_table_taint(table);
|
||||||
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
|
acpi_install_table(acpi_tables_addr + table_offset, TRUE);
|
||||||
|
set_bit(table_index, acpi_initrd_installed);
|
||||||
|
next_table:
|
||||||
|
table_offset += table_length;
|
||||||
|
table_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
acpi_status
|
||||||
|
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
|
||||||
|
acpi_physical_address *address,
|
||||||
|
u32 *table_length)
|
||||||
|
{
|
||||||
|
*table_length = 0;
|
||||||
|
*address = 0;
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init acpi_initrd_initialize_tables(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_os_table_override(struct acpi_table_header *existing_table,
|
||||||
|
struct acpi_table_header **new_table)
|
||||||
{
|
{
|
||||||
if (!existing_table || !new_table)
|
if (!existing_table || !new_table)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
@ -775,69 +876,6 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
|
|
||||||
acpi_physical_address *address,
|
|
||||||
u32 *table_length)
|
|
||||||
{
|
|
||||||
#ifndef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
|
|
||||||
*table_length = 0;
|
|
||||||
*address = 0;
|
|
||||||
return AE_OK;
|
|
||||||
#else
|
|
||||||
int table_offset = 0;
|
|
||||||
struct acpi_table_header *table;
|
|
||||||
|
|
||||||
*table_length = 0;
|
|
||||||
*address = 0;
|
|
||||||
|
|
||||||
if (!acpi_tables_addr)
|
|
||||||
return AE_OK;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (table_offset + ACPI_HEADER_SIZE > all_tables_size) {
|
|
||||||
WARN_ON(1);
|
|
||||||
return AE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
|
|
||||||
ACPI_HEADER_SIZE);
|
|
||||||
|
|
||||||
if (table_offset + table->length > all_tables_size) {
|
|
||||||
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
|
||||||
WARN_ON(1);
|
|
||||||
return AE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
table_offset += table->length;
|
|
||||||
|
|
||||||
if (memcmp(existing_table->signature, table->signature, 4)) {
|
|
||||||
acpi_os_unmap_memory(table,
|
|
||||||
ACPI_HEADER_SIZE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only override tables with matching oem id */
|
|
||||||
if (memcmp(table->oem_table_id, existing_table->oem_table_id,
|
|
||||||
ACPI_OEM_TABLE_ID_SIZE)) {
|
|
||||||
acpi_os_unmap_memory(table,
|
|
||||||
ACPI_HEADER_SIZE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
table_offset -= table->length;
|
|
||||||
*table_length = table->length;
|
|
||||||
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
|
||||||
*address = acpi_tables_addr + table_offset;
|
|
||||||
break;
|
|
||||||
} while (table_offset + ACPI_HEADER_SIZE < all_tables_size);
|
|
||||||
|
|
||||||
if (*address != 0)
|
|
||||||
acpi_table_taint(existing_table);
|
|
||||||
return AE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
u32 handled;
|
u32 handled;
|
||||||
|
|
|
@ -1930,6 +1930,7 @@ int __init acpi_scan_init(void)
|
||||||
acpi_memory_hotplug_init();
|
acpi_memory_hotplug_init();
|
||||||
acpi_pnp_init();
|
acpi_pnp_init();
|
||||||
acpi_int340x_thermal_init();
|
acpi_int340x_thermal_init();
|
||||||
|
acpi_amba_init();
|
||||||
|
|
||||||
acpi_scan_add_handler(&generic_device_handler);
|
acpi_scan_add_handler(&generic_device_handler);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
#define ACPI_MAX_TABLES 128
|
#define ACPI_MAX_TABLES 128
|
||||||
|
|
||||||
|
@ -456,6 +457,7 @@ int __init acpi_table_init(void)
|
||||||
status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
|
status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
acpi_initrd_initialize_tables();
|
||||||
|
|
||||||
check_multiple_madt();
|
check_multiple_madt();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue