/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>

#include <zephyr.h>
#include <kernel.h>
#include <power.h>
#include <misc/printk.h>
#include <power.h>
#include <soc_power.h>
#include <rtc.h>
#include <ipm.h>
#include <ipm/ipm_quark_se.h>

#ifdef TEST_CASE_SLEEP_SUCCESS
#define TASK_TIME_IN_SEC 15
#define IDLE_TIME_IN_SEC 5
#else
#define TASK_TIME_IN_SEC 5
#define IDLE_TIME_IN_SEC 15
#endif /* TEST_CASE_SLEEP_SUCCESS */

#define MAX_SUSPEND_DEVICE_COUNT 15

static struct device *suspended_devices[MAX_SUSPEND_DEVICE_COUNT];
static int suspend_device_count;
static struct k_fifo fifo;
static struct device *ipm;

QUARK_SE_IPM_DEFINE(alarm_notification, 0, QUARK_SE_IPM_OUTBOUND);

static void suspend_devices(void)
{
	for (int i = suspend_device_count - 1; i >= 0; i--) {
		device_set_power_state(suspended_devices[i],
				       DEVICE_PM_SUSPEND_STATE);
	}
}

static void resume_devices(void)
{
	for (int i = 0; i < suspend_device_count; i++) {
		device_set_power_state(suspended_devices[i],
				       DEVICE_PM_ACTIVE_STATE);
	}
}

int _sys_soc_suspend(int32_t ticks)
{
	printk("LMT: Try to put the system in SYS_POWER_STATE_DEEP_SLEEP_2"
	       " state\n");

	if (!_sys_soc_power_state_is_arc_ready()) {
		printk("LMT: Failed. ARC is busy.\n");
		return SYS_PM_NOT_HANDLED;
	}

	suspend_devices();

	_sys_soc_set_power_state(SYS_POWER_STATE_DEEP_SLEEP_2);

	resume_devices();

	printk("LMT: Succeed.\n");

	_sys_soc_power_state_post_ops(SYS_POWER_STATE_DEEP_SLEEP_2);

	return SYS_PM_DEEP_SLEEP;
}

static void build_suspend_device_list(void)
{
	int i, devcount;
	struct device *devices;

	device_list_get(&devices, &devcount);
	if (devcount > MAX_SUSPEND_DEVICE_COUNT) {
		printk("Error: List of devices exceeds what we can track "
		       "for suspend. Built: %d, Max: %d\n",
		       devcount, MAX_SUSPEND_DEVICE_COUNT);
		return;
	}

	suspend_device_count = 3;
	for (i = 0; i < devcount; i++) {
		if (!strcmp(devices[i].config->name, "loapic")) {
			suspended_devices[0] = &devices[i];
		} else if (!strcmp(devices[i].config->name, "ioapic")) {
			suspended_devices[1] = &devices[i];
		} else if (!strcmp(devices[i].config->name,
				 CONFIG_UART_CONSOLE_ON_DEV_NAME)) {
			suspended_devices[2] = &devices[i];
		} else {
			suspended_devices[suspend_device_count++] = &devices[i];
		}
	}
}

static void alarm_handler(struct device *dev)
{
	/* Unblock LMT application thread. */
	k_fifo_put(&fifo, NULL);

	/* Send a dummy message to ARC so the ARC application
	 * thread can be unblocked.
	 */
	ipm_send(ipm, 0, 0, NULL, 0);
}

void main(void)
{
	struct device *rtc_dev;
	struct rtc_config config;
	uint32_t now;

	printk("LMT: Quark SE PM Multicore Demo\n");

	k_fifo_init(&fifo);

	build_suspend_device_list();

	ipm = device_get_binding("alarm_notification");
	if (!ipm) {
		printk("Error: Failed to get IPM device\n");
		return;
	}

	rtc_dev = device_get_binding("RTC_0");
	if (!rtc_dev) {
		printk("Error: Failed to get RTC device\n");
		return;
	}

	rtc_enable(rtc_dev);

	/* In QMSI, in order to save the alarm callback we must set
	 * 'alarm_enable = 1' during configuration. However, this
	 * automatically triggers the alarm underneath. So, to avoid
	 * the alarm being fired any time soon, we set the 'init_val'
	 * to 1 and the 'alarm_val' to 0.
	 */
	config.init_val = 1;
	config.alarm_val = 0;
	config.alarm_enable = 1;
	config.cb_fn = alarm_handler;
	rtc_set_config(rtc_dev, &config);

	while (1) {
		/* Simulate some task handling by busy waiting. */
		printk("LMT: busy\n");
		k_busy_wait(TASK_TIME_IN_SEC * 1000 * 1000);

		now = rtc_read(rtc_dev);
		rtc_set_alarm(rtc_dev,
			      now + (RTC_ALARM_SECOND * IDLE_TIME_IN_SEC));

		printk("LMT: idle\n");
		k_fifo_get(&fifo, K_FOREVER);
	}
}
