// SPDX-License-Identifier: GPL-2.0
/*
 * Energy Model of devices
 *
 * Copyright (c) 2018-2021, Arm ltd.
 * Written by: Quentin Perret, Arm ltd.
 * Improvements provided by: Lukasz Luba, Arm ltd.
 */

#define pr_fmt(fmt) "energy_model: " fmt

#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
#include <linux/debugfs.h>
#include <linux/energy_model.h>
#include <linux/sched/topology.h>
#include <linux/slab.h>

/*
 * Mutex serializing the registrations of performance domains and letting
 * callbacks defined by drivers sleep.
 */
static DEFINE_MUTEX(em_pd_mutex);

static void em_cpufreq_update_efficiencies(struct device *dev,
					   struct em_perf_state *table);
static void em_check_capacity_update(void);
static void em_update_workfn(struct work_struct *work);
static DECLARE_DELAYED_WORK(em_update_work, em_update_workfn);

static bool _is_cpu_device(struct device *dev)
{
	return (dev->bus == &cpu_subsys);
}

#ifdef CONFIG_DEBUG_FS
static struct dentry *rootdir;

struct em_dbg_info {
	struct em_perf_domain *pd;
	int ps_id;
};

#define DEFINE_EM_DBG_SHOW(name, fname)					\
static int em_debug_##fname##_show(struct seq_file *s, void *unused)	\
{									\
	struct em_dbg_info *em_dbg = s->private;			\
	struct em_perf_state *table;					\
	unsigned long val;						\
									\
	rcu_read_lock();						\
	table = em_perf_state_from_pd(em_dbg->pd);			\
	val = table[em_dbg->ps_id].name;				\
	rcu_read_unlock();						\
									\
	seq_printf(s, "%lu\n", val);					\
	return 0;							\
}									\
DEFINE_SHOW_ATTRIBUTE(em_debug_##fname)

DEFINE_EM_DBG_SHOW(frequency, frequency);
DEFINE_EM_DBG_SHOW(power, power);
DEFINE_EM_DBG_SHOW(cost, cost);
DEFINE_EM_DBG_SHOW(performance, performance);
DEFINE_EM_DBG_SHOW(flags, inefficiency);

static void em_debug_create_ps(struct em_perf_domain *em_pd,
			       struct em_dbg_info *em_dbg, int i,
			       struct dentry *pd)
{
	struct em_perf_state *table;
	unsigned long freq;
	struct dentry *d;
	char name[24];

	em_dbg[i].pd = em_pd;
	em_dbg[i].ps_id = i;

	rcu_read_lock();
	table = em_perf_state_from_pd(em_pd);
	freq = table[i].frequency;
	rcu_read_unlock();

	snprintf(name, sizeof(name), "ps:%lu", freq);

	/* Create per-ps directory */
	d = debugfs_create_dir(name, pd);
	debugfs_create_file("frequency", 0444, d, &em_dbg[i],
			    &em_debug_frequency_fops);
	debugfs_create_file("power", 0444, d, &em_dbg[i],
			    &em_debug_power_fops);
	debugfs_create_file("cost", 0444, d, &em_dbg[i],
			    &em_debug_cost_fops);
	debugfs_create_file("performance", 0444, d, &em_dbg[i],
			    &em_debug_performance_fops);
	debugfs_create_file("inefficient", 0444, d, &em_dbg[i],
			    &em_debug_inefficiency_fops);
}

static int em_debug_cpus_show(struct seq_file *s, void *unused)
{
	seq_printf(s, "%*pbl\n", cpumask_pr_args(to_cpumask(s->private)));

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(em_debug_cpus);

static int em_debug_flags_show(struct seq_file *s, void *unused)
{
	struct em_perf_domain *pd = s->private;

	seq_printf(s, "%#lx\n", pd->flags);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(em_debug_flags);

static void em_debug_create_pd(struct device *dev)
{
	struct em_dbg_info *em_dbg;
	struct dentry *d;
	int i;

	/* Create the directory of the performance domain */
	d = debugfs_create_dir(dev_name(dev), rootdir);

	if (_is_cpu_device(dev))
		debugfs_create_file("cpus", 0444, d, dev->em_pd->cpus,
				    &em_debug_cpus_fops);

	debugfs_create_file("flags", 0444, d, dev->em_pd,
			    &em_debug_flags_fops);

	em_dbg = devm_kcalloc(dev, dev->em_pd->nr_perf_states,
			      sizeof(*em_dbg), GFP_KERNEL);
	if (!em_dbg)
		return;

	/* Create a sub-directory for each performance state */
	for (i = 0; i < dev->em_pd->nr_perf_states; i++)
		em_debug_create_ps(dev->em_pd, em_dbg, i, d);

}

static void em_debug_remove_pd(struct device *dev)
{
	debugfs_lookup_and_remove(dev_name(dev), rootdir);
}

static int __init em_debug_init(void)
{
	/* Create /sys/kernel/debug/energy_model directory */
	rootdir = debugfs_create_dir("energy_model", NULL);

	return 0;
}
fs_initcall(em_debug_init);
#else /* CONFIG_DEBUG_FS */
static void em_debug_create_pd(struct device *dev) {}
static void em_debug_remove_pd(struct device *dev) {}
#endif

static void em_release_table_kref(struct kref *kref)
{
	/* It was the last owner of this table so we can free */
	kfree_rcu(container_of(kref, struct em_perf_table, kref), rcu);
}

/**
 * em_table_free() - Handles safe free of the EM table when needed
 * @table : EM table which is going to be freed
 *
 * No return values.
 */
void em_table_free(struct em_perf_table *table)
{
	kref_put(&table->kref, em_release_table_kref);
}

/**
 * em_table_alloc() - Allocate a new EM table
 * @pd		: EM performance domain for which this must be done
 *
 * Allocate a new EM table and initialize its kref to indicate that it
 * has a user.
 * Returns allocated table or NULL.
 */
struct em_perf_table *em_table_alloc(struct em_perf_domain *pd)
{
	struct em_perf_table *table;
	int table_size;

	table_size = sizeof(struct em_perf_state) * pd->nr_perf_states;

	table = kzalloc(sizeof(*table) + table_size, GFP_KERNEL);
	if (!table)
		return NULL;

	kref_init(&table->kref);

	return table;
}

static void em_init_performance(struct device *dev, struct em_perf_domain *pd,
				struct em_perf_state *table, int nr_states)
{
	u64 fmax, max_cap;
	int i, cpu;

	/* This is needed only for CPUs and EAS skip other devices */
	if (!_is_cpu_device(dev))
		return;

	cpu = cpumask_first(em_span_cpus(pd));

	/*
	 * Calculate the performance value for each frequency with
	 * linear relationship. The final CPU capacity might not be ready at
	 * boot time, but the EM will be updated a bit later with correct one.
	 */
	fmax = (u64) table[nr_states - 1].frequency;
	max_cap = (u64) arch_scale_cpu_capacity(cpu);
	for (i = 0; i < nr_states; i++)
		table[i].performance = div64_u64(max_cap * table[i].frequency,
						 fmax);
}

static int em_compute_costs(struct device *dev, struct em_perf_state *table,
			    struct em_data_callback *cb, int nr_states,
			    unsigned long flags)
{
	unsigned long prev_cost = ULONG_MAX;
	int i, ret;

	/* Compute the cost of each performance state. */
	for (i = nr_states - 1; i >= 0; i--) {
		unsigned long power_res, cost;

		if ((flags & EM_PERF_DOMAIN_ARTIFICIAL) && cb->get_cost) {
			ret = cb->get_cost(dev, table[i].frequency, &cost);
			if (ret || !cost || cost > EM_MAX_POWER) {
				dev_err(dev, "EM: invalid cost %lu %d\n",
					cost, ret);
				return -EINVAL;
			}
		} else {
			/* increase resolution of 'cost' precision */
			power_res = table[i].power * 10;
			cost = power_res / table[i].performance;
		}

		table[i].cost = cost;

		if (table[i].cost >= prev_cost) {
			table[i].flags = EM_PERF_STATE_INEFFICIENT;
			dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
				table[i].frequency);
		} else {
			prev_cost = table[i].cost;
		}
	}

	return 0;
}

/**
 * em_dev_compute_costs() - Calculate cost values for new runtime EM table
 * @dev		: Device for which the EM table is to be updated
 * @table	: The new EM table that is going to get the costs calculated
 * @nr_states	: Number of performance states
 *
 * Calculate the em_perf_state::cost values for new runtime EM table. The
 * values are used for EAS during task placement. It also calculates and sets
 * the efficiency flag for each performance state. When the function finish
 * successfully the EM table is ready to be updated and used by EAS.
 *
 * Return 0 on success or a proper error in case of failure.
 */
int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
			 int nr_states)
{
	return em_compute_costs(dev, table, NULL, nr_states, 0);
}

/**
 * em_dev_update_perf_domain() - Update runtime EM table for a device
 * @dev		: Device for which the EM is to be updated
 * @new_table	: The new EM table that is going to be used from now
 *
 * Update EM runtime modifiable table for the @dev using the provided @table.
 *
 * This function uses a mutex to serialize writers, so it must not be called
 * from a non-sleeping context.
 *
 * Return 0 on success or an error code on failure.
 */
int em_dev_update_perf_domain(struct device *dev,
			      struct em_perf_table *new_table)
{
	struct em_perf_table *old_table;
	struct em_perf_domain *pd;

	if (!dev)
		return -EINVAL;

	/* Serialize update/unregister or concurrent updates */
	mutex_lock(&em_pd_mutex);

	if (!dev->em_pd) {
		mutex_unlock(&em_pd_mutex);
		return -EINVAL;
	}
	pd = dev->em_pd;

	kref_get(&new_table->kref);

	old_table = rcu_dereference_protected(pd->em_table,
					      lockdep_is_held(&em_pd_mutex));
	rcu_assign_pointer(pd->em_table, new_table);

	em_cpufreq_update_efficiencies(dev, new_table->state);

	em_table_free(old_table);

	mutex_unlock(&em_pd_mutex);
	return 0;
}
EXPORT_SYMBOL_GPL(em_dev_update_perf_domain);

static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
				struct em_perf_state *table,
				struct em_data_callback *cb,
				unsigned long flags)
{
	unsigned long power, freq, prev_freq = 0;
	int nr_states = pd->nr_perf_states;
	int i, ret;

	/* Build the list of performance states for this performance domain */
	for (i = 0, freq = 0; i < nr_states; i++, freq++) {
		/*
		 * active_power() is a driver callback which ceils 'freq' to
		 * lowest performance state of 'dev' above 'freq' and updates
		 * 'power' and 'freq' accordingly.
		 */
		ret = cb->active_power(dev, &power, &freq);
		if (ret) {
			dev_err(dev, "EM: invalid perf. state: %d\n",
				ret);
			return -EINVAL;
		}

		/*
		 * We expect the driver callback to increase the frequency for
		 * higher performance states.
		 */
		if (freq <= prev_freq) {
			dev_err(dev, "EM: non-increasing freq: %lu\n",
				freq);
			return -EINVAL;
		}

		/*
		 * The power returned by active_state() is expected to be
		 * positive and be in range.
		 */
		if (!power || power > EM_MAX_POWER) {
			dev_err(dev, "EM: invalid power: %lu\n",
				power);
			return -EINVAL;
		}

		table[i].power = power;
		table[i].frequency = prev_freq = freq;
	}

	em_init_performance(dev, pd, table, nr_states);

	ret = em_compute_costs(dev, table, cb, nr_states, flags);
	if (ret)
		return -EINVAL;

	return 0;
}

static int em_create_pd(struct device *dev, int nr_states,
			struct em_data_callback *cb, cpumask_t *cpus,
			unsigned long flags)
{
	struct em_perf_table *em_table;
	struct em_perf_domain *pd;
	struct device *cpu_dev;
	int cpu, ret, num_cpus;

	if (_is_cpu_device(dev)) {
		num_cpus = cpumask_weight(cpus);

		/* Prevent max possible energy calculation to not overflow */
		if (num_cpus > EM_MAX_NUM_CPUS) {
			dev_err(dev, "EM: too many CPUs, overflow possible\n");
			return -EINVAL;
		}

		pd = kzalloc(sizeof(*pd) + cpumask_size(), GFP_KERNEL);
		if (!pd)
			return -ENOMEM;

		cpumask_copy(em_span_cpus(pd), cpus);
	} else {
		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
		if (!pd)
			return -ENOMEM;
	}

	pd->nr_perf_states = nr_states;

	em_table = em_table_alloc(pd);
	if (!em_table)
		goto free_pd;

	ret = em_create_perf_table(dev, pd, em_table->state, cb, flags);
	if (ret)
		goto free_pd_table;

	rcu_assign_pointer(pd->em_table, em_table);

	if (_is_cpu_device(dev))
		for_each_cpu(cpu, cpus) {
			cpu_dev = get_cpu_device(cpu);
			cpu_dev->em_pd = pd;
		}

	dev->em_pd = pd;

	return 0;

free_pd_table:
	kfree(em_table);
free_pd:
	kfree(pd);
	return -EINVAL;
}

static void
em_cpufreq_update_efficiencies(struct device *dev, struct em_perf_state *table)
{
	struct em_perf_domain *pd = dev->em_pd;
	struct cpufreq_policy *policy;
	int found = 0;
	int i, cpu;

	if (!_is_cpu_device(dev))
		return;

	/* Try to get a CPU which is active and in this PD */
	cpu = cpumask_first_and(em_span_cpus(pd), cpu_active_mask);
	if (cpu >= nr_cpu_ids) {
		dev_warn(dev, "EM: No online CPU for CPUFreq policy\n");
		return;
	}

	policy = cpufreq_cpu_get(cpu);
	if (!policy) {
		dev_warn(dev, "EM: Access to CPUFreq policy failed\n");
		return;
	}

	for (i = 0; i < pd->nr_perf_states; i++) {
		if (!(table[i].flags & EM_PERF_STATE_INEFFICIENT))
			continue;

		if (!cpufreq_table_set_inefficient(policy, table[i].frequency))
			found++;
	}

	cpufreq_cpu_put(policy);

	if (!found)
		return;

	/*
	 * Efficiencies have been installed in CPUFreq, inefficient frequencies
	 * will be skipped. The EM can do the same.
	 */
	pd->flags |= EM_PERF_DOMAIN_SKIP_INEFFICIENCIES;
}

/**
 * em_pd_get() - Return the performance domain for a device
 * @dev : Device to find the performance domain for
 *
 * Returns the performance domain to which @dev belongs, or NULL if it doesn't
 * exist.
 */
struct em_perf_domain *em_pd_get(struct device *dev)
{
	if (IS_ERR_OR_NULL(dev))
		return NULL;

	return dev->em_pd;
}
EXPORT_SYMBOL_GPL(em_pd_get);

/**
 * em_cpu_get() - Return the performance domain for a CPU
 * @cpu : CPU to find the performance domain for
 *
 * Returns the performance domain to which @cpu belongs, or NULL if it doesn't
 * exist.
 */
struct em_perf_domain *em_cpu_get(int cpu)
{
	struct device *cpu_dev;

	cpu_dev = get_cpu_device(cpu);
	if (!cpu_dev)
		return NULL;

	return em_pd_get(cpu_dev);
}
EXPORT_SYMBOL_GPL(em_cpu_get);

/**
 * em_dev_register_perf_domain() - Register the Energy Model (EM) for a device
 * @dev		: Device for which the EM is to register
 * @nr_states	: Number of performance states to register
 * @cb		: Callback functions providing the data of the Energy Model
 * @cpus	: Pointer to cpumask_t, which in case of a CPU device is
 *		obligatory. It can be taken from i.e. 'policy->cpus'. For other
 *		type of devices this should be set to NULL.
 * @microwatts	: Flag indicating that the power values are in micro-Watts or
 *		in some other scale. It must be set properly.
 *
 * Create Energy Model tables for a performance domain using the callbacks
 * defined in cb.
 *
 * The @microwatts is important to set with correct value. Some kernel
 * sub-systems might rely on this flag and check if all devices in the EM are
 * using the same scale.
 *
 * If multiple clients register the same performance domain, all but the first
 * registration will be ignored.
 *
 * Return 0 on success
 */
int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
				struct em_data_callback *cb, cpumask_t *cpus,
				bool microwatts)
{
	struct em_perf_table *em_table;
	unsigned long cap, prev_cap = 0;
	unsigned long flags = 0;
	int cpu, ret;

	if (!dev || !nr_states || !cb)
		return -EINVAL;

	/*
	 * Use a mutex to serialize the registration of performance domains and
	 * let the driver-defined callback functions sleep.
	 */
	mutex_lock(&em_pd_mutex);

	if (dev->em_pd) {
		ret = -EEXIST;
		goto unlock;
	}

	if (_is_cpu_device(dev)) {
		if (!cpus) {
			dev_err(dev, "EM: invalid CPU mask\n");
			ret = -EINVAL;
			goto unlock;
		}

		for_each_cpu(cpu, cpus) {
			if (em_cpu_get(cpu)) {
				dev_err(dev, "EM: exists for CPU%d\n", cpu);
				ret = -EEXIST;
				goto unlock;
			}
			/*
			 * All CPUs of a domain must have the same
			 * micro-architecture since they all share the same
			 * table.
			 */
			cap = arch_scale_cpu_capacity(cpu);
			if (prev_cap && prev_cap != cap) {
				dev_err(dev, "EM: CPUs of %*pbl must have the same capacity\n",
					cpumask_pr_args(cpus));

				ret = -EINVAL;
				goto unlock;
			}
			prev_cap = cap;
		}
	}

	if (microwatts)
		flags |= EM_PERF_DOMAIN_MICROWATTS;
	else if (cb->get_cost)
		flags |= EM_PERF_DOMAIN_ARTIFICIAL;

	/*
	 * EM only supports uW (exception is artificial EM).
	 * Therefore, check and force the drivers to provide
	 * power in uW.
	 */
	if (!microwatts && !(flags & EM_PERF_DOMAIN_ARTIFICIAL)) {
		dev_err(dev, "EM: only supports uW power values\n");
		ret = -EINVAL;
		goto unlock;
	}

	ret = em_create_pd(dev, nr_states, cb, cpus, flags);
	if (ret)
		goto unlock;

	dev->em_pd->flags |= flags;
	dev->em_pd->min_perf_state = 0;
	dev->em_pd->max_perf_state = nr_states - 1;

	em_table = rcu_dereference_protected(dev->em_pd->em_table,
					     lockdep_is_held(&em_pd_mutex));
	em_cpufreq_update_efficiencies(dev, em_table->state);

	em_debug_create_pd(dev);
	dev_info(dev, "EM: created perf domain\n");

unlock:
	mutex_unlock(&em_pd_mutex);

	if (_is_cpu_device(dev))
		em_check_capacity_update();

	return ret;
}
EXPORT_SYMBOL_GPL(em_dev_register_perf_domain);

/**
 * em_dev_unregister_perf_domain() - Unregister Energy Model (EM) for a device
 * @dev		: Device for which the EM is registered
 *
 * Unregister the EM for the specified @dev (but not a CPU device).
 */
void em_dev_unregister_perf_domain(struct device *dev)
{
	if (IS_ERR_OR_NULL(dev) || !dev->em_pd)
		return;

	if (_is_cpu_device(dev))
		return;

	/*
	 * The mutex separates all register/unregister requests and protects
	 * from potential clean-up/setup issues in the debugfs directories.
	 * The debugfs directory name is the same as device's name.
	 */
	mutex_lock(&em_pd_mutex);
	em_debug_remove_pd(dev);

	em_table_free(rcu_dereference_protected(dev->em_pd->em_table,
						lockdep_is_held(&em_pd_mutex)));

	kfree(dev->em_pd);
	dev->em_pd = NULL;
	mutex_unlock(&em_pd_mutex);
}
EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);

static struct em_perf_table *em_table_dup(struct em_perf_domain *pd)
{
	struct em_perf_table *em_table;
	struct em_perf_state *ps, *new_ps;
	int ps_size;

	em_table = em_table_alloc(pd);
	if (!em_table)
		return NULL;

	new_ps = em_table->state;

	rcu_read_lock();
	ps = em_perf_state_from_pd(pd);
	/* Initialize data based on old table */
	ps_size = sizeof(struct em_perf_state) * pd->nr_perf_states;
	memcpy(new_ps, ps, ps_size);

	rcu_read_unlock();

	return em_table;
}

static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd,
				struct em_perf_table *em_table)
{
	int ret;

	ret = em_compute_costs(dev, em_table->state, NULL, pd->nr_perf_states,
			       pd->flags);
	if (ret)
		goto free_em_table;

	ret = em_dev_update_perf_domain(dev, em_table);
	if (ret)
		goto free_em_table;

	/*
	 * This is one-time-update, so give up the ownership in this updater.
	 * The EM framework has incremented the usage counter and from now
	 * will keep the reference (then free the memory when needed).
	 */
free_em_table:
	em_table_free(em_table);
	return ret;
}

/*
 * Adjustment of CPU performance values after boot, when all CPUs capacites
 * are correctly calculated.
 */
static void em_adjust_new_capacity(struct device *dev,
				   struct em_perf_domain *pd,
				   u64 max_cap)
{
	struct em_perf_table *em_table;

	em_table = em_table_dup(pd);
	if (!em_table) {
		dev_warn(dev, "EM: allocation failed\n");
		return;
	}

	em_init_performance(dev, pd, em_table->state, pd->nr_perf_states);

	em_recalc_and_update(dev, pd, em_table);
}

static void em_check_capacity_update(void)
{
	cpumask_var_t cpu_done_mask;
	struct em_perf_state *table;
	struct em_perf_domain *pd;
	unsigned long cpu_capacity;
	int cpu;

	if (!zalloc_cpumask_var(&cpu_done_mask, GFP_KERNEL)) {
		pr_warn("no free memory\n");
		return;
	}

	/* Check if CPUs capacity has changed than update EM */
	for_each_possible_cpu(cpu) {
		struct cpufreq_policy *policy;
		unsigned long em_max_perf;
		struct device *dev;

		if (cpumask_test_cpu(cpu, cpu_done_mask))
			continue;

		policy = cpufreq_cpu_get(cpu);
		if (!policy) {
			pr_debug("Accessing cpu%d policy failed\n", cpu);
			schedule_delayed_work(&em_update_work,
					      msecs_to_jiffies(1000));
			break;
		}
		cpufreq_cpu_put(policy);

		pd = em_cpu_get(cpu);
		if (!pd || em_is_artificial(pd))
			continue;

		cpumask_or(cpu_done_mask, cpu_done_mask,
			   em_span_cpus(pd));

		cpu_capacity = arch_scale_cpu_capacity(cpu);

		rcu_read_lock();
		table = em_perf_state_from_pd(pd);
		em_max_perf = table[pd->nr_perf_states - 1].performance;
		rcu_read_unlock();

		/*
		 * Check if the CPU capacity has been adjusted during boot
		 * and trigger the update for new performance values.
		 */
		if (em_max_perf == cpu_capacity)
			continue;

		pr_debug("updating cpu%d cpu_cap=%lu old capacity=%lu\n",
			 cpu, cpu_capacity, em_max_perf);

		dev = get_cpu_device(cpu);
		em_adjust_new_capacity(dev, pd, cpu_capacity);
	}

	free_cpumask_var(cpu_done_mask);
}

static void em_update_workfn(struct work_struct *work)
{
	em_check_capacity_update();
}

/**
 * em_dev_update_chip_binning() - Update Energy Model after the new voltage
 *				information is present in the OPPs.
 * @dev		: Device for which the Energy Model has to be updated.
 *
 * This function allows to update easily the EM with new values available in
 * the OPP framework and DT. It can be used after the chip has been properly
 * verified by device drivers and the voltages adjusted for the 'chip binning'.
 */
int em_dev_update_chip_binning(struct device *dev)
{
	struct em_perf_table *em_table;
	struct em_perf_domain *pd;
	int i, ret;

	if (IS_ERR_OR_NULL(dev))
		return -EINVAL;

	pd = em_pd_get(dev);
	if (!pd) {
		dev_warn(dev, "Couldn't find Energy Model\n");
		return -EINVAL;
	}

	em_table = em_table_dup(pd);
	if (!em_table) {
		dev_warn(dev, "EM: allocation failed\n");
		return -ENOMEM;
	}

	/* Update power values which might change due to new voltage in OPPs */
	for (i = 0; i < pd->nr_perf_states; i++) {
		unsigned long freq = em_table->state[i].frequency;
		unsigned long power;

		ret = dev_pm_opp_calc_power(dev, &power, &freq);
		if (ret) {
			em_table_free(em_table);
			return ret;
		}

		em_table->state[i].power = power;
	}

	return em_recalc_and_update(dev, pd, em_table);
}
EXPORT_SYMBOL_GPL(em_dev_update_chip_binning);


/**
 * em_update_performance_limits() - Update Energy Model with performance
 *				limits information.
 * @pd			: Performance Domain with EM that has to be updated.
 * @freq_min_khz	: New minimum allowed frequency for this device.
 * @freq_max_khz	: New maximum allowed frequency for this device.
 *
 * This function allows to update the EM with information about available
 * performance levels. It takes the minimum and maximum frequency in kHz
 * and does internal translation to performance levels.
 * Returns 0 on success or -EINVAL when failed.
 */
int em_update_performance_limits(struct em_perf_domain *pd,
		unsigned long freq_min_khz, unsigned long freq_max_khz)
{
	struct em_perf_state *table;
	int min_ps = -1;
	int max_ps = -1;
	int i;

	if (!pd)
		return -EINVAL;

	rcu_read_lock();
	table = em_perf_state_from_pd(pd);

	for (i = 0; i < pd->nr_perf_states; i++) {
		if (freq_min_khz == table[i].frequency)
			min_ps = i;
		if (freq_max_khz == table[i].frequency)
			max_ps = i;
	}
	rcu_read_unlock();

	/* Only update when both are found and sane */
	if (min_ps < 0 || max_ps < 0 || max_ps < min_ps)
		return -EINVAL;


	/* Guard simultaneous updates and make them atomic */
	mutex_lock(&em_pd_mutex);
	pd->min_perf_state = min_ps;
	pd->max_perf_state = max_ps;
	mutex_unlock(&em_pd_mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(em_update_performance_limits);

static void rebuild_sd_workfn(struct work_struct *work)
{
	rebuild_sched_domains_energy();
}

void em_rebuild_sched_domains(void)
{
	static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);

	/*
	 * When called from the cpufreq_register_driver() path, the
	 * cpu_hotplug_lock is already held, so use a work item to
	 * avoid nested locking in rebuild_sched_domains().
	 */
	schedule_work(&rebuild_sd_work);
}
