// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/debug.h>
#include <ddk/protocol/acpi.h>
#include <ddk/protocol/pciroot.h>

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <threads.h>

#include <zircon/compiler.h>
#include <zircon/process.h>

#include "errors.h"
#include "init.h"
#include "dev.h"
#include "errors.h"
#include "pci.h"
#include "powerbtn.h"
#include "processor.h"
#include "power.h"
#include "resources.h"

#define MAX_NAMESPACE_DEPTH 100

#define HID_LENGTH 8
#define CID_LENGTH 8

typedef struct acpi_device_resource {
    bool writeable;
    uint32_t base_address;
    uint32_t alignment;
    uint32_t address_length;
} acpi_device_resource_t;

typedef struct acpi_device_irq {
    uint8_t trigger;
#define ACPI_IRQ_TRIGGER_LEVEL  0
#define ACPI_IRQ_TRIGGER_EDGE   1
    uint8_t polarity;
#define ACPI_IRQ_ACTIVE_HIGH    0
#define ACPI_IRQ_ACTIVE_LOW     1
#define ACPI_IRQ_ACTIVE_BOTH    2
    uint8_t sharable;
#define ACPI_IRQ_EXCLUSIVE      0
#define ACPI_IRQ_SHARED         1
    uint8_t wake_capable;
    uint8_t pin;
} acpi_device_irq_t;

typedef struct acpi_device {
    zx_device_t* zxdev;

    mtx_t lock;

    bool got_resources;

    // memory resources from _CRS
    acpi_device_resource_t* resources;
    size_t resource_count;

    // interrupt resources from _CRS
    acpi_device_irq_t* irqs;
    size_t irq_count;

    // handle to the corresponding ACPI node
    ACPI_HANDLE ns_node;
} acpi_device_t;

typedef struct {
    zx_device_t* parent;
    bool found_pci;
} publish_acpi_device_ctx_t;

typedef struct {
    uint8_t max;
    uint8_t i;
    zx_status_t st;
    uint32_t* more;
    uint32_t* cookie;
    auxdata_i2c_device_t* data;
} pci_child_auxdata_ctx_t;

typedef struct {
} acpi_auxdata_ctx_t;

zx_handle_t root_resource_handle;

static zx_device_t* publish_device(zx_device_t* parent, ACPI_HANDLE handle,
                                   ACPI_DEVICE_INFO* info, const char* name,
                                   uint32_t protocol_id, void* protocol_ops);

static void acpi_device_release(void* ctx) {
    acpi_device_t* dev = (acpi_device_t*)ctx;
    free(dev);
}

static zx_protocol_device_t acpi_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .release = acpi_device_release,
};

static ACPI_STATUS find_pci_child_callback(ACPI_HANDLE object, uint32_t nesting_level,
                                           void* context, void** out_value) {
    ACPI_DEVICE_INFO* info;
    ACPI_STATUS acpi_status = AcpiGetObjectInfo(object, &info);
    if (acpi_status != AE_OK) {
        zxlogf(TRACE, "bus-acpi: AcpiGetObjectInfo failed %d\n", acpi_status);
        return acpi_status;
    }
    ACPI_FREE(info);
    ACPI_OBJECT obj = {
        .Type = ACPI_TYPE_INTEGER,
    };
    ACPI_BUFFER buffer = {
        .Length = sizeof(obj),
        .Pointer = &obj,
    };
    acpi_status = AcpiEvaluateObject(object, (char*)"_ADR", NULL, &buffer);
    if (acpi_status != AE_OK) {
        return AE_OK;
    }
    uint32_t addr = *(uint32_t*)context;
    ACPI_HANDLE* out_handle = (ACPI_HANDLE*)out_value;
    if (addr == obj.Integer.Value) {
        *out_handle = object;
        return AE_CTRL_TERMINATE;
    } else {
        return AE_OK;
    }
}

static ACPI_STATUS pci_child_data_resources_callback(ACPI_RESOURCE* res, void* context) {
    pci_child_auxdata_ctx_t* ctx = (pci_child_auxdata_ctx_t*)context;
    auxdata_i2c_device_t* child = ctx->data;

    if (res->Type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
        return AE_NOT_FOUND;
    }
    if (res->Data.I2cSerialBus.Type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
        return AE_NOT_FOUND;
    }

    ACPI_RESOURCE_I2C_SERIALBUS* i2c = &res->Data.I2cSerialBus;
    child->bus_master = i2c->SlaveMode;
    child->ten_bit = i2c->AccessMode;
    child->address = i2c->SlaveAddress;
    child->bus_speed = i2c->ConnectionSpeed;

    ctx->st = ZX_OK;

    return AE_CTRL_TERMINATE;
}

static ACPI_STATUS pci_child_data_callback(ACPI_HANDLE object,
                                           uint32_t nesting_level,
                                           void* context, void** out_value) {
    pci_child_auxdata_ctx_t* ctx = (pci_child_auxdata_ctx_t*)context;
    if (ctx->i++ > ctx->max) {
        *ctx->more = 1;
        return AE_CTRL_TERMINATE;
    }

    // get device type (only looking for i2c-hid right now)
    ACPI_BUFFER buffer = {
        .Length = ACPI_ALLOCATE_BUFFER,
    };
    ACPI_STATUS acpi_status = AcpiEvaluateObject(object, (char*)"_CID", NULL, &buffer);
    if (acpi_status == AE_OK) {
        ACPI_OBJECT* obj = buffer.Pointer;
        if (!memcmp(obj->String.Pointer, I2C_HID_CID_STRING, CID_LENGTH)) {
            ctx->data->protocol_id = ZX_PROTOCOL_I2C_HID;
        }
        ACPI_FREE(obj);
    }

    // call _CRS to get i2c info
    acpi_status = AcpiWalkResources(object, (char*)"_CRS",
                                    pci_child_data_resources_callback, ctx);
    if (acpi_status != AE_OK) {
        ctx->st = acpi_to_zx_status(acpi_status);
    }

    // terminate child walk once the the nth device is found
    return AE_CTRL_TERMINATE;
}

static zx_status_t pciroot_op_get_auxdata(void* context, const char* args,
                                          void* data, uint32_t bytes,
                                          uint32_t* actual) {
    acpi_device_t* dev = (acpi_device_t*)context;

    char type[16];
    uint32_t bus_id, dev_id, func_id;
    if (sscanf(args, "%s,%02x:%02x:%02x", type, bus_id, dev_id, func_id) < 0) {
        return ZX_ERR_INVALID_ARGS;
    }

    if (strcmp(type, "i2c-child")) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    if (bytes < (2 * sizeof(uint32_t))) {
        return ZX_ERR_BUFFER_TOO_SMALL;
    }

    ACPI_HANDLE pci_node = NULL;
    uint32_t addr = (dev_id << 16) | func_id;

    // Look for the child node with this device and function id
    ACPI_STATUS acpi_status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, dev->ns_node, 1,
                                                find_pci_child_callback, NULL,
                                                &addr, &pci_node);
    if ((acpi_status != AE_OK) && (acpi_status != AE_CTRL_TERMINATE)) {
        return acpi_to_zx_status(acpi_status);
    }
    if (pci_node == NULL) {
        return ZX_ERR_NOT_FOUND;
    }

    // Look for as many children as can fit in the provided buffer
    pci_child_auxdata_ctx_t ctx = {
        .max = (bytes - 2 * sizeof(uint32_t)) / sizeof(auxdata_i2c_device_t),
        .i = 0,
        .st = ZX_ERR_NOT_FOUND,
        .more = data,
        .cookie = data + sizeof(uint32_t),
        .data = data + 2 * sizeof(uint32_t),
    };

    acpi_status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, pci_node, 1,
                                    pci_child_data_callback, NULL, &ctx, NULL);
    if ((acpi_status != AE_OK) && (acpi_status != AE_CTRL_TERMINATE)) {
        return acpi_to_zx_status(acpi_status);
    }

    return ctx.st;
}

static pciroot_protocol_ops_t pciroot_proto = {
    .get_auxdata = pciroot_op_get_auxdata,
};

typedef struct {
    acpi_device_resource_t* resources;
    size_t resource_count;
    size_t resource_i;

    acpi_device_irq_t* irqs;
    size_t irq_count;
    size_t irq_i;
} acpi_crs_ctx_t;

static ACPI_STATUS report_current_resources_resource_cb(ACPI_RESOURCE* res, void* _ctx) {
    acpi_crs_ctx_t* ctx = (acpi_crs_ctx_t*)_ctx;

    if (resource_is_memory(res)) {
        resource_memory_t mem;
        zx_status_t st = resource_parse_memory(res, &mem);
        // only expect fixed memory resource. resource_parse_memory sets minimum == maximum
        // for this memory resource type.
        if ((st != ZX_OK) || (mem.minimum != mem.maximum)) {
            return AE_ERROR;
        }

        ctx->resources[ctx->resource_i].writeable = mem.writeable;
        ctx->resources[ctx->resource_i].base_address = mem.minimum;
        ctx->resources[ctx->resource_i].alignment = mem.alignment;
        ctx->resources[ctx->resource_i].address_length = mem.address_length;

        ctx->resource_i += 1;

    } else if (resource_is_address(res)) {
        resource_address_t addr;
        zx_status_t st = resource_parse_address(res, &addr);
        if (st != ZX_OK) {
            return AE_ERROR;
        }
        if ((addr.resource_type == RESOURCE_ADDRESS_MEMORY) && addr.min_address_fixed &&
            addr.max_address_fixed && (addr.maximum < addr.minimum)) {

            ctx->resources[ctx->resource_i].writeable = true;
            ctx->resources[ctx->resource_i].base_address = addr.min_address_fixed;
            ctx->resources[ctx->resource_i].alignment = 0;
            ctx->resources[ctx->resource_i].address_length = addr.address_length;

            ctx->resource_i += 1;
        }

    } else if (resource_is_irq(res)) {
        resource_irq_t irq;
        zx_status_t st = resource_parse_irq(res, &irq);
        if (st != ZX_OK) {
            return AE_ERROR;
        }
        for (size_t i = 0; i < irq.pin_count; i++) {
            ctx->irqs[ctx->irq_i].trigger = irq.trigger;
            ctx->irqs[ctx->irq_i].polarity = irq.polarity;
            ctx->irqs[ctx->irq_i].sharable = irq.sharable;
            ctx->irqs[ctx->irq_i].wake_capable = irq.wake_capable;
            ctx->irqs[ctx->irq_i].pin = irq.pins[i];

            ctx->irq_i += 1;
        }
    }

    return AE_OK;
}

static ACPI_STATUS report_current_resources_count_cb(ACPI_RESOURCE* res, void* _ctx) {
    acpi_crs_ctx_t* ctx = (acpi_crs_ctx_t*)_ctx;

    if (resource_is_memory(res)) {
        resource_memory_t mem;
        zx_status_t st = resource_parse_memory(res, &mem);
        if ((st != ZX_OK) || (mem.minimum != mem.maximum)) {
            return AE_ERROR;
        }
        ctx->resource_count += 1;

    } else if (resource_is_address(res)) {
        resource_address_t addr;
        zx_status_t st = resource_parse_address(res, &addr);
        if (st != ZX_OK) {
            return AE_ERROR;
        }
        if ((addr.resource_type == RESOURCE_ADDRESS_MEMORY) && addr.min_address_fixed &&
            addr.max_address_fixed && (addr.maximum < addr.minimum)) {
            ctx->resource_count += 1;
        }

    } else if (resource_is_irq(res)) {
        ctx->irq_count += res->Data.Irq.InterruptCount;
    }

    return AE_OK;
}

static zx_status_t report_current_resources(acpi_device_t* dev) {
    acpi_crs_ctx_t ctx;
    memset(&ctx, 0, sizeof(ctx));

    if (dev->got_resources) {
        return ZX_OK;
    }

    // call _CRS to count number of resources
    ACPI_STATUS acpi_status = AcpiWalkResources(dev->ns_node, (char*)"_CRS",
            report_current_resources_count_cb, &ctx);
    if ((acpi_status != AE_NOT_FOUND) && (acpi_status != AE_OK)) {
        return acpi_to_zx_status(acpi_status);
    }

    if (ctx.resource_count == 0) {
        return ZX_OK;
    }

    // allocate resources
    ctx.resources = calloc(ctx.resource_count, sizeof(acpi_device_resource_t));
    if (!ctx.resources) {
        return ZX_ERR_NO_MEMORY;
    }
    ctx.irqs = calloc(ctx.irq_count, sizeof(acpi_device_irq_t));
    if (!ctx.irqs) {
        free(ctx.resources);
        return ZX_ERR_NO_MEMORY;
    }

    // call _CRS again and fill in resources
    acpi_status = AcpiWalkResources(dev->ns_node, (char*)"_CRS",
            report_current_resources_resource_cb, &ctx);
    if ((acpi_status != AE_NOT_FOUND) && (acpi_status != AE_OK)) {
        free(ctx.resources);
        free(ctx.irqs);
        return acpi_to_zx_status(acpi_status);
    }

    dev->resources = ctx.resources;
    dev->resource_count = ctx.resource_count;
    dev->irqs = ctx.irqs;
    dev->irq_count = ctx.irq_count;

    zxlogf(TRACE, "acpi-bus[%s]: found %zd resources %zx irqs\n", device_get_name(dev->zxdev),
            dev->resource_count, dev->irq_count);
    if (driver_get_log_flags() & DDK_LOG_SPEW) {
        zxlogf(SPEW, "resources:\n");
        for (size_t i = 0; i < dev->resource_count; i++) {
            zxlogf(SPEW, "  %02zd: addr=0x%x length=0x%x align=0x%x writeable=%d\n", i,
                    dev->resources[i].base_address,
                    dev->resources[i].address_length,
                    dev->resources[i].alignment,
                    dev->resources[i].writeable);
        }
        zxlogf(SPEW, "irqs:\n");
        for (size_t i = 0; i < dev->irq_count; i++) {
            zxlogf(SPEW, "  %02zd: pin=%u %s %s %s %s\n", i,
                    dev->irqs[i].pin,
                    dev->irqs[i].trigger ? "edge" : "level",
                    (dev->irqs[i].polarity == 2) ? "both" :
                        (dev->irqs[i].polarity ? "low" : "high"),
                    dev->irqs[i].sharable ? "shared" : "exclusive",
                    dev->irqs[i].wake_capable ? "wake" : "nowake");
        }
    }

    dev->got_resources = true;

    return ZX_OK;
}

static zx_status_t acpi_op_map_resource(void* ctx, uint32_t res_id, uint32_t cache_policy,
        void** out_vaddr, size_t* out_size, zx_handle_t* out_handle) {
    acpi_device_t* dev = (acpi_device_t*)ctx;
    mtx_lock(&dev->lock);

    zx_status_t st = report_current_resources(dev);
    if (st != ZX_OK) {
        goto unlock;
    }

    if (res_id >= dev->resource_count) {
        st = ZX_ERR_NOT_FOUND;
        goto unlock;
    }

    acpi_device_resource_t* res = dev->resources + res_id;
    if (((res->base_address & (PAGE_SIZE - 1)) != 0) ||
        ((res->address_length & (PAGE_SIZE - 1)) != 0)) {
        zxlogf(ERROR, "acpi-bus[%s]: resource id=%d addr=0x%08x len=0x%x is not page aligned\n",
                device_get_name(dev->zxdev), res_id, res->base_address, res->address_length);
        st = ZX_ERR_NOT_FOUND;
        goto unlock;
    }

    zx_handle_t vmo;
    zx_vaddr_t vaddr;
    size_t size = res->address_length;
    st = zx_vmo_create_physical(get_root_resource(), res->base_address, size, &vmo);
    if (st != ZX_OK) {
        goto unlock;
    }

    st = zx_vmo_set_cache_policy(vmo, cache_policy);
    if (st != ZX_OK) {
        zx_handle_close(vmo);
        goto unlock;
    }

    st = zx_vmar_map(zx_vmar_root_self(), 0, vmo, 0, size,
                     ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_MAP_RANGE,
                     &vaddr);
    if (st != ZX_OK) {
        zx_handle_close(vmo);
    } else {
        *out_handle = vmo;
        *out_vaddr = (void*)vaddr;
        *out_size = size;
    }
unlock:
    mtx_unlock(&dev->lock);
    return st;
}

static zx_status_t acpi_op_map_interrupt(void* ctx, int which_irq, zx_handle_t* out_handle) {
    acpi_device_t* dev = (acpi_device_t*)ctx;
    mtx_lock(&dev->lock);

    zx_status_t st = report_current_resources(dev);
    if (st != ZX_OK) {
        goto unlock;
    }

    if ((uint)which_irq >= dev->irq_count) {
        st = ZX_ERR_NOT_FOUND;
        goto unlock;
    }

    acpi_device_irq_t* irq = dev->irqs + which_irq;
    zx_handle_t handle;
    st = zx_interrupt_create(get_root_resource(), irq->pin, ZX_INTERRUPT_REMAP_IRQ, &handle);
    if (st != ZX_OK) {
        goto unlock;
    }

    *out_handle = handle;

unlock:
    mtx_unlock(&dev->lock);
    return st;
}

// TODO marking unused until we publish some devices
static __attribute__ ((unused)) acpi_protocol_ops_t acpi_proto = {
    .map_resource = acpi_op_map_resource,
    .map_interrupt = acpi_op_map_interrupt,
};

static zx_protocol_device_t acpi_root_device_proto = {
    .version = DEVICE_OPS_VERSION,
};

static zx_status_t sys_device_suspend(void* ctx, uint32_t flags) {
    switch (flags) {
    case DEVICE_SUSPEND_FLAG_REBOOT:
        reboot();
        // Kill this driver so that the IPC channel gets closed; devmgr will
        // perform a fallback that should shutdown or reboot the machine.
        exit(0);
    case DEVICE_SUSPEND_FLAG_POWEROFF:
        poweroff();
        exit(0);
    default:
        return ZX_ERR_NOT_SUPPORTED;
    };
}

static zx_protocol_device_t sys_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .suspend = sys_device_suspend,
};

static const char* hid_from_acpi_devinfo(ACPI_DEVICE_INFO* info) {
    const char* hid = NULL;
    if ((info->Valid & ACPI_VALID_HID) &&
            (info->HardwareId.Length > 0) &&
            ((info->HardwareId.Length - 1) <= sizeof(uint64_t))) {
        hid = (const char*)info->HardwareId.String;
    }
    return hid;
}

static zx_device_t* publish_device(zx_device_t* parent,
                                   ACPI_HANDLE handle,
                                   ACPI_DEVICE_INFO* info,
                                   const char* name,
                                   uint32_t protocol_id,
                                   void* protocol_ops) {
    zx_device_prop_t props[4];
    int propcount = 0;

    char acpi_name[5] = { 0 };
    if (!name) {
        memcpy(acpi_name, &info->Name, sizeof(acpi_name) - 1);
        name = (const char*)acpi_name;
    }

    // Publish HID in device props
    const char* hid = hid_from_acpi_devinfo(info);
    if (hid) {
        props[propcount].id = BIND_ACPI_HID_0_3;
        props[propcount++].value = htobe32(*((uint32_t*)(hid)));
        props[propcount].id = BIND_ACPI_HID_4_7;
        props[propcount++].value = htobe32(*((uint32_t*)(hid + 4)));
    }

    // Publish the first CID in device props
    const char* cid = (const char*)info->CompatibleIdList.Ids[0].String;
    if ((info->Valid & ACPI_VALID_CID) &&
            (info->CompatibleIdList.Count > 0) &&
            ((info->CompatibleIdList.Ids[0].Length - 1) <= sizeof(uint64_t))) {
        props[propcount].id = BIND_ACPI_CID_0_3;
        props[propcount++].value = htobe32(*((uint32_t*)(cid)));
        props[propcount].id = BIND_ACPI_CID_4_7;
        props[propcount++].value = htobe32(*((uint32_t*)(cid + 4)));
    }

    if (driver_get_log_flags() & DDK_LOG_SPEW) {
        // ACPI names are always 4 characters in a uint32
        zxlogf(SPEW, "acpi-bus: got device %s\n", acpi_name);
        if (info->Valid & ACPI_VALID_HID) {
            zxlogf(SPEW, "     HID=%s\n", info->HardwareId.String);
        } else {
            zxlogf(SPEW, "     HID=invalid\n");
        }
        if (info->Valid & ACPI_VALID_ADR) {
            zxlogf(SPEW, "     ADR=0x%" PRIx64 "\n", (uint64_t)info->Address);
        } else {
            zxlogf(SPEW, "     ADR=invalid\n");
        }
        if (info->Valid & ACPI_VALID_CID) {
            zxlogf(SPEW, "    CIDS=%d\n", info->CompatibleIdList.Count);
            for (uint i = 0; i < info->CompatibleIdList.Count; i++) {
                zxlogf(SPEW, "     [%u] %s\n", i, info->CompatibleIdList.Ids[i].String);
            }
        } else {
            zxlogf(SPEW, "     CID=invalid\n");
        }
        zxlogf(SPEW, "    devprops:\n");
        for (int i = 0; i < propcount; i++) {
            zxlogf(SPEW, "     [%d] id=0x%08x value=0x%08x\n", i, props[i].id, props[i].value);
        }
    }

    acpi_device_t* dev = calloc(1, sizeof(acpi_device_t));
    if (!dev) {
        return NULL;
    }

    dev->ns_node = handle;

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = name,
        .ctx = dev,
        .ops = &acpi_device_proto,
        .proto_id = protocol_id,
        .proto_ops = protocol_ops,
        .props = (propcount > 0) ? props : NULL,
        .prop_count = propcount,
    };

    zx_status_t status;
    if ((status = device_add(parent, &args, &dev->zxdev)) != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: error %d in device_add, parent=%s(%p)\n",
                status, device_get_name(parent), parent);
        free(dev);
        return NULL;
    } else {
        zxlogf(ERROR, "acpi-bus: published device %s(%p), parent=%s(%p), handle=%p\n",
                name, dev, device_get_name(parent), parent, (void*)dev->ns_node);
        return dev->zxdev;
    }
}

static ACPI_STATUS acpi_ns_walk_callback(ACPI_HANDLE object, uint32_t nesting_level,
                                         void* context, void** status) {
    ACPI_DEVICE_INFO* info = NULL;
    ACPI_STATUS acpi_status = AcpiGetObjectInfo(object, &info);
    if (acpi_status != AE_OK) {
        return acpi_status;
    }

    // TODO: This is a temporary workaround until we have full ACPI device
    // enumeration. If this is the I2C1 bus, we run _PS0 so the controller
    // is active.
    if (!memcmp(&info->Name, "I2C1", 4)) {
        ACPI_STATUS acpi_status = AcpiEvaluateObject(object, (char*)"_PS0", NULL, NULL);
        if (acpi_status != AE_OK) {
            zxlogf(ERROR, "acpi-bus: acpi error 0x%x in I2C1._PS0\n", acpi_status);
        }
    }

    zxlogf(TRACE, "acpi-bus: handle %p nesting level %d\n", (void*)object, nesting_level);

    publish_acpi_device_ctx_t* ctx = (publish_acpi_device_ctx_t*)context;
    zx_device_t* parent = ctx->parent;
    const char* hid = hid_from_acpi_devinfo(info);
    if (hid == 0) {
        goto out;
    }
    if (!ctx->found_pci && (!memcmp(hid, PCI_EXPRESS_ROOT_HID_STRING, HID_LENGTH) ||
                            !memcmp(hid, PCI_ROOT_HID_STRING, HID_LENGTH))) {
        // Publish PCI root as top level
        // Only publish one PCI root device for all PCI roots
        // TODO: store context for PCI root protocol
        parent = device_get_parent(parent);
        zx_device_t* pcidev = publish_device(parent, object, info, "pci",
                ZX_PROTOCOL_PCIROOT, &pciroot_proto);
        ctx->found_pci = (pcidev != NULL);
    } else if (!memcmp(hid, BATTERY_HID_STRING, HID_LENGTH)) {
        battery_init(parent, object);
    } else if (!memcmp(hid, PWRSRC_HID_STRING, HID_LENGTH)) {
        pwrsrc_init(parent, object);
    } else if (!memcmp(hid, EC_HID_STRING, HID_LENGTH)) {
        ec_init(parent, object);
    } else if (!memcmp(hid, GOOGLE_TBMC_HID_STRING, HID_LENGTH)) {
        tbmc_init(parent, object);
    } else if (!memcmp(hid, GOOGLE_CROS_EC_HID_STRING, HID_LENGTH)) {
        cros_ec_lpc_init(parent, object);
    }

out:
    ACPI_FREE(info);

    return AE_OK;
}

static zx_status_t publish_acpi_devices(zx_device_t* parent) {
    // Walk the ACPI namespace for devices and publish them
    // Only publish a single PCI device
    publish_acpi_device_ctx_t ctx = {
        .parent = parent,
        .found_pci = false,
    };
    ACPI_STATUS acpi_status = AcpiWalkNamespace(ACPI_TYPE_DEVICE,
                                                ACPI_ROOT_OBJECT,
                                                MAX_NAMESPACE_DEPTH,
                                                acpi_ns_walk_callback,
                                                NULL, &ctx, NULL);
    if (acpi_status != AE_OK) {
        return ZX_ERR_BAD_STATE;
    } else {
        return ZX_OK;
    }
}

static zx_status_t acpi_drv_create(void* ctx, zx_device_t* parent, const char* name,
                                   const char* _args, zx_handle_t rpc_channel) {
    // ACPI is the root driver for its devhost so run init in the bind thread.
    zxlogf(TRACE, "acpi-bus: bind to %s %p\n", device_get_name(parent), parent);
    root_resource_handle = get_root_resource();

    if (init() != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: failed to initialize ACPI\n");
        return ZX_ERR_INTERNAL;
    }

    zxlogf(TRACE, "acpi-bus: initialized\n");

    zx_status_t status = install_powerbtn_handlers();
    if (status != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: error %d in install_powerbtn_handlers\n", status);
        return status;
    }

    // Report current resources to kernel PCI driver
    status = pci_report_current_resources(get_root_resource());
    if (status != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: WARNING: ACPI failed to report all current resources!\n");
    }

    // Initialize kernel PCI driver
    zx_pci_init_arg_t* arg;
    uint32_t arg_size;
    status = get_pci_init_arg(&arg, &arg_size);
    if (status != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: erorr %d in get_pci_init_arg\n", status);
        return status;
    }

    status = zx_pci_init(get_root_resource(), arg, arg_size);
    if (status != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: error %d in zx_pci_init\n", status);
        return status;
    }

    free(arg);

    // publish sys root
    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = name,
        .ops = &sys_device_proto,
        .flags = DEVICE_ADD_NON_BINDABLE,
    };

    zx_device_t* sys_root = NULL;
    status = device_add(parent, &args, &sys_root);
    if (status != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: error %d in device_add(sys)\n", status);
        return status;
    }

    // publish acpi root
    device_add_args_t args2 = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "acpi",
        .ops = &acpi_root_device_proto,
        .flags = DEVICE_ADD_NON_BINDABLE,
    };

    zx_device_t* acpi_root = NULL;
    status = device_add(sys_root, &args2, &acpi_root);
    if (status != ZX_OK) {
        zxlogf(ERROR, "acpi-bus: error %d in device_add(sys/acpi)\n", status);
        device_remove(sys_root);
        return status;
    }

    publish_acpi_devices(acpi_root);

    return ZX_OK;
}

static zx_driver_ops_t acpi_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .create = acpi_drv_create,
};

ZIRCON_DRIVER_BEGIN(acpi, acpi_driver_ops, "zircon", "0.1", 1)
    BI_ABORT_IF_AUTOBIND, // loaded by devcoordinator
ZIRCON_DRIVER_END(acpi)
