/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Copyright (C) 2016 ARM Limited
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/atomic.h>
#include <linux/completion.h>
#include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <uapi/linux/sched/types.h>
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/psci.h>
#include <linux/slab.h>
#include <linux/tick.h>
#include <linux/topology.h>

#include <asm/cpuidle.h>

#include <uapi/linux/psci.h>

#define NUM_SUSPEND_CYCLE (10)

static unsigned int nb_available_cpus;
static int tos_resident_cpu = -1;

static atomic_t nb_active_threads;
static struct completion suspend_threads_started =
	COMPLETION_INITIALIZER(suspend_threads_started);
static struct completion suspend_threads_done =
	COMPLETION_INITIALIZER(suspend_threads_done);

/*
 * We assume that PSCI operations are used if they are available. This is not
 * necessarily true on arm64, since the decision is based on the
 * "enable-method" property of each CPU in the DT, but given that there is no
 * arch-specific way to check this, we assume that the DT is sensible.
 */
static int psci_ops_check(void)
{
	int migrate_type = -1;
	int cpu;

	if (!(psci_ops.cpu_off && psci_ops.cpu_on && psci_ops.cpu_suspend)) {
		pr_warn("Missing PSCI operations, aborting tests\n");
		return -EOPNOTSUPP;
	}

	if (psci_ops.migrate_info_type)
		migrate_type = psci_ops.migrate_info_type();

	if (migrate_type == PSCI_0_2_TOS_UP_MIGRATE ||
	    migrate_type == PSCI_0_2_TOS_UP_NO_MIGRATE) {
		/* There is a UP Trusted OS, find on which core it resides. */
		for_each_online_cpu(cpu)
			if (psci_tos_resident_on(cpu)) {
				tos_resident_cpu = cpu;
				break;
			}
		if (tos_resident_cpu == -1)
			pr_warn("UP Trusted OS resides on no online CPU\n");
	}

	return 0;
}

/*
 * offlined_cpus is a temporary array but passing it as an argument avoids
 * multiple allocations.
 */
static unsigned int down_and_up_cpus(const struct cpumask *cpus,
				     struct cpumask *offlined_cpus)
{
	int cpu;
	int err = 0;

	cpumask_clear(offlined_cpus);

	/* Try to power down all CPUs in the mask. */
	for_each_cpu(cpu, cpus) {
		int ret = cpu_down(cpu);

		/*
		 * cpu_down() checks the number of online CPUs before the TOS
		 * resident CPU.
		 */
		if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
			if (ret != -EBUSY) {
				pr_err("Unexpected return code %d while trying "
				       "to power down last online CPU %d\n",
				       ret, cpu);
				++err;
			}
		} else if (cpu == tos_resident_cpu) {
			if (ret != -EPERM) {
				pr_err("Unexpected return code %d while trying "
				       "to power down TOS resident CPU %d\n",
				       ret, cpu);
				++err;
			}
		} else if (ret != 0) {
			pr_err("Error occurred (%d) while trying "
			       "to power down CPU %d\n", ret, cpu);
			++err;
		}

		if (ret == 0)
			cpumask_set_cpu(cpu, offlined_cpus);
	}

	/* Try to power up all the CPUs that have been offlined. */
	for_each_cpu(cpu, offlined_cpus) {
		int ret = cpu_up(cpu);

		if (ret != 0) {
			pr_err("Error occurred (%d) while trying "
			       "to power up CPU %d\n", ret, cpu);
			++err;
		} else {
			cpumask_clear_cpu(cpu, offlined_cpus);
		}
	}

	/*
	 * Something went bad at some point and some CPUs could not be turned
	 * back on.
	 */
	WARN_ON(!cpumask_empty(offlined_cpus) ||
		num_online_cpus() != nb_available_cpus);

	return err;
}

static void free_cpu_groups(int num, cpumask_var_t **pcpu_groups)
{
	int i;
	cpumask_var_t *cpu_groups = *pcpu_groups;

	for (i = 0; i < num; ++i)
		free_cpumask_var(cpu_groups[i]);
	kfree(cpu_groups);
}

static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
{
	int num_groups = 0;
	cpumask_var_t tmp, *cpu_groups;

	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
		return -ENOMEM;

	cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups),
			     GFP_KERNEL);
	if (!cpu_groups) {
		free_cpumask_var(tmp);
		return -ENOMEM;
	}

	cpumask_copy(tmp, cpu_online_mask);

	while (!cpumask_empty(tmp)) {
		const struct cpumask *cpu_group =
			topology_core_cpumask(cpumask_any(tmp));

		if (!alloc_cpumask_var(&cpu_groups[num_groups], GFP_KERNEL)) {
			free_cpumask_var(tmp);
			free_cpu_groups(num_groups, &cpu_groups);
			return -ENOMEM;
		}
		cpumask_copy(cpu_groups[num_groups++], cpu_group);
		cpumask_andnot(tmp, tmp, cpu_group);
	}

	free_cpumask_var(tmp);
	*pcpu_groups = cpu_groups;

	return num_groups;
}

static int hotplug_tests(void)
{
	int i, nb_cpu_group, err = -ENOMEM;
	cpumask_var_t offlined_cpus, *cpu_groups;
	char *page_buf;

	if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
		return err;

	nb_cpu_group = alloc_init_cpu_groups(&cpu_groups);
	if (nb_cpu_group < 0)
		goto out_free_cpus;
	page_buf = (char *)__get_free_page(GFP_KERNEL);
	if (!page_buf)
		goto out_free_cpu_groups;

	err = 0;
	/*
	 * Of course the last CPU cannot be powered down and cpu_down() should
	 * refuse doing that.
	 */
	pr_info("Trying to turn off and on again all CPUs\n");
	err += down_and_up_cpus(cpu_online_mask, offlined_cpus);

	/*
	 * Take down CPUs by cpu group this time. When the last CPU is turned
	 * off, the cpu group itself should shut down.
	 */
	for (i = 0; i < nb_cpu_group; ++i) {
		ssize_t len = cpumap_print_to_pagebuf(true, page_buf,
						      cpu_groups[i]);
		/* Remove trailing newline. */
		page_buf[len - 1] = '\0';
		pr_info("Trying to turn off and on again group %d (CPUs %s)\n",
			i, page_buf);
		err += down_and_up_cpus(cpu_groups[i], offlined_cpus);
	}

	free_page((unsigned long)page_buf);
out_free_cpu_groups:
	free_cpu_groups(nb_cpu_group, &cpu_groups);
out_free_cpus:
	free_cpumask_var(offlined_cpus);
	return err;
}

static void dummy_callback(struct timer_list *unused) {}

static int suspend_cpu(int index, bool broadcast)
{
	int ret;

	arch_cpu_idle_enter();

	if (broadcast) {
		/*
		 * The local timer will be shut down, we need to enter tick
		 * broadcast.
		 */
		ret = tick_broadcast_enter();
		if (ret) {
			/*
			 * In the absence of hardware broadcast mechanism,
			 * this CPU might be used to broadcast wakeups, which
			 * may be why entering tick broadcast has failed.
			 * There is little the kernel can do to work around
			 * that, so enter WFI instead (idle state 0).
			 */
			cpu_do_idle();
			ret = 0;
			goto out_arch_exit;
		}
	}

	/*
	 * Replicate the common ARM cpuidle enter function
	 * (arm_enter_idle_state).
	 */
	ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);

	if (broadcast)
		tick_broadcast_exit();

out_arch_exit:
	arch_cpu_idle_exit();

	return ret;
}

static int suspend_test_thread(void *arg)
{
	int cpu = (long)arg;
	int i, nb_suspend = 0, nb_shallow_sleep = 0, nb_err = 0;
	struct sched_param sched_priority = { .sched_priority = MAX_RT_PRIO-1 };
	struct cpuidle_device *dev;
	struct cpuidle_driver *drv;
	/* No need for an actual callback, we just want to wake up the CPU. */
	struct timer_list wakeup_timer;

	/* Wait for the main thread to give the start signal. */
	wait_for_completion(&suspend_threads_started);

	/* Set maximum priority to preempt all other threads on this CPU. */
	if (sched_setscheduler_nocheck(current, SCHED_FIFO, &sched_priority))
		pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
			cpu);

	dev = this_cpu_read(cpuidle_devices);
	drv = cpuidle_get_cpu_driver(dev);

	pr_info("CPU %d entering suspend cycles, states 1 through %d\n",
		cpu, drv->state_count - 1);

	timer_setup_on_stack(&wakeup_timer, dummy_callback, 0);
	for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
		int index;
		/*
		 * Test all possible states, except 0 (which is usually WFI and
		 * doesn't use PSCI).
		 */
		for (index = 1; index < drv->state_count; ++index) {
			struct cpuidle_state *state = &drv->states[index];
			bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
			int ret;

			/*
			 * Set the timer to wake this CPU up in some time (which
			 * should be largely sufficient for entering suspend).
			 * If the local tick is disabled when entering suspend,
			 * suspend_cpu() takes care of switching to a broadcast
			 * tick, so the timer will still wake us up.
			 */
			mod_timer(&wakeup_timer, jiffies +
				  usecs_to_jiffies(state->target_residency));

			/* IRQs must be disabled during suspend operations. */
			local_irq_disable();

			ret = suspend_cpu(index, broadcast);

			/*
			 * We have woken up. Re-enable IRQs to handle any
			 * pending interrupt, do not wait until the end of the
			 * loop.
			 */
			local_irq_enable();

			if (ret == index) {
				++nb_suspend;
			} else if (ret >= 0) {
				/* We did not enter the expected state. */
				++nb_shallow_sleep;
			} else {
				pr_err("Failed to suspend CPU %d: error %d "
				       "(requested state %d, cycle %d)\n",
				       cpu, ret, index, i);
				++nb_err;
			}
		}
	}

	/*
	 * Disable the timer to make sure that the timer will not trigger
	 * later.
	 */
	del_timer(&wakeup_timer);
	destroy_timer_on_stack(&wakeup_timer);

	if (atomic_dec_return_relaxed(&nb_active_threads) == 0)
		complete(&suspend_threads_done);

	/* Give up on RT scheduling and wait for termination. */
	sched_priority.sched_priority = 0;
	if (sched_setscheduler_nocheck(current, SCHED_NORMAL, &sched_priority))
		pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
			cpu);
	for (;;) {
		/* Needs to be set first to avoid missing a wakeup. */
		set_current_state(TASK_INTERRUPTIBLE);
		if (kthread_should_park())
			break;
		schedule();
	}

	pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
		cpu, nb_suspend, nb_shallow_sleep, nb_err);

	kthread_parkme();

	return nb_err;
}

static int suspend_tests(void)
{
	int i, cpu, err = 0;
	struct task_struct **threads;
	int nb_threads = 0;

	threads = kmalloc_array(nb_available_cpus, sizeof(*threads),
				GFP_KERNEL);
	if (!threads)
		return -ENOMEM;

	/*
	 * Stop cpuidle to prevent the idle tasks from entering a deep sleep
	 * mode, as it might interfere with the suspend threads on other CPUs.
	 * This does not prevent the suspend threads from using cpuidle (only
	 * the idle tasks check this status). Take the idle lock so that
	 * the cpuidle driver and device look-up can be carried out safely.
	 */
	cpuidle_pause_and_lock();

	for_each_online_cpu(cpu) {
		struct task_struct *thread;
		/* Check that cpuidle is available on that CPU. */
		struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
		struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);

		if (!dev || !drv) {
			pr_warn("cpuidle not available on CPU %d, ignoring\n",
				cpu);
			continue;
		}

		thread = kthread_create_on_cpu(suspend_test_thread,
					       (void *)(long)cpu, cpu,
					       "psci_suspend_test");
		if (IS_ERR(thread))
			pr_err("Failed to create kthread on CPU %d\n", cpu);
		else
			threads[nb_threads++] = thread;
	}

	if (nb_threads < 1) {
		err = -ENODEV;
		goto out;
	}

	atomic_set(&nb_active_threads, nb_threads);

	/*
	 * Wake up the suspend threads. To avoid the main thread being preempted
	 * before all the threads have been unparked, the suspend threads will
	 * wait for the completion of suspend_threads_started.
	 */
	for (i = 0; i < nb_threads; ++i)
		wake_up_process(threads[i]);
	complete_all(&suspend_threads_started);

	wait_for_completion(&suspend_threads_done);


	/* Stop and destroy all threads, get return status. */
	for (i = 0; i < nb_threads; ++i) {
		err += kthread_park(threads[i]);
		err += kthread_stop(threads[i]);
	}
 out:
	cpuidle_resume_and_unlock();
	kfree(threads);
	return err;
}

static int __init psci_checker(void)
{
	int ret;

	/*
	 * Since we're in an initcall, we assume that all the CPUs that all
	 * CPUs that can be onlined have been onlined.
	 *
	 * The tests assume that hotplug is enabled but nobody else is using it,
	 * otherwise the results will be unpredictable. However, since there
	 * is no userspace yet in initcalls, that should be fine, as long as
	 * no torture test is running at the same time (see Kconfig).
	 */
	nb_available_cpus = num_online_cpus();

	/* Check PSCI operations are set up and working. */
	ret = psci_ops_check();
	if (ret)
		return ret;

	pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);

	pr_info("Starting hotplug tests\n");
	ret = hotplug_tests();
	if (ret == 0)
		pr_info("Hotplug tests passed OK\n");
	else if (ret > 0)
		pr_err("%d error(s) encountered in hotplug tests\n", ret);
	else {
		pr_err("Out of memory\n");
		return ret;
	}

	pr_info("Starting suspend tests (%d cycles per state)\n",
		NUM_SUSPEND_CYCLE);
	ret = suspend_tests();
	if (ret == 0)
		pr_info("Suspend tests passed OK\n");
	else if (ret > 0)
		pr_err("%d error(s) encountered in suspend tests\n", ret);
	else {
		switch (ret) {
		case -ENOMEM:
			pr_err("Out of memory\n");
			break;
		case -ENODEV:
			pr_warn("Could not start suspend tests on any CPU\n");
			break;
		}
	}

	pr_info("PSCI checker completed\n");
	return ret < 0 ? ret : 0;
}
late_initcall(psci_checker);
