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

#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/sys/__assert.h>

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);

#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
#define PM_DOMAIN(_pm) \
	(_pm)->domain
#else
#define PM_DOMAIN(_pm) NULL
#endif

/**
 * @brief Suspend a device
 *
 * @note Asynchronous operations are not supported when in pre-kernel mode. In
 * this case, the async flag will be always forced to be false, and so the
 * the function will be blocking.
 *
 * @funcprops \pre_kernel_ok
 *
 * @param dev Device instance.
 * @param async Perform operation asynchronously.
 *
 * @retval 0 If device has been suspended or queued for suspend.
 * @retval -EALREADY If device is already suspended (can only happen if get/put
 * calls are unbalanced).
 * @retval -errno Other negative errno, result of the action callback.
 */
static int runtime_suspend(const struct device *dev, bool async)
{
	int ret = 0;
	struct pm_device *pm = dev->pm;

	if (k_is_pre_kernel()) {
		async = false;
	} else {
		(void)k_mutex_lock(&pm->lock, K_FOREVER);
	}

	if ((pm->flags & BIT(PM_DEVICE_FLAG_RUNTIME_ENABLED)) == 0U) {
		goto unlock;
	}

	if (pm->usage == 0U) {
		LOG_WRN("Unbalanced suspend");
		ret = -EALREADY;
		goto unlock;
	}

	pm->usage--;
	if (pm->usage > 0U) {
		goto unlock;
	}

	if (async && !k_is_pre_kernel()) {
		/* queue suspend */
		pm->state = PM_DEVICE_STATE_SUSPENDING;
		(void)k_work_schedule(&pm->work, K_NO_WAIT);
	} else {
		/* suspend now */
		ret = pm->action_cb(pm->dev, PM_DEVICE_ACTION_SUSPEND);
		if (ret < 0) {
			pm->usage++;
			goto unlock;
		}

		pm->state = PM_DEVICE_STATE_SUSPENDED;
	}

unlock:
	if (!k_is_pre_kernel()) {
		k_mutex_unlock(&pm->lock);
	}

	return ret;
}

static void runtime_suspend_work(struct k_work *work)
{
	int ret;
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct pm_device *pm = CONTAINER_OF(dwork, struct pm_device, work);

	ret = pm->action_cb(pm->dev, PM_DEVICE_ACTION_SUSPEND);

	(void)k_mutex_lock(&pm->lock, K_FOREVER);
	if (ret < 0) {
		pm->usage++;
		pm->state = PM_DEVICE_STATE_ACTIVE;
	} else {
		pm->state = PM_DEVICE_STATE_SUSPENDED;
	}
	k_condvar_broadcast(&pm->condvar);
	k_mutex_unlock(&pm->lock);

	/*
	 * On async put, we have to suspend the domain when the device
	 * finishes its operation
	 */
	if (PM_DOMAIN(pm) != NULL) {
		(void)pm_device_runtime_put(PM_DOMAIN(pm));
	}

	__ASSERT(ret == 0, "Could not suspend device (%d)", ret);
}

int pm_device_runtime_get(const struct device *dev)
{
	int ret = 0;
	struct pm_device *pm = dev->pm;

	if (pm == NULL) {
		return -ENOTSUP;
	}

	SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_get, dev);

	if (!k_is_pre_kernel()) {
		(void)k_mutex_lock(&pm->lock, K_FOREVER);
	}

	if ((pm->flags & BIT(PM_DEVICE_FLAG_RUNTIME_ENABLED)) == 0U) {
		goto unlock;
	}

	/*
	 * If the device is under a power domain, the domain has to be get
	 * first.
	 */
	if (PM_DOMAIN(pm) != NULL) {
		ret = pm_device_runtime_get(PM_DOMAIN(pm));
		if (ret != 0) {
			goto unlock;
		}
	}

	pm->usage++;

	if (!k_is_pre_kernel()) {
		/* wait until possible async suspend is completed */
		while (pm->state == PM_DEVICE_STATE_SUSPENDING) {
			(void)k_condvar_wait(&pm->condvar, &pm->lock, K_FOREVER);
		}
	}

	if (pm->usage > 1U) {
		goto unlock;
	}

	ret = pm->action_cb(pm->dev, PM_DEVICE_ACTION_RESUME);
	if (ret < 0) {
		pm->usage--;
		goto unlock;
	}

	pm->state = PM_DEVICE_STATE_ACTIVE;

unlock:
	if (!k_is_pre_kernel()) {
		k_mutex_unlock(&pm->lock);
	}

	SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_get, dev, ret);

	return ret;
}

int pm_device_runtime_put(const struct device *dev)
{
	int ret;

	if (dev->pm == NULL) {
		return -ENOTSUP;
	}

	SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_put, dev);
	ret = runtime_suspend(dev, false);

	/*
	 * Now put the domain
	 */
	if ((ret == 0) && PM_DOMAIN(dev->pm) != NULL) {
		ret = pm_device_runtime_put(PM_DOMAIN(dev->pm));
	}
	SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_put, dev, ret);

	return ret;
}

int pm_device_runtime_put_async(const struct device *dev)
{
	int ret;

	if (dev->pm == NULL) {
		return -ENOTSUP;
	}

	SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_put_async, dev);
	ret = runtime_suspend(dev, true);
	SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_put_async, dev, ret);

	return ret;
}

int pm_device_runtime_enable(const struct device *dev)
{
	int ret = 0;
	struct pm_device *pm = dev->pm;

	if (pm == NULL) {
		return -ENOTSUP;
	}

	SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_enable, dev);

	if (pm_device_state_is_locked(dev)) {
		ret = -EPERM;
		goto end;
	}

	if (!k_is_pre_kernel()) {
		(void)k_mutex_lock(&pm->lock, K_FOREVER);
	}

	if ((pm->flags & BIT(PM_DEVICE_FLAG_RUNTIME_ENABLED)) != 0U) {
		goto unlock;
	}

	/* lazy init of PM fields */
	if (pm->dev == NULL) {
		pm->dev = dev;
		k_work_init_delayable(&pm->work, runtime_suspend_work);
	}

	if (pm->state == PM_DEVICE_STATE_ACTIVE) {
		ret = pm->action_cb(pm->dev, PM_DEVICE_ACTION_SUSPEND);
		if (ret < 0) {
			goto unlock;
		}
		pm->state = PM_DEVICE_STATE_SUSPENDED;
	}

	pm->usage = 0U;

	atomic_set_bit(&pm->flags, PM_DEVICE_FLAG_RUNTIME_ENABLED);

unlock:
	if (!k_is_pre_kernel()) {
		k_mutex_unlock(&pm->lock);
	}

end:
	SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_enable, dev, ret);
	return ret;
}

int pm_device_runtime_disable(const struct device *dev)
{
	int ret = 0;
	struct pm_device *pm = dev->pm;

	if (pm == NULL) {
		return -ENOTSUP;
	}

	SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_disable, dev);

	if (!k_is_pre_kernel()) {
		(void)k_mutex_lock(&pm->lock, K_FOREVER);
	}

	if ((pm->flags & BIT(PM_DEVICE_FLAG_RUNTIME_ENABLED)) == 0U) {
		goto unlock;
	}

	/* wait until possible async suspend is completed */
	if (!k_is_pre_kernel()) {
		while (pm->state == PM_DEVICE_STATE_SUSPENDING) {
			(void)k_condvar_wait(&pm->condvar, &pm->lock,
					     K_FOREVER);
		}
	}

	/* wake up the device if suspended */
	if (pm->state == PM_DEVICE_STATE_SUSPENDED) {
		ret = pm->action_cb(pm->dev, PM_DEVICE_ACTION_RESUME);
		if (ret < 0) {
			goto unlock;
		}

		pm->state = PM_DEVICE_STATE_ACTIVE;
	}

	atomic_clear_bit(&pm->flags, PM_DEVICE_FLAG_RUNTIME_ENABLED);

unlock:
	if (!k_is_pre_kernel()) {
		k_mutex_unlock(&pm->lock);
	}

	SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_disable, dev, ret);

	return ret;
}

bool pm_device_runtime_is_enabled(const struct device *dev)
{
	struct pm_device *pm = dev->pm;

	return pm && atomic_test_bit(&pm->flags, PM_DEVICE_FLAG_RUNTIME_ENABLED);
}
