// 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 n;
    uint8_t i;
    zx_status_t st;
    auxdata_i2c_device_t* data;
} pci_child_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,
                                   bool composite);

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 acpi_ADR(ACPI_HANDLE object, UINT64* out_addr) {
    ACPI_OBJECT obj = {
        .Type = ACPI_TYPE_INTEGER,
    };
    ACPI_BUFFER buffer = {
        .Length = sizeof(obj),
        .Pointer = &obj,
    };
    ACPI_STATUS acpi_status = AcpiEvaluateObject(object, (char*)"_ADR", NULL, &buffer);
    if (acpi_status != AE_OK) {
        return acpi_status;
    }
    *out_addr = obj.Integer.Value;
    return AE_OK;
}

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);

    UINT64 acpi_addr;
    acpi_status = acpi_ADR(object, &acpi_addr);
    if (acpi_status != AE_OK) {
        return AE_OK;
    }
    uint32_t addr = *(uint32_t*)context;
    ACPI_HANDLE* out_handle = (ACPI_HANDLE*)out_value;
    if (addr == (uint32_t)acpi_addr) {
        *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;
    uint32_t i = ctx->i++;
    if (i < ctx->n) {
        return AE_OK;
    } else if (i > ctx->n) {
        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, auxdata_type_t type,
                                          void* _args, size_t args_len,
                                          void* out_data, size_t out_len) {
    acpi_device_t* dev = (acpi_device_t*)context;
    if (type != AUXDATA_PCI_CHILD_NTH_DEVICE) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    auxdata_args_pci_child_nth_device_t* args = _args;
    if (args->child_type != AUXDATA_DEVICE_I2C) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    if (out_len != sizeof(auxdata_i2c_device_t)) {
        return ZX_ERR_INVALID_ARGS;
    }

    ACPI_HANDLE pci_node = NULL;
    uint32_t addr = (args->dev_id << 16) | args->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 the nth child for this pci node and fill in data
    pci_child_auxdata_ctx_t ctx = {
        .n = args->n,
        .i = 0,
        .st = ZX_ERR_NOT_FOUND,
        .data = out_data,
    };

    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;
}

static 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 ACPI_STATUS publish_device_resource_callback(ACPI_RESOURCE* res, void* context) {
    zx_binding_t* binding = context;
    if (res->Type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
        return AE_OK;
    }
    if (res->Data.I2cSerialBus.Type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
        return AE_OK;
    }

    ACPI_RESOURCE_I2C_SERIALBUS* i2c = &res->Data.I2cSerialBus;
    ACPI_HANDLE obj;
    ACPI_STATUS acpi_status = AcpiGetHandle(NULL, i2c->ResourceSource.StringPtr, &obj);
    if (acpi_status != AE_OK) {
        // next resource
        return AE_OK;
    }
    // binding is based on PCI b:d.f
    UINT64 addr;
    acpi_status = acpi_ADR(obj, &addr);
    if (acpi_status != AE_OK) {
        // next resource
        return AE_OK;
    }

    // BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C_BUS)
    binding->bindings[0].op = (COND_NE << 28) | (OP_ABORT << 24) | BINDINST_PB(BIND_PROTOCOL);
    binding->bindings[0].arg = ZX_PROTOCOL_I2C_BUS;

    // BI_MATCH_IF(NE, BIND_PCI_BDF_ADDR, <b:d.f>)
    // TODO Only support a single PCI bus for now
    binding->bindings[1].op = (COND_EQ << 28) | (OP_MATCH << 24) | BINDINST_PB(BIND_PCI_BDF_ADDR);
    binding->bindings[1].arg = BIND_PCI_BDF_PACK(0, (addr >> 16), (addr & 0xffff));

    binding->bindcount = 2;

    // stop at the first i2c resource
    return AE_CTRL_TERMINATE;
}

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,
                                   bool composite) {
    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 this a composite device, look for resource dependencies
    uint32_t depcount = 0;
    zx_bind_inst_t bindings[2]; // space for 1 dependency with 2 bind rules
    zx_binding_t binding = {
        .bindings = bindings,
        .bindcount = 0,
    };
    AcpiWalkResources(handle, (char*)"_CRS", publish_device_resource_callback, &binding);
    if (binding.bindcount > 0) {
        depcount = 1;
    }

    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);
        }
        if (depcount > 0) {
            zxlogf(SPEW, "    composite, depcount=%u\n", depcount);
        }
    }

    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,
        .dep_count = depcount,
        .deps = (depcount > 0) ? &binding : NULL,
        .flags = (depcount > 0) ? DEVICE_ADD_COMPOSITE : 0,
    };

    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 handle_i2c_device_resource_callback(ACPI_RESOURCE* res, void* context) {
    if (res->Type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
        return AE_OK;
    }
    if (res->Data.I2cSerialBus.Type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
        return AE_OK;
    }
    bool* is_i2cdev = context;
    *is_i2cdev = true;
    return AE_CTRL_TERMINATE;
}

static void handle_i2c_device(ACPI_HANDLE object, ACPI_DEVICE_INFO* info, zx_device_t* parent) {
    bool is_i2cdev = false;
    AcpiWalkResources(object, (char*)"_CRS", handle_i2c_device_resource_callback, &is_i2cdev);
    if (!is_i2cdev) {
        return;
    }
    publish_device(parent, object, info, NULL, ZX_PROTOCOL_ACPI, &acpi_proto, true);
}

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, false);
        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);
    } else {
        handle_i2c_device(object, info, parent);
    }

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)
