/*
 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <platsupport/ltimer.h>
#include <platsupport/irq.h>
#include <platsupport/fdt.h>

/* Per-platform ltimer IRQ handling function type */
typedef int (*ltimer_handle_irq_fn_t)(void *data, ps_irq_t *irq);

typedef struct {
    ltimer_t *ltimer;
    ps_irq_t *irq;
    ltimer_handle_irq_fn_t irq_handler;
} timer_callback_data_t;

/*
 * This is a simple wrapper around the per-platform ltimer IRQ handling function.
 *
 * This is called as a callback function from the IRQ interface when the user asks it to handle IRQs.
 *
 * Note that this wrapper assumes that the interrupts are level triggered.
 */
static inline void handle_irq_wrapper(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void *ack_data)
{
    assert(data);

    timer_callback_data_t *callback_data = (timer_callback_data_t *) data;

    ltimer_t *ltimer = callback_data->ltimer;
    ps_irq_t *irq = callback_data->irq;
    ltimer_handle_irq_fn_t irq_handler = callback_data->irq_handler;

    int UNUSED error = irq_handler(ltimer->data, irq);
    assert(!error);

    error = acknowledge_fn(ack_data);
    assert(!error);
}

static int helper_fdt_alloc_simple(
    ps_io_ops_t *ops, char *fdt_path,
    unsigned reg_choice, unsigned irq_choice,
    void **vmap, pmem_region_t *pmem, irq_id_t *irq_id,
    irq_callback_fn_t handler, void *handler_token
)
{
    assert(fdt_path != NULL);
    assert(vmap != NULL && pmem != NULL && irq_id != NULL);

    int error;
    void *temp_vmap;
    pmem_region_t temp_pmem;
    irq_id_t temp_irq_id;

    *vmap = NULL;
    *irq_id = PS_INVALID_IRQ_ID;

    /* Gather FDT info */
    ps_fdt_cookie_t *cookie = NULL;
    error = ps_fdt_read_path(&ops->io_fdt, &ops->malloc_ops, fdt_path, &cookie);
    if (error) {
        ZF_LOGE("Simple FDT helper failed to read path (%d, %s)", error, fdt_path);
        return error;
    }

    temp_vmap = ps_fdt_index_map_register(ops, cookie, reg_choice, &temp_pmem);
    if (temp_vmap == NULL) {
        ZF_LOGE("Simple FDT helper failed to map registers");
        return ENODEV;
    }

    temp_irq_id = ps_fdt_index_register_irq(ops, cookie, irq_choice, handler, handler_token);
    if (temp_irq_id <= PS_INVALID_IRQ_ID) {
        ZF_LOGE("Simple FDT helper failed to register irqs (%d)", temp_irq_id);
        return temp_irq_id;
    }

    error = ps_fdt_cleanup_cookie(&ops->malloc_ops, cookie);
    if (error) {
        ZF_LOGE("Simple FDT helper failed to clean up cookie (%d)", error);
        return error;
    }

    *vmap = temp_vmap;
    *pmem = temp_pmem;
    *irq_id = temp_irq_id;

    return 0;
}

static int get_resolution_dummy(void *data, uint64_t *resolution)
{
    return ENOSYS;
}

static int create_ltimer_simple(
    ltimer_t *ltimer, ps_io_ops_t ops, size_t sz,
    int (*get_time)(void *data, uint64_t *time),
    int (*set_timeout)(void *data, uint64_t ns, timeout_type_t type),
    int (*reset)(void *data),
    void (*destroy)(void *data)
)
{
    assert(ltimer != NULL);

    ltimer->get_time = get_time;
    ltimer->get_resolution = get_resolution_dummy;
    ltimer->set_timeout = set_timeout;
    ltimer->reset = reset;
    ltimer->destroy = destroy;
    ltimer->get_nth_irq = NULL;
    ltimer->get_nth_pmem = NULL;
    ltimer->get_num_irqs = NULL;
    ltimer->get_num_pmems = NULL;

    int error = ps_calloc(&ops.malloc_ops, 1, sz, &ltimer->data);
    if (error) {
        ZF_LOGE("Unable to allocate ltimer data");
        return error;
    }
    assert(ltimer->data != NULL);

    return 0;
}
