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

extern const struct device __device_start[];
extern const struct device __device_end[];

extern const struct device *__pm_device_slots_start[];

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

static bool should_suspend(const struct device *dev, uint32_t state)
{
	int rc;
	uint32_t current_state;

	if (device_busy_check(dev) != 0) {
		return false;
	}

	rc = pm_device_state_get(dev, &current_state);
	if ((rc == -ENOSYS) || (rc != 0)) {
		LOG_DBG("Was not possible to get device %s state: %d",
			dev->name, rc);
		return false;
	}

	/*
	 * If the device is currently powered off or the request was
	 * to go to the same state, just ignore it.
	 */
	if ((current_state == PM_DEVICE_STATE_OFF) ||
			(current_state == state)) {
		return false;
	}

	return true;
}

static int _pm_devices(uint32_t state)
{
	const struct device *dev;
	num_susp = 0;

	for (dev = (__device_end - 1); dev > __device_start; dev--) {
		bool suspend;
		int rc;

		suspend = should_suspend(dev, state);
		if (suspend) {
			/*
			 * Don't bother the device if it is currently
			 * in the right state.
			 */
			rc = pm_device_state_set(dev, state, NULL, NULL);
			if ((rc != -ENOSYS) && (rc != 0)) {
				LOG_DBG("%s did not enter %s state: %d",
					dev->name, pm_device_state_str(state),
					rc);
				return rc;
			}

			__pm_device_slots_start[num_susp] = dev;
			num_susp++;
		}
	}

	return 0;
}

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

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

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

void pm_resume_devices(void)
{
	size_t i;

	for (i = 0; i < num_susp; i++) {
		pm_device_state_set(__pm_device_slots_start[i],
				       PM_DEVICE_STATE_ACTIVE,
				       NULL, NULL);
	}

	num_susp = 0;
}
#endif /* defined(CONFIG_PM) */

const char *pm_device_state_str(uint32_t state)
{
	switch (state) {
	case PM_DEVICE_STATE_ACTIVE:
		return "active";
	case PM_DEVICE_STATE_LOW_POWER:
		return "low power";
	case PM_DEVICE_STATE_SUSPEND:
		return "suspend";
	case PM_DEVICE_STATE_FORCE_SUSPEND:
		return "force suspend";
	case PM_DEVICE_STATE_OFF:
		return "off";
	default:
		return "";
	}
}

int pm_device_state_set(const struct device *dev, uint32_t device_power_state,
			pm_device_cb cb, void *arg)
{
	if (dev->pm_control == NULL) {
		return -ENOSYS;
	}

	return dev->pm_control(dev, PM_DEVICE_STATE_SET,
			       &device_power_state, cb, arg);
}

int pm_device_state_get(const struct device *dev, uint32_t *device_power_state)
{
	if (dev->pm_control == NULL) {
		return -ENOSYS;
	}

	return dev->pm_control(dev, PM_DEVICE_STATE_GET,
			       device_power_state, NULL, NULL);
}
