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

#include <zephyr.h>
#include <kernel.h>
#include <string.h>
#include <device.h>
#include "policy/pm_policy.h"

#if defined(CONFIG_PM)
#define LOG_LEVEL CONFIG_PM_LOG_LEVEL /* From power module Kconfig */
#include <logging/log.h>
LOG_MODULE_DECLARE(power);

/*
 * FIXME: Remove the conditional inclusion of
 * core_devices array once we enble the capability
 * to build the device list based on devices power
 * and clock domain dependencies.
 */

__weak const char *const z_pm_core_devices[] = {
#if defined(CONFIG_SOC_FAMILY_NRF)
	"CLOCK",
	"sys_clock",
	"UART_0",
#elif defined(CONFIG_SOC_SERIES_CC13X2_CC26X2)
	"sys_clock",
	"UART_0",
#elif defined(CONFIG_SOC_SERIES_KINETIS_K6X)
	DT_LABEL(DT_INST(0, nxp_kinetis_ethernet)),
#elif defined(CONFIG_NET_TEST)
	"",
#elif defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32WBX)
	"sys_clock",
#endif
	NULL
};

/* Ordinal of sufficient size to index available devices. */
typedef uint16_t device_idx_t;

/* The maximum value representable with a device_idx_t. */
#define DEVICE_IDX_MAX ((device_idx_t)(-1))

/* An array of all devices in the application. */
static const struct device *all_devices;

/* Indexes into all_devices for devices that support pm,
 * in dependency order (later may depend on earlier).
 */
static device_idx_t pm_devices[CONFIG_PM_MAX_DEVICES];

/* Number of devices that support pm */
static device_idx_t num_pm;

/* Number of devices successfully suspended. */
static device_idx_t num_susp;

const char *device_pm_state_str(uint32_t state)
{
	switch (state) {
	case DEVICE_PM_ACTIVE_STATE:
		return "active";
	case DEVICE_PM_LOW_POWER_STATE:
		return "low power";
	case DEVICE_PM_SUSPEND_STATE:
		return "suspend";
	case DEVICE_PM_FORCE_SUSPEND_STATE:
		return "force suspend";
	case DEVICE_PM_OFF_STATE:
		return "off";
	default:
		return "";
	}
}

static int _pm_devices(uint32_t state)
{
	num_susp = 0;

	for (int i = num_pm - 1; i >= 0; i--) {
		device_idx_t idx = pm_devices[i];
		const struct device *dev = &all_devices[idx];
		int rc;

		/* TODO: Improve the logic by checking device status
		 * and set the device states accordingly.
		 */
		rc = device_set_power_state(dev, state, NULL, NULL);
		if ((rc != -ENOTSUP) && (rc != 0)) {
			LOG_DBG("%s did not enter %s state: %d",
				dev->name, device_pm_state_str(state), rc);
			return rc;
		}

		++num_susp;
	}

	return 0;
}

int pm_suspend_devices(void)
{
	return _pm_devices(DEVICE_PM_SUSPEND_STATE);
}

int pm_low_power_devices(void)
{
	return _pm_devices(DEVICE_PM_LOW_POWER_STATE);
}

int pm_force_suspend_devices(void)
{
	return _pm_devices(DEVICE_PM_FORCE_SUSPEND_STATE);
}

void pm_resume_devices(void)
{
	device_idx_t pmi = num_pm - num_susp;

	num_susp = 0;
	while (pmi < num_pm) {
		device_idx_t idx = pm_devices[pmi];

		device_set_power_state(&all_devices[idx],
				       DEVICE_PM_ACTIVE_STATE,
				       NULL, NULL);
		++pmi;
	}
}

void pm_create_device_list(void)
{
	size_t count = z_device_get_all_static(&all_devices);
	device_idx_t pmi, core_dev;

	/*
	 * Create an ordered list of devices that will be suspended.
	 * Ordering should be done based on dependencies. Devices
	 * in the beginning of the list will be resumed first.
	 */

	__ASSERT_NO_MSG(count <= DEVICE_IDX_MAX);

	/* Reserve initial slots for core devices. */
	core_dev = 0;
	while (z_pm_core_devices[core_dev]) {
		core_dev++;
	}

	num_pm = core_dev;
	__ASSERT_NO_MSG(num_pm <= CONFIG_PM_MAX_DEVICES);

	for (pmi = 0; pmi < count; pmi++) {
		device_idx_t cdi = 0;
		const struct device *dev = &all_devices[pmi];

		/* Ignore "device"s that don't support PM */
		if ((dev->device_pm_control == NULL) ||
		    (dev->device_pm_control == device_pm_control_nop)) {
			continue;
		}

		/* Check if the device is a core device, which has a
		 * reserved slot.
		 */
		while (z_pm_core_devices[cdi]) {
			if (strcmp(dev->name, z_pm_core_devices[cdi]) == 0) {
				pm_devices[cdi] = pmi;
				break;
			}
			++cdi;
		}

		/* Append the device if it doesn't have a reserved slot. */
		if (cdi == core_dev) {
			pm_devices[num_pm++] = pmi;
		}
	}
}
#endif /* defined(CONFIG_PM) */
