| /* |
| * arch/ia64/kernel/acpi-ext.c |
| * |
| * Copyright (C) 2003 Hewlett-Packard |
| * Copyright (C) Alex Williamson |
| * Copyright (C) Bjorn Helgaas |
| * |
| * Vendor specific extensions to ACPI. |
| */ |
| |
| #include <linux/config.h> |
| #include <linux/module.h> |
| #include <linux/types.h> |
| #include <linux/acpi.h> |
| #include <linux/efi.h> |
| |
| #include <asm/acpi-ext.h> |
| |
| struct acpi_vendor_descriptor { |
| u8 guid_id; |
| efi_guid_t guid; |
| }; |
| |
| struct acpi_vendor_info { |
| struct acpi_vendor_descriptor *descriptor; |
| u8 *data; |
| u32 length; |
| }; |
| |
| acpi_status |
| acpi_vendor_resource_match(struct acpi_resource *resource, void *context) |
| { |
| struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; |
| struct acpi_resource_vendor *vendor; |
| struct acpi_vendor_descriptor *descriptor; |
| u32 byte_length; |
| |
| if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) |
| return AE_OK; |
| |
| vendor = (struct acpi_resource_vendor *)&resource->data; |
| descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; |
| if (vendor->byte_length <= sizeof(*info->descriptor) || |
| descriptor->guid_id != info->descriptor->guid_id || |
| efi_guidcmp(descriptor->guid, info->descriptor->guid)) |
| return AE_OK; |
| |
| byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); |
| info->data = acpi_os_allocate(byte_length); |
| if (!info->data) |
| return AE_NO_MEMORY; |
| |
| memcpy(info->data, |
| vendor->byte_data + sizeof(struct acpi_vendor_descriptor), |
| byte_length); |
| info->length = byte_length; |
| return AE_CTRL_TERMINATE; |
| } |
| |
| acpi_status |
| acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, |
| u8 ** data, u32 * byte_length) |
| { |
| struct acpi_vendor_info info; |
| |
| info.descriptor = id; |
| info.data = NULL; |
| |
| acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, |
| &info); |
| if (!info.data) |
| return AE_NOT_FOUND; |
| |
| *data = info.data; |
| *byte_length = info.length; |
| return AE_OK; |
| } |
| |
| struct acpi_vendor_descriptor hp_ccsr_descriptor = { |
| .guid_id = 2, |
| .guid = |
| EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, |
| 0x37, 0x0e, 0xad) |
| }; |
| |
| acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length) |
| { |
| acpi_status status; |
| u8 *data; |
| u32 length; |
| |
| status = |
| acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); |
| |
| if (ACPI_FAILURE(status) || length != 16) |
| return AE_NOT_FOUND; |
| |
| memcpy(csr_base, data, sizeof(*csr_base)); |
| memcpy(csr_length, data + 8, sizeof(*csr_length)); |
| acpi_os_free(data); |
| |
| return AE_OK; |
| } |
| |
| EXPORT_SYMBOL(hp_acpi_csr_space); |