lib: acpi: add device resource enum support
add device resource enumaration support such as irq and mmio. Signed-off-by: Najumon B.A <najumon.ba@intel.com>
This commit is contained in:
parent
dd9e0df06b
commit
2f3fb49d76
23
dts/bindings/acpi/acpi.yaml
Normal file
23
dts/bindings/acpi/acpi.yaml
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright (c) 2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Common fields for ACPI informed based devices
|
||||
|
||||
properties:
|
||||
acpi-hid:
|
||||
type: string
|
||||
description: Used to supply OSPM with the device’s PNP ID or ACPI ID.
|
||||
A node is consder as acpi based or not based on whether this property
|
||||
is present or not.
|
||||
|
||||
acpi-uid:
|
||||
type: string
|
||||
description: |
|
||||
Provides OSPM with a logical device ID that does not change
|
||||
across reboots. This object is optional, but is required when the device
|
||||
has no other way to report a persistent unique device ID. The _UID must be
|
||||
unique across all devices with either a common _HID or _CID.
|
||||
|
||||
acpi-comp-id:
|
||||
type: string-array
|
||||
description: Used to supply OSPM with a device’s Plug and Play-Compatible Device ID
|
|
@ -15,10 +15,30 @@
|
|||
#define ACPI_DMAR_FLAG_X2APIC_OPT_OUT BIT(1)
|
||||
#define ACPI_DMAR_FLAG_DMA_CTRL_PLATFORM_OPT_IN BIT(2)
|
||||
|
||||
#define ACPI_MMIO_GET(res) (res)->reg_base[0].mmio
|
||||
#define ACPI_IO_GET(res) (res)->reg_base[0].port
|
||||
#define ACPI_RESOURCE_SIZE_GET(res) (res)->reg_base[0].length
|
||||
#define ACPI_RESOURCE_TYPE_GET(res) (res)->reg_base[0].type
|
||||
|
||||
#define ACPI_MULTI_MMIO_GET(res, idx) (res)->reg_base[idx].mmio
|
||||
#define ACPI_MULTI_IO_GET(res, idx) (res)->reg_base[idx].port
|
||||
#define ACPI_MULTI_RESOURCE_SIZE_GET(res, idx) (res)->reg_base[idx].length
|
||||
#define ACPI_MULTI_RESOURCE_TYPE_GET(res, idx) (res)->reg_base[idx].type
|
||||
|
||||
#define ACPI_RESOURCE_COUNT_GET(res) (res)->mmio_max
|
||||
|
||||
enum acpi_res_type {
|
||||
/** IO mapped Resource type */
|
||||
ACPI_RES_TYPE_IO,
|
||||
/** Memory mapped Resource type */
|
||||
ACPI_RES_TYPE_MEM,
|
||||
/** Unknown Resource type */
|
||||
ACPI_RES_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
struct acpi_dev {
|
||||
ACPI_HANDLE handle;
|
||||
char *path;
|
||||
char hid[CONFIG_ACPI_HID_LEN_MAX];
|
||||
ACPI_RESOURCE *res_lst;
|
||||
int res_type;
|
||||
ACPI_DEVICE_INFO *dev_info;
|
||||
|
@ -40,6 +60,72 @@ struct acpi_mcfg {
|
|||
ACPI_MCFG_ALLOCATION pci_segs[];
|
||||
} __packed;
|
||||
|
||||
struct acpi_irq_resource {
|
||||
uint32_t flags;
|
||||
union {
|
||||
uint16_t irq;
|
||||
uint16_t irqs[CONFIG_ACPI_IRQ_VECTOR_MAX];
|
||||
};
|
||||
uint8_t irq_vector_max;
|
||||
};
|
||||
|
||||
struct acpi_reg_base {
|
||||
enum acpi_res_type type;
|
||||
union {
|
||||
uintptr_t mmio;
|
||||
uintptr_t port;
|
||||
};
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct acpi_mmio_resource {
|
||||
struct acpi_reg_base reg_base[CONFIG_ACPI_MMIO_ENTRIES_MAX];
|
||||
uint8_t mmio_max;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get the ACPI HID for a node
|
||||
*
|
||||
* @param node_id DTS node identifier
|
||||
* @return The HID of the ACPI node
|
||||
*/
|
||||
#define ACPI_DT_HID(node_id) DT_PROP(node_id, acpi_hid)
|
||||
|
||||
/**
|
||||
* @brief Get the ACPI UID for a node if one exist
|
||||
*
|
||||
* @param node_id DTS node identifier
|
||||
* @return The UID of the ACPI node else NULL if does not exist
|
||||
*/
|
||||
#define ACPI_DT_UID(node_id) DT_PROP_OR(node_id, acpi_uid, NULL)
|
||||
|
||||
/**
|
||||
* @brief check whether the node has ACPI HID property or not
|
||||
*
|
||||
* @param node_id DTS node identifier
|
||||
* @return 1 if the node has the HID, 0 otherwise.
|
||||
*/
|
||||
#define ACPI_DT_HAS_HID(node_id) DT_NODE_HAS_PROP(node_id, acpi_hid)
|
||||
|
||||
/**
|
||||
* @brief check whether the node has ACPI UID property or not
|
||||
*
|
||||
* @param node_id DTS node identifier
|
||||
* @return 1 if the node has the UID, 0 otherwise.
|
||||
*/
|
||||
#define ACPI_DT_HAS_UID(node_id) DT_NODE_HAS_PROP(node_id, acpi_uid)
|
||||
|
||||
/**
|
||||
* @brief Init legacy interrupt routing table information from ACPI.
|
||||
* Currently assume platform have only one PCI bus.
|
||||
*
|
||||
* @param hid the hardware id of the ACPI child device
|
||||
* @param uid the unique id of the ACPI child device. The uid can be
|
||||
* NULL if only one device with given hid present in the platform.
|
||||
* @return return 0 on success or error code
|
||||
*/
|
||||
int acpi_legacy_irq_init(const char *hid, const char *uid);
|
||||
|
||||
/**
|
||||
* @brief Retrieve a legacy interrupt number for a PCI device.
|
||||
*
|
||||
|
@ -75,16 +161,6 @@ int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res);
|
|||
*/
|
||||
int acpi_current_resource_free(ACPI_RESOURCE *res);
|
||||
|
||||
/**
|
||||
* @brief Retrieve IRQ routing table of a bus.
|
||||
*
|
||||
* @param bus_name the name of the bus
|
||||
* @param rt_table the IRQ routing table
|
||||
* @param rt_size number of elements in the IRQ routing table
|
||||
* @return return 0 on success or error code
|
||||
*/
|
||||
int acpi_get_irq_routing_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size);
|
||||
|
||||
/**
|
||||
* @brief Parse resource table for a given resource type.
|
||||
*
|
||||
|
@ -95,13 +171,14 @@ int acpi_get_irq_routing_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table,
|
|||
ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type);
|
||||
|
||||
/**
|
||||
* @brief Retrieve acpi device info for given hardware id and unique id.
|
||||
* @brief Retrieve ACPI device info for given hardware id and unique id.
|
||||
*
|
||||
* @param hid the hardware id of the acpi child device
|
||||
* @param inst the unique id of the acpi child device
|
||||
* @return acpi child device info on success or NULL
|
||||
* @param hid the hardware id of the ACPI child device
|
||||
* @param uid the unique id of the ACPI child device. The uid can be
|
||||
* NULL if only one device with given HID present in the platform.
|
||||
* @return ACPI child device info on success or NULL
|
||||
*/
|
||||
struct acpi_dev *acpi_device_get(char *hid, int inst);
|
||||
struct acpi_dev *acpi_device_get(const char *hid, const char *uid);
|
||||
|
||||
/**
|
||||
* @brief Retrieve acpi device info from the index.
|
||||
|
@ -124,6 +201,24 @@ static inline ACPI_RESOURCE_IRQ *acpi_irq_res_get(ACPI_RESOURCE *res_lst)
|
|||
return res ? &res->Data.Irq : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse resource table for irq info.
|
||||
*
|
||||
* @param child_dev the device object of the ACPI node
|
||||
* @param irq_res irq resource info
|
||||
* @return return 0 on success or error code
|
||||
*/
|
||||
int acpi_device_irq_get(struct acpi_dev *child_dev, struct acpi_irq_resource *irq_res);
|
||||
|
||||
/**
|
||||
* @brief Parse resource table for MMIO info.
|
||||
*
|
||||
* @param child_dev the device object of the ACPI node
|
||||
* @param mmio_res MMIO resource info
|
||||
* @return return 0 on success or error code
|
||||
*/
|
||||
int acpi_device_mmio_get(struct acpi_dev *child_dev, struct acpi_mmio_resource *mmio_res);
|
||||
|
||||
/**
|
||||
* @brief Parse resource table for identify resource type.
|
||||
*
|
||||
|
@ -196,4 +291,15 @@ int acpi_dmar_ioapic_get(uint16_t *ioapic_id);
|
|||
* @return local apic info on success or NULL otherwise
|
||||
*/
|
||||
ACPI_MADT_LOCAL_APIC *acpi_local_apic_get(int cpu_num);
|
||||
|
||||
/**
|
||||
* @brief invoke an ACPI method and return the result.
|
||||
*
|
||||
* @param path the path name of the ACPI object
|
||||
* @param arg_list the list of arguments to be pass down
|
||||
* @param ret_obj the ACPI result to be return
|
||||
* @return return 0 on success or error code
|
||||
*/
|
||||
int acpi_invoke_method(char *path, ACPI_OBJECT_LIST *arg_list, ACPI_OBJECT *ret_obj);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,12 +16,6 @@ source "subsys/logging/Kconfig.template.log_config"
|
|||
|
||||
if PCIE_PRT
|
||||
|
||||
config ACPI_PRT_BUS_NAME
|
||||
string "ACPI name of PCI bus"
|
||||
default "_SB.PCI0"
|
||||
help
|
||||
ACPI name of PCI bus.
|
||||
|
||||
config ACPI_MAX_PRT_ENTRY
|
||||
int "Size of PRT buffer"
|
||||
default 4096
|
||||
|
@ -46,10 +40,16 @@ config ACPI_DEV_MAX
|
|||
help
|
||||
maximum acpi child devices.
|
||||
|
||||
endif # ACPI
|
||||
|
||||
config ACPI_HID_LEN_MAX
|
||||
int "Size of HID name"
|
||||
default 12
|
||||
config ACPI_IRQ_VECTOR_MAX
|
||||
int "Interrupt vectors per device"
|
||||
default 32
|
||||
help
|
||||
Size of HID string.
|
||||
Maximum interrupt vectors per device.
|
||||
|
||||
config ACPI_MMIO_ENTRIES_MAX
|
||||
int "MMIO entries per device"
|
||||
default 32
|
||||
help
|
||||
Maximum MMIO entries per device.
|
||||
|
||||
endif # ACPI
|
||||
|
|
269
lib/acpi/acpi.c
269
lib/acpi/acpi.c
|
@ -34,12 +34,12 @@ static int check_init_status(void)
|
|||
acpi.status = acpi_init();
|
||||
}
|
||||
|
||||
if (ACPI_SUCCESS(acpi.status)) {
|
||||
return 0;
|
||||
} else {
|
||||
if (ACPI_FAILURE(acpi.status)) {
|
||||
LOG_ERR("ACPI init was not success");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void notify_handler(ACPI_HANDLE device, UINT32 value, void *ctx)
|
||||
|
@ -216,6 +216,10 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev
|
|||
return AE_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!(dev_info->Valid & ACPI_VALID_HID)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
child_dev = (struct acpi_dev *)&acpi.child_dev[acpi.num_dev++];
|
||||
child_dev->handle = obj_handle;
|
||||
child_dev->dev_info = dev_info;
|
||||
|
@ -241,7 +245,7 @@ static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 lev
|
|||
|
||||
exit:
|
||||
|
||||
return status;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int acpi_enum_devices(void)
|
||||
|
@ -302,10 +306,10 @@ int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res)
|
|||
if (ACPI_FAILURE(status)) {
|
||||
LOG_ERR("AcpiGetCurrentResources failed: %s", AcpiFormatException(status));
|
||||
return -ENOTSUP;
|
||||
} else {
|
||||
*res = rt_buffer.Pointer;
|
||||
}
|
||||
|
||||
*res = rt_buffer.Pointer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -345,70 +349,6 @@ int acpi_current_resource_free(ACPI_RESOURCE *res)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PCIE_PRT
|
||||
static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, uint32_t rt_size)
|
||||
{
|
||||
ACPI_BUFFER rt_buffer;
|
||||
ACPI_NAMESPACE_NODE *node;
|
||||
ACPI_STATUS status;
|
||||
|
||||
LOG_DBG("%s", bus_name);
|
||||
|
||||
node = acpi_evaluate_method(bus_name, METHOD_NAME__PRT);
|
||||
if (!node) {
|
||||
LOG_ERR("Evaluation failed for given device: %s", bus_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rt_buffer.Pointer = rt_table;
|
||||
rt_buffer.Length = rt_size * sizeof(ACPI_PCI_ROUTING_TABLE);
|
||||
|
||||
status = AcpiGetIrqRoutingTable(node, &rt_buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
LOG_ERR("unable to retrieve IRQ Routing Table: %s", bus_name);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_retrieve_legacy_irq(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* TODO: assume platform have only one PCH with single PCI bus (bus 0). */
|
||||
ret = acpi_get_irq_table(CONFIG_ACPI_PRT_BUS_NAME,
|
||||
acpi.pci_prt_table, ARRAY_SIZE(acpi.pci_prt_table));
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(acpi.pci_prt_table); i++) {
|
||||
if (!acpi.pci_prt_table[i].SourceIndex) {
|
||||
break;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_X86_64)) {
|
||||
/* mark the PRT irq numbers as reserved. */
|
||||
arch_irq_set_used(acpi.pci_prt_table[i].SourceIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int acpi_get_irq_routing_table(char *bus_name,
|
||||
ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = check_init_status();
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return acpi_get_irq_table(bus_name, rt_table, rt_size);
|
||||
}
|
||||
|
||||
uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf)
|
||||
{
|
||||
uint32_t slot = PCIE_BDF_TO_DEV(bdf), pin;
|
||||
|
@ -434,13 +374,65 @@ uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf)
|
|||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
int acpi_legacy_irq_init(const char *hid, const char *uid)
|
||||
{
|
||||
struct acpi_dev *child_dev = acpi_device_get(hid, uid);
|
||||
ACPI_PCI_ROUTING_TABLE *rt_table = acpi.pci_prt_table;
|
||||
ACPI_BUFFER rt_buffer;
|
||||
ACPI_NAMESPACE_NODE *node;
|
||||
ACPI_STATUS status;
|
||||
|
||||
if (!child_dev) {
|
||||
LOG_ERR("no such PCI bus device %s %s", hid, uid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
node = acpi_evaluate_method(child_dev->path, METHOD_NAME__PRT);
|
||||
if (!node) {
|
||||
LOG_ERR("Evaluation failed for given device: %s", child_dev->path);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rt_buffer.Pointer = rt_table;
|
||||
rt_buffer.Length = ARRAY_SIZE(acpi.pci_prt_table) * sizeof(ACPI_PCI_ROUTING_TABLE);
|
||||
|
||||
status = AcpiGetIrqRoutingTable(node, &rt_buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
LOG_ERR("unable to retrieve IRQ Routing Table: %s", child_dev->path);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (rt_table->Source[0]) {
|
||||
/*
|
||||
* If Name path exist then PCI interrupts are configurable and are not hardwired to
|
||||
* any specific interrupt inputs on the interrupt controller. OSPM can uses
|
||||
* _PRS/_CRS/_SRS to configure interrupts. But currently leave existing PCI bus
|
||||
* driver with arch_irq_allocate() menthod for allocate and configure interrupts
|
||||
* without conflicting.
|
||||
*/
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(acpi.pci_prt_table); i++) {
|
||||
if (!acpi.pci_prt_table[i].SourceIndex) {
|
||||
break;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_X86_64)) {
|
||||
/* mark the PRT irq numbers as reserved. */
|
||||
arch_irq_set_used(acpi.pci_prt_table[i].SourceIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PCIE_PRT */
|
||||
|
||||
ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type)
|
||||
{
|
||||
do {
|
||||
if (!res->Length) {
|
||||
LOG_DBG("Error: zero length found!");
|
||||
LOG_DBG("zero length found!");
|
||||
break;
|
||||
} else if (res->Type == res_type) {
|
||||
break;
|
||||
|
@ -455,6 +447,105 @@ ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type)
|
|||
return res;
|
||||
}
|
||||
|
||||
int acpi_device_irq_get(struct acpi_dev *child_dev, struct acpi_irq_resource *irq_res)
|
||||
{
|
||||
ACPI_RESOURCE *res = acpi_resource_parse(child_dev->res_lst, ACPI_RESOURCE_TYPE_IRQ);
|
||||
|
||||
if (!res) {
|
||||
res = acpi_resource_parse(child_dev->res_lst, ACPI_RESOURCE_TYPE_EXTENDED_IRQ);
|
||||
if (!res) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (res->Data.ExtendedIrq.InterruptCount > CONFIG_ACPI_IRQ_VECTOR_MAX) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(irq_res, 0, sizeof(struct acpi_irq_resource));
|
||||
irq_res->irq_vector_max = res->Data.ExtendedIrq.InterruptCount;
|
||||
for (int i = 0; i < irq_res->irq_vector_max; i++) {
|
||||
irq_res->irqs[i] = (uint16_t)res->Data.ExtendedIrq.Interrupts[i];
|
||||
}
|
||||
|
||||
irq_res->flags = arch_acpi_encode_irq_flags(res->Data.ExtendedIrq.Polarity,
|
||||
res->Data.ExtendedIrq.Triggering);
|
||||
} else {
|
||||
if (res->Data.Irq.InterruptCount > CONFIG_ACPI_IRQ_VECTOR_MAX) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
irq_res->irq_vector_max = res->Data.Irq.InterruptCount;
|
||||
for (int i = 0; i < irq_res->irq_vector_max; i++) {
|
||||
irq_res->irqs[i] = (uint16_t)res->Data.Irq.Interrupts[i];
|
||||
}
|
||||
|
||||
irq_res->flags = arch_acpi_encode_irq_flags(res->Data.ExtendedIrq.Polarity,
|
||||
res->Data.ExtendedIrq.Triggering);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_device_mmio_get(struct acpi_dev *child_dev, struct acpi_mmio_resource *mmio_res)
|
||||
{
|
||||
ACPI_RESOURCE *res = child_dev->res_lst;
|
||||
struct acpi_reg_base *reg_base = mmio_res->reg_base;
|
||||
int mmio_cnt = 0;
|
||||
|
||||
do {
|
||||
if (!res->Length) {
|
||||
LOG_DBG("Found Acpi resource with zero length!");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (res->Type) {
|
||||
case ACPI_RESOURCE_TYPE_IO:
|
||||
reg_base[mmio_cnt].type = ACPI_RES_TYPE_IO;
|
||||
reg_base[mmio_cnt].port = (uint32_t)res->Data.Io.Minimum;
|
||||
reg_base[mmio_cnt++].length = res->Data.Io.AddressLength;
|
||||
break;
|
||||
|
||||
case ACPI_RESOURCE_TYPE_FIXED_IO:
|
||||
reg_base[mmio_cnt].type = ACPI_RES_TYPE_IO;
|
||||
reg_base[mmio_cnt].port = (uint32_t)res->Data.FixedIo.Address;
|
||||
reg_base[mmio_cnt++].length = res->Data.FixedIo.AddressLength;
|
||||
break;
|
||||
|
||||
case ACPI_RESOURCE_TYPE_MEMORY24:
|
||||
reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
|
||||
reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.Memory24.Minimum;
|
||||
reg_base[mmio_cnt++].length = res->Data.Memory24.AddressLength;
|
||||
break;
|
||||
|
||||
case ACPI_RESOURCE_TYPE_MEMORY32:
|
||||
reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
|
||||
reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.Memory32.Minimum;
|
||||
reg_base[mmio_cnt++].length = res->Data.Memory32.AddressLength;
|
||||
break;
|
||||
|
||||
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
|
||||
reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
|
||||
reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.FixedMemory32.Address;
|
||||
reg_base[mmio_cnt++].length = res->Data.FixedMemory32.AddressLength;
|
||||
break;
|
||||
}
|
||||
|
||||
res = ACPI_NEXT_RESOURCE(res);
|
||||
if (mmio_cnt >= CONFIG_ACPI_MMIO_ENTRIES_MAX &&
|
||||
res->Type != ACPI_RESOURCE_TYPE_END_TAG) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
} while (res->Type != ACPI_RESOURCE_TYPE_END_TAG);
|
||||
|
||||
if (!mmio_cnt) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mmio_res->mmio_max = mmio_cnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_res_type(ACPI_RESOURCE *res)
|
||||
{
|
||||
int type;
|
||||
|
@ -513,10 +604,10 @@ int acpi_device_type_get(ACPI_RESOURCE *res)
|
|||
return type;
|
||||
}
|
||||
|
||||
struct acpi_dev *acpi_device_get(char *hid, int inst)
|
||||
struct acpi_dev *acpi_device_get(const char *hid, const char *uid)
|
||||
{
|
||||
struct acpi_dev *child_dev;
|
||||
int i = 0, inst_id;
|
||||
int i = 0;
|
||||
|
||||
LOG_DBG("");
|
||||
|
||||
|
@ -537,9 +628,8 @@ struct acpi_dev *acpi_device_get(char *hid, int inst)
|
|||
}
|
||||
|
||||
if (!strcmp(hid, child_dev->dev_info->HardwareId.String)) {
|
||||
if (child_dev->dev_info->UniqueId.Length) {
|
||||
inst_id = atoi(child_dev->dev_info->UniqueId.String);
|
||||
if (inst_id == inst) {
|
||||
if (uid && child_dev->dev_info->UniqueId.Length) {
|
||||
if (!strcmp(child_dev->dev_info->UniqueId.String, uid)) {
|
||||
return child_dev;
|
||||
}
|
||||
} else {
|
||||
|
@ -836,6 +926,23 @@ ACPI_MADT_LOCAL_APIC *acpi_local_apic_get(int cpu_num)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int acpi_invoke_method(char *path, ACPI_OBJECT_LIST *arg_list, ACPI_OBJECT *ret_obj)
|
||||
{
|
||||
ACPI_STATUS status;
|
||||
ACPI_BUFFER ret_buff;
|
||||
|
||||
ret_buff.Length = sizeof(*ret_obj);
|
||||
ret_buff.Pointer = ret_obj;
|
||||
|
||||
status = AcpiEvaluateObject(NULL, path, arg_list, &ret_buff);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
LOG_ERR("error While executing %s method: %d", path, status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_init(void)
|
||||
{
|
||||
ACPI_STATUS status;
|
||||
|
@ -857,16 +964,6 @@ static int acpi_init(void)
|
|||
LOG_WRN("Error in enable pic mode acpi method:%d", status);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCIE_PRT
|
||||
int ret = acpi_retrieve_legacy_irq();
|
||||
|
||||
if (ret) {
|
||||
LOG_ERR("Error in retrieve legacy interrupt info:%d", ret);
|
||||
status = AE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
acpi_enum_devices();
|
||||
|
||||
exit:
|
||||
|
|
Loading…
Reference in a new issue