// SPDX-License-Identifier: GPL-2.0
/*
 * drivers/base/power/domain_governor.c - Governors for device PM domains.
 *
 * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
 */
#include <linux/kernel.h>
#include <linux/pm_domain.h>
#include <linux/pm_qos.h>
#include <linux/hrtimer.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/ktime.h>

static int dev_update_qos_constraint(struct device *dev, void *data)
{
	s64 *constraint_ns_p = data;
	s64 constraint_ns;

	if (dev->power.subsys_data && dev->power.subsys_data->domain_data) {
		struct gpd_timing_data *td = dev_gpd_data(dev)->td;

		/*
		 * Only take suspend-time QoS constraints of devices into
		 * account, because constraints updated after the device has
		 * been suspended are not guaranteed to be taken into account
		 * anyway.  In order for them to take effect, the device has to
		 * be resumed and suspended again.
		 */
		constraint_ns = td ? td->effective_constraint_ns :
				PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
	} else {
		/*
		 * The child is not in a domain and there's no info on its
		 * suspend/resume latencies, so assume them to be negligible and
		 * take its current PM QoS constraint (that's the only thing
		 * known at this point anyway).
		 */
		constraint_ns = dev_pm_qos_read_value(dev, DEV_PM_QOS_RESUME_LATENCY);
		constraint_ns *= NSEC_PER_USEC;
	}

	if (constraint_ns < *constraint_ns_p)
		*constraint_ns_p = constraint_ns;

	return 0;
}

/**
 * default_suspend_ok - Default PM domain governor routine to suspend devices.
 * @dev: Device to check.
 *
 * Returns: true if OK to suspend, false if not OK to suspend
 */
static bool default_suspend_ok(struct device *dev)
{
	struct gpd_timing_data *td = dev_gpd_data(dev)->td;
	unsigned long flags;
	s64 constraint_ns;

	dev_dbg(dev, "%s()\n", __func__);

	spin_lock_irqsave(&dev->power.lock, flags);

	if (!td->constraint_changed) {
		bool ret = td->cached_suspend_ok;

		spin_unlock_irqrestore(&dev->power.lock, flags);
		return ret;
	}
	td->constraint_changed = false;
	td->cached_suspend_ok = false;
	td->effective_constraint_ns = 0;
	constraint_ns = __dev_pm_qos_resume_latency(dev);

	spin_unlock_irqrestore(&dev->power.lock, flags);

	if (constraint_ns == 0)
		return false;

	constraint_ns *= NSEC_PER_USEC;
	/*
	 * We can walk the children without any additional locking, because
	 * they all have been suspended at this point and their
	 * effective_constraint_ns fields won't be modified in parallel with us.
	 */
	if (!dev->power.ignore_children)
		device_for_each_child(dev, &constraint_ns,
				      dev_update_qos_constraint);

	if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS) {
		/* "No restriction", so the device is allowed to suspend. */
		td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
		td->cached_suspend_ok = true;
	} else if (constraint_ns == 0) {
		/*
		 * This triggers if one of the children that don't belong to a
		 * domain has a zero PM QoS constraint and it's better not to
		 * suspend then.  effective_constraint_ns is zero already and
		 * cached_suspend_ok is false, so bail out.
		 */
		return false;
	} else {
		constraint_ns -= td->suspend_latency_ns +
				td->resume_latency_ns;
		/*
		 * effective_constraint_ns is zero already and cached_suspend_ok
		 * is false, so if the computed value is not positive, return
		 * right away.
		 */
		if (constraint_ns <= 0)
			return false;

		td->effective_constraint_ns = constraint_ns;
		td->cached_suspend_ok = true;
	}

	/*
	 * The children have been suspended already, so we don't need to take
	 * their suspend latencies into account here.
	 */
	return td->cached_suspend_ok;
}

static void update_domain_next_wakeup(struct generic_pm_domain *genpd, ktime_t now)
{
	ktime_t domain_wakeup = KTIME_MAX;
	ktime_t next_wakeup;
	struct pm_domain_data *pdd;
	struct gpd_link *link;

	if (!(genpd->flags & GENPD_FLAG_MIN_RESIDENCY))
		return;

	/*
	 * Devices that have a predictable wakeup pattern, may specify
	 * their next wakeup. Let's find the next wakeup from all the
	 * devices attached to this domain and from all the sub-domains.
	 * It is possible that component's a next wakeup may have become
	 * stale when we read that here. We will ignore to ensure the domain
	 * is able to enter its optimal idle state.
	 */
	list_for_each_entry(pdd, &genpd->dev_list, list_node) {
		next_wakeup = to_gpd_data(pdd)->td->next_wakeup;
		if (next_wakeup != KTIME_MAX && !ktime_before(next_wakeup, now))
			if (ktime_before(next_wakeup, domain_wakeup))
				domain_wakeup = next_wakeup;
	}

	list_for_each_entry(link, &genpd->parent_links, parent_node) {
		struct genpd_governor_data *cgd = link->child->gd;

		next_wakeup = cgd ? cgd->next_wakeup : KTIME_MAX;
		if (next_wakeup != KTIME_MAX && !ktime_before(next_wakeup, now))
			if (ktime_before(next_wakeup, domain_wakeup))
				domain_wakeup = next_wakeup;
	}

	genpd->gd->next_wakeup = domain_wakeup;
}

static bool next_wakeup_allows_state(struct generic_pm_domain *genpd,
				     unsigned int state, ktime_t now)
{
	ktime_t domain_wakeup = genpd->gd->next_wakeup;
	s64 idle_time_ns, min_sleep_ns;

	min_sleep_ns = genpd->states[state].power_off_latency_ns +
		       genpd->states[state].residency_ns;

	idle_time_ns = ktime_to_ns(ktime_sub(domain_wakeup, now));

	return idle_time_ns >= min_sleep_ns;
}

static bool __default_power_down_ok(struct dev_pm_domain *pd,
				     unsigned int state)
{
	struct generic_pm_domain *genpd = pd_to_genpd(pd);
	struct gpd_link *link;
	struct pm_domain_data *pdd;
	s64 min_off_time_ns;
	s64 off_on_time_ns;

	off_on_time_ns = genpd->states[state].power_off_latency_ns +
		genpd->states[state].power_on_latency_ns;

	min_off_time_ns = -1;
	/*
	 * Check if subdomains can be off for enough time.
	 *
	 * All subdomains have been powered off already at this point.
	 */
	list_for_each_entry(link, &genpd->parent_links, parent_node) {
		struct genpd_governor_data *cgd = link->child->gd;

		s64 sd_max_off_ns = cgd ? cgd->max_off_time_ns : -1;

		if (sd_max_off_ns < 0)
			continue;

		/*
		 * Check if the subdomain is allowed to be off long enough for
		 * the current domain to turn off and on (that's how much time
		 * it will have to wait worst case).
		 */
		if (sd_max_off_ns <= off_on_time_ns)
			return false;

		if (min_off_time_ns > sd_max_off_ns || min_off_time_ns < 0)
			min_off_time_ns = sd_max_off_ns;
	}

	/*
	 * Check if the devices in the domain can be off enough time.
	 */
	list_for_each_entry(pdd, &genpd->dev_list, list_node) {
		struct gpd_timing_data *td;
		s64 constraint_ns;

		/*
		 * Check if the device is allowed to be off long enough for the
		 * domain to turn off and on (that's how much time it will
		 * have to wait worst case).
		 */
		td = to_gpd_data(pdd)->td;
		constraint_ns = td->effective_constraint_ns;
		/*
		 * Zero means "no suspend at all" and this runs only when all
		 * devices in the domain are suspended, so it must be positive.
		 */
		if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS)
			continue;

		if (constraint_ns <= off_on_time_ns)
			return false;

		if (min_off_time_ns > constraint_ns || min_off_time_ns < 0)
			min_off_time_ns = constraint_ns;
	}

	/*
	 * If the computed minimum device off time is negative, there are no
	 * latency constraints, so the domain can spend arbitrary time in the
	 * "off" state.
	 */
	if (min_off_time_ns < 0)
		return true;

	/*
	 * The difference between the computed minimum subdomain or device off
	 * time and the time needed to turn the domain on is the maximum
	 * theoretical time this domain can spend in the "off" state.
	 */
	genpd->gd->max_off_time_ns = min_off_time_ns -
		genpd->states[state].power_on_latency_ns;
	return true;
}

/**
 * _default_power_down_ok - Default generic PM domain power off governor routine.
 * @pd: PM domain to check.
 * @now: current ktime.
 *
 * This routine must be executed under the PM domain's lock.
 *
 * Returns: true if OK to power down, false if not OK to power down
 */
static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now)
{
	struct generic_pm_domain *genpd = pd_to_genpd(pd);
	struct genpd_governor_data *gd = genpd->gd;
	int state_idx = genpd->state_count - 1;
	struct gpd_link *link;

	/*
	 * Find the next wakeup from devices that can determine their own wakeup
	 * to find when the domain would wakeup and do it for every device down
	 * the hierarchy. It is not worth while to sleep if the state's residency
	 * cannot be met.
	 */
	update_domain_next_wakeup(genpd, now);
	if ((genpd->flags & GENPD_FLAG_MIN_RESIDENCY) && (gd->next_wakeup != KTIME_MAX)) {
		/* Let's find out the deepest domain idle state, the devices prefer */
		while (state_idx >= 0) {
			if (next_wakeup_allows_state(genpd, state_idx, now)) {
				gd->max_off_time_changed = true;
				break;
			}
			state_idx--;
		}

		if (state_idx < 0) {
			state_idx = 0;
			gd->cached_power_down_ok = false;
			goto done;
		}
	}

	if (!gd->max_off_time_changed) {
		genpd->state_idx = gd->cached_power_down_state_idx;
		return gd->cached_power_down_ok;
	}

	/*
	 * We have to invalidate the cached results for the parents, so
	 * use the observation that default_power_down_ok() is not
	 * going to be called for any parent until this instance
	 * returns.
	 */
	list_for_each_entry(link, &genpd->child_links, child_node) {
		struct genpd_governor_data *pgd = link->parent->gd;

		if (pgd)
			pgd->max_off_time_changed = true;
	}

	gd->max_off_time_ns = -1;
	gd->max_off_time_changed = false;
	gd->cached_power_down_ok = true;

	/*
	 * Find a state to power down to, starting from the state
	 * determined by the next wakeup.
	 */
	while (!__default_power_down_ok(pd, state_idx)) {
		if (state_idx == 0) {
			gd->cached_power_down_ok = false;
			break;
		}
		state_idx--;
	}

done:
	genpd->state_idx = state_idx;
	gd->cached_power_down_state_idx = genpd->state_idx;
	return gd->cached_power_down_ok;
}

static bool default_power_down_ok(struct dev_pm_domain *pd)
{
	return _default_power_down_ok(pd, ktime_get());
}

#ifdef CONFIG_CPU_IDLE
static bool cpu_power_down_ok(struct dev_pm_domain *pd)
{
	struct generic_pm_domain *genpd = pd_to_genpd(pd);
	struct cpuidle_device *dev;
	ktime_t domain_wakeup, next_hrtimer;
	ktime_t now = ktime_get();
	s64 idle_duration_ns;
	int cpu, i;

	/* Validate dev PM QoS constraints. */
	if (!_default_power_down_ok(pd, now))
		return false;

	if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN))
		return true;

	/*
	 * Find the next wakeup for any of the online CPUs within the PM domain
	 * and its subdomains. Note, we only need the genpd->cpus, as it already
	 * contains a mask of all CPUs from subdomains.
	 */
	domain_wakeup = ktime_set(KTIME_SEC_MAX, 0);
	for_each_cpu_and(cpu, genpd->cpus, cpu_online_mask) {
		dev = per_cpu(cpuidle_devices, cpu);
		if (dev) {
			next_hrtimer = READ_ONCE(dev->next_hrtimer);
			if (ktime_before(next_hrtimer, domain_wakeup))
				domain_wakeup = next_hrtimer;
		}
	}

	/* The minimum idle duration is from now - until the next wakeup. */
	idle_duration_ns = ktime_to_ns(ktime_sub(domain_wakeup, now));
	if (idle_duration_ns <= 0)
		return false;

	/* Store the next domain_wakeup to allow consumers to use it. */
	genpd->gd->next_hrtimer = domain_wakeup;

	/*
	 * Find the deepest idle state that has its residency value satisfied
	 * and by also taking into account the power off latency for the state.
	 * Start at the state picked by the dev PM QoS constraint validation.
	 */
	i = genpd->state_idx;
	do {
		if (idle_duration_ns >= (genpd->states[i].residency_ns +
		    genpd->states[i].power_off_latency_ns)) {
			genpd->state_idx = i;
			return true;
		}
	} while (--i >= 0);

	return false;
}

struct dev_power_governor pm_domain_cpu_gov = {
	.suspend_ok = default_suspend_ok,
	.power_down_ok = cpu_power_down_ok,
};
#endif

struct dev_power_governor simple_qos_governor = {
	.suspend_ok = default_suspend_ok,
	.power_down_ok = default_power_down_ok,
};

/*
 * pm_domain_always_on_gov - A governor implementing an always-on policy
 */
struct dev_power_governor pm_domain_always_on_gov = {
	.suspend_ok = default_suspend_ok,
};
