/*
 * kernel/power/autosleep.c
 *
 * Opportunistic sleep support.
 *
 * Copyright (C) 2012 Rafael J. Wysocki <rjw@sisk.pl>
 */

#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/pm_wakeup.h>

#include "power.h"

static suspend_state_t autosleep_state;
static struct workqueue_struct *autosleep_wq;
/*
 * Note: it is only safe to mutex_lock(&autosleep_lock) if a wakeup_source
 * is active, otherwise a deadlock with try_to_suspend() is possible.
 * Alternatively mutex_lock_interruptible() can be used.  This will then fail
 * if an auto_sleep cycle tries to freeze processes.
 */
static DEFINE_MUTEX(autosleep_lock);
static struct wakeup_source *autosleep_ws;

static void try_to_suspend(struct work_struct *work);
static DECLARE_WORK(suspend_work, try_to_suspend);

static void try_to_suspend(struct work_struct *work)
{
	unsigned int initial_count, final_count;

	if (pm_is_forced_sleep()) {
		mutex_lock(&autosleep_lock);
		pm_suspend(autosleep_state);
		mutex_unlock(&autosleep_lock);
		try_to_suspend(&suspend_work);
	} else {
		if (!pm_get_wakeup_count(&initial_count, true))
			goto out;

		mutex_lock(&autosleep_lock);

		if (!pm_save_wakeup_count(initial_count) ||
				system_state != SYSTEM_RUNNING) {
			mutex_unlock(&autosleep_lock);
			goto out;
		}

		if (autosleep_state == PM_SUSPEND_ON) {
			mutex_unlock(&autosleep_lock);
			return;
		}
		if (autosleep_state >= PM_SUSPEND_MAX)
			hibernate();
		else
			pm_suspend(autosleep_state);

		mutex_unlock(&autosleep_lock);

		if (!pm_get_wakeup_count(&final_count, false))
			goto out;

		/*
		 * If the wakeup occured for an unknown reason, wait to prevent
		 * system from trying to suspend and waking up in a tight loop.
		 */
		if (final_count == initial_count)
			schedule_timeout_uninterruptible(HZ / 2);
 out:
	queue_up_suspend_work();
	}
}


void queue_up_suspend_work(void)
{
	if (autosleep_state > PM_SUSPEND_ON)
		queue_work(autosleep_wq, &suspend_work);
}

suspend_state_t pm_autosleep_state(void)
{
	return autosleep_state;
}

int pm_autosleep_lock(void)
{
	return mutex_lock_interruptible(&autosleep_lock);
}

void pm_autosleep_unlock(void)
{
	mutex_unlock(&autosleep_lock);
}

int pm_autosleep_set_state(suspend_state_t state)
{

#ifndef CONFIG_HIBERNATION
	if (state >= PM_SUSPEND_MAX)
		return -EINVAL;
#endif

	__pm_stay_awake(autosleep_ws);

	mutex_lock(&autosleep_lock);

	autosleep_state = state;

	__pm_relax(autosleep_ws);

	if (state > PM_SUSPEND_ON) {
		pm_wakep_autosleep_enabled(true);
		if (pm_is_forced_sleep()) {
			mutex_unlock(&autosleep_lock);
			try_to_suspend(&suspend_work);
			return 0;
		} else
			queue_up_suspend_work();
	} else {
		pm_wakep_autosleep_enabled(false);
	}

	mutex_unlock(&autosleep_lock);
	return 0;
}

int __init pm_autosleep_init(void)
{
	autosleep_ws = wakeup_source_register("autosleep");
	if (!autosleep_ws)
		return -ENOMEM;

	autosleep_wq = alloc_ordered_workqueue("autosleep", 0);
	if (autosleep_wq)
		return 0;

	wakeup_source_unregister(autosleep_ws);
	return -ENOMEM;
}
