// SPDX-License-Identifier: GPL-2.0-only
/*
 * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework
 *	    for Non-CPU Devices.
 *
 * Copyright (C) 2011 Samsung Electronics
 *	MyungJoo Ham <myungjoo.ham@samsung.com>
 */

#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/sched.h>
#include <linux/debugfs.h>
#include <linux/devfreq_cooling.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/pm_opp.h>
#include <linux/devfreq.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/list.h>
#include <linux/printk.h>
#include <linux/hrtimer.h>
#include <linux/of.h>
#include <linux/pm_qos.h>
#include <linux/units.h>
#include "governor.h"

#define CREATE_TRACE_POINTS
#include <trace/events/devfreq.h>

#define IS_SUPPORTED_FLAG(f, name) ((f & DEVFREQ_GOV_FLAG_##name) ? true : false)
#define IS_SUPPORTED_ATTR(f, name) ((f & DEVFREQ_GOV_ATTR_##name) ? true : false)

static struct class *devfreq_class;
static struct dentry *devfreq_debugfs;

/*
 * devfreq core provides delayed work based load monitoring helper
 * functions. Governors can use these or can implement their own
 * monitoring mechanism.
 */
static struct workqueue_struct *devfreq_wq;

/* The list of all device-devfreq governors */
static LIST_HEAD(devfreq_governor_list);
/* The list of all device-devfreq */
static LIST_HEAD(devfreq_list);
static DEFINE_MUTEX(devfreq_list_lock);

static const char timer_name[][DEVFREQ_NAME_LEN] = {
	[DEVFREQ_TIMER_DEFERRABLE] = { "deferrable" },
	[DEVFREQ_TIMER_DELAYED] = { "delayed" },
};

/**
 * find_device_devfreq() - find devfreq struct using device pointer
 * @dev:	device pointer used to lookup device devfreq.
 *
 * Search the list of device devfreqs and return the matched device's
 * devfreq info. devfreq_list_lock should be held by the caller.
 */
static struct devfreq *find_device_devfreq(struct device *dev)
{
	struct devfreq *tmp_devfreq;

	lockdep_assert_held(&devfreq_list_lock);

	if (IS_ERR_OR_NULL(dev)) {
		pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	list_for_each_entry(tmp_devfreq, &devfreq_list, node) {
		if (tmp_devfreq->dev.parent == dev)
			return tmp_devfreq;
	}

	return ERR_PTR(-ENODEV);
}

static unsigned long find_available_min_freq(struct devfreq *devfreq)
{
	struct dev_pm_opp *opp;
	unsigned long min_freq = 0;

	opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &min_freq);
	if (IS_ERR(opp))
		min_freq = 0;
	else
		dev_pm_opp_put(opp);

	return min_freq;
}

static unsigned long find_available_max_freq(struct devfreq *devfreq)
{
	struct dev_pm_opp *opp;
	unsigned long max_freq = ULONG_MAX;

	opp = dev_pm_opp_find_freq_floor(devfreq->dev.parent, &max_freq);
	if (IS_ERR(opp))
		max_freq = 0;
	else
		dev_pm_opp_put(opp);

	return max_freq;
}

/**
 * devfreq_get_freq_range() - Get the current freq range
 * @devfreq:	the devfreq instance
 * @min_freq:	the min frequency
 * @max_freq:	the max frequency
 *
 * This takes into consideration all constraints.
 */
void devfreq_get_freq_range(struct devfreq *devfreq,
			    unsigned long *min_freq,
			    unsigned long *max_freq)
{
	unsigned long *freq_table = devfreq->profile->freq_table;
	s32 qos_min_freq, qos_max_freq;

	lockdep_assert_held(&devfreq->lock);

	/*
	 * Initialize minimum/maximum frequency from freq table.
	 * The devfreq drivers can initialize this in either ascending or
	 * descending order and devfreq core supports both.
	 */
	if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) {
		*min_freq = freq_table[0];
		*max_freq = freq_table[devfreq->profile->max_state - 1];
	} else {
		*min_freq = freq_table[devfreq->profile->max_state - 1];
		*max_freq = freq_table[0];
	}

	/* Apply constraints from PM QoS */
	qos_min_freq = dev_pm_qos_read_value(devfreq->dev.parent,
					     DEV_PM_QOS_MIN_FREQUENCY);
	qos_max_freq = dev_pm_qos_read_value(devfreq->dev.parent,
					     DEV_PM_QOS_MAX_FREQUENCY);
	*min_freq = max(*min_freq, (unsigned long)HZ_PER_KHZ * qos_min_freq);
	if (qos_max_freq != PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE)
		*max_freq = min(*max_freq,
				(unsigned long)HZ_PER_KHZ * qos_max_freq);

	/* Apply constraints from OPP interface */
	*min_freq = max(*min_freq, devfreq->scaling_min_freq);
	*max_freq = min(*max_freq, devfreq->scaling_max_freq);

	if (*min_freq > *max_freq)
		*min_freq = *max_freq;
}
EXPORT_SYMBOL(devfreq_get_freq_range);

/**
 * devfreq_get_freq_level() - Lookup freq_table for the frequency
 * @devfreq:	the devfreq instance
 * @freq:	the target frequency
 */
static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
{
	int lev;

	for (lev = 0; lev < devfreq->profile->max_state; lev++)
		if (freq == devfreq->profile->freq_table[lev])
			return lev;

	return -EINVAL;
}

static int set_freq_table(struct devfreq *devfreq)
{
	struct devfreq_dev_profile *profile = devfreq->profile;
	struct dev_pm_opp *opp;
	unsigned long freq;
	int i, count;

	/* Initialize the freq_table from OPP table */
	count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
	if (count <= 0)
		return -EINVAL;

	profile->max_state = count;
	profile->freq_table = devm_kcalloc(devfreq->dev.parent,
					profile->max_state,
					sizeof(*profile->freq_table),
					GFP_KERNEL);
	if (!profile->freq_table) {
		profile->max_state = 0;
		return -ENOMEM;
	}

	for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
		opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq);
		if (IS_ERR(opp)) {
			devm_kfree(devfreq->dev.parent, profile->freq_table);
			profile->max_state = 0;
			return PTR_ERR(opp);
		}
		dev_pm_opp_put(opp);
		profile->freq_table[i] = freq;
	}

	return 0;
}

/**
 * devfreq_update_status() - Update statistics of devfreq behavior
 * @devfreq:	the devfreq instance
 * @freq:	the update target frequency
 */
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
{
	int lev, prev_lev, ret = 0;
	u64 cur_time;

	lockdep_assert_held(&devfreq->lock);
	cur_time = get_jiffies_64();

	/* Immediately exit if previous_freq is not initialized yet. */
	if (!devfreq->previous_freq)
		goto out;

	prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq);
	if (prev_lev < 0) {
		ret = prev_lev;
		goto out;
	}

	devfreq->stats.time_in_state[prev_lev] +=
			cur_time - devfreq->stats.last_update;

	lev = devfreq_get_freq_level(devfreq, freq);
	if (lev < 0) {
		ret = lev;
		goto out;
	}

	if (lev != prev_lev) {
		devfreq->stats.trans_table[
			(prev_lev * devfreq->profile->max_state) + lev]++;
		devfreq->stats.total_trans++;
	}

out:
	devfreq->stats.last_update = cur_time;
	return ret;
}
EXPORT_SYMBOL(devfreq_update_status);

/**
 * find_devfreq_governor() - find devfreq governor from name
 * @name:	name of the governor
 *
 * Search the list of devfreq governors and return the matched
 * governor's pointer. devfreq_list_lock should be held by the caller.
 */
static struct devfreq_governor *find_devfreq_governor(const char *name)
{
	struct devfreq_governor *tmp_governor;

	lockdep_assert_held(&devfreq_list_lock);

	if (IS_ERR_OR_NULL(name)) {
		pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	list_for_each_entry(tmp_governor, &devfreq_governor_list, node) {
		if (!strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
			return tmp_governor;
	}

	return ERR_PTR(-ENODEV);
}

/**
 * try_then_request_governor() - Try to find the governor and request the
 *                               module if is not found.
 * @name:	name of the governor
 *
 * Search the list of devfreq governors and request the module and try again
 * if is not found. This can happen when both drivers (the governor driver
 * and the driver that call devfreq_add_device) are built as modules.
 * devfreq_list_lock should be held by the caller. Returns the matched
 * governor's pointer or an error pointer.
 */
static struct devfreq_governor *try_then_request_governor(const char *name)
{
	struct devfreq_governor *governor;
	int err = 0;

	lockdep_assert_held(&devfreq_list_lock);

	if (IS_ERR_OR_NULL(name)) {
		pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	governor = find_devfreq_governor(name);
	if (IS_ERR(governor)) {
		mutex_unlock(&devfreq_list_lock);

		if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND,
			     DEVFREQ_NAME_LEN))
			err = request_module("governor_%s", "simpleondemand");
		else
			err = request_module("governor_%s", name);
		/* Restore previous state before return */
		mutex_lock(&devfreq_list_lock);
		if (err)
			return (err < 0) ? ERR_PTR(err) : ERR_PTR(-EINVAL);

		governor = find_devfreq_governor(name);
	}

	return governor;
}

static int devfreq_notify_transition(struct devfreq *devfreq,
		struct devfreq_freqs *freqs, unsigned int state)
{
	if (!devfreq)
		return -EINVAL;

	switch (state) {
	case DEVFREQ_PRECHANGE:
		srcu_notifier_call_chain(&devfreq->transition_notifier_list,
				DEVFREQ_PRECHANGE, freqs);
		break;

	case DEVFREQ_POSTCHANGE:
		srcu_notifier_call_chain(&devfreq->transition_notifier_list,
				DEVFREQ_POSTCHANGE, freqs);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int devfreq_set_target(struct devfreq *devfreq, unsigned long new_freq,
			      u32 flags)
{
	struct devfreq_freqs freqs;
	unsigned long cur_freq;
	int err = 0;

	if (devfreq->profile->get_cur_freq)
		devfreq->profile->get_cur_freq(devfreq->dev.parent, &cur_freq);
	else
		cur_freq = devfreq->previous_freq;

	freqs.old = cur_freq;
	freqs.new = new_freq;
	devfreq_notify_transition(devfreq, &freqs, DEVFREQ_PRECHANGE);

	err = devfreq->profile->target(devfreq->dev.parent, &new_freq, flags);
	if (err) {
		freqs.new = cur_freq;
		devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);
		return err;
	}

	/*
	 * Print devfreq_frequency trace information between DEVFREQ_PRECHANGE
	 * and DEVFREQ_POSTCHANGE because for showing the correct frequency
	 * change order of between devfreq device and passive devfreq device.
	 */
	if (trace_devfreq_frequency_enabled() && new_freq != cur_freq)
		trace_devfreq_frequency(devfreq, new_freq, cur_freq);

	freqs.new = new_freq;
	devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);

	if (devfreq_update_status(devfreq, new_freq))
		dev_err(&devfreq->dev,
			"Couldn't update frequency transition information.\n");

	devfreq->previous_freq = new_freq;

	if (devfreq->suspend_freq)
		devfreq->resume_freq = new_freq;

	return err;
}

/**
 * devfreq_update_target() - Reevaluate the device and configure frequency
 *			   on the final stage.
 * @devfreq:	the devfreq instance.
 * @freq:	the new frequency of parent device. This argument
 *		is only used for devfreq device using passive governor.
 *
 * Note: Lock devfreq->lock before calling devfreq_update_target. This function
 *	 should be only used by both update_devfreq() and devfreq governors.
 */
int devfreq_update_target(struct devfreq *devfreq, unsigned long freq)
{
	unsigned long min_freq, max_freq;
	int err = 0;
	u32 flags = 0;

	lockdep_assert_held(&devfreq->lock);

	if (!devfreq->governor)
		return -EINVAL;

	/* Reevaluate the proper frequency */
	err = devfreq->governor->get_target_freq(devfreq, &freq);
	if (err)
		return err;
	devfreq_get_freq_range(devfreq, &min_freq, &max_freq);

	if (freq < min_freq) {
		freq = min_freq;
		flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
	}
	if (freq > max_freq) {
		freq = max_freq;
		flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
	}

	return devfreq_set_target(devfreq, freq, flags);
}
EXPORT_SYMBOL(devfreq_update_target);

/* Load monitoring helper functions for governors use */

/**
 * update_devfreq() - Reevaluate the device and configure frequency.
 * @devfreq:	the devfreq instance.
 *
 * Note: Lock devfreq->lock before calling update_devfreq
 *	 This function is exported for governors.
 */
int update_devfreq(struct devfreq *devfreq)
{
	return devfreq_update_target(devfreq, 0L);
}
EXPORT_SYMBOL(update_devfreq);

/**
 * devfreq_monitor() - Periodically poll devfreq objects.
 * @work:	the work struct used to run devfreq_monitor periodically.
 *
 */
static void devfreq_monitor(struct work_struct *work)
{
	int err;
	struct devfreq *devfreq = container_of(work,
					struct devfreq, work.work);

	mutex_lock(&devfreq->lock);
	err = update_devfreq(devfreq);
	if (err)
		dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err);

	queue_delayed_work(devfreq_wq, &devfreq->work,
				msecs_to_jiffies(devfreq->profile->polling_ms));
	mutex_unlock(&devfreq->lock);

	trace_devfreq_monitor(devfreq);
}

/**
 * devfreq_monitor_start() - Start load monitoring of devfreq instance
 * @devfreq:	the devfreq instance.
 *
 * Helper function for starting devfreq device load monitoring. By
 * default delayed work based monitoring is supported. Function
 * to be called from governor in response to DEVFREQ_GOV_START
 * event when device is added to devfreq framework.
 */
void devfreq_monitor_start(struct devfreq *devfreq)
{
	if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
		return;

	switch (devfreq->profile->timer) {
	case DEVFREQ_TIMER_DEFERRABLE:
		INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor);
		break;
	case DEVFREQ_TIMER_DELAYED:
		INIT_DELAYED_WORK(&devfreq->work, devfreq_monitor);
		break;
	default:
		return;
	}

	if (devfreq->profile->polling_ms)
		queue_delayed_work(devfreq_wq, &devfreq->work,
			msecs_to_jiffies(devfreq->profile->polling_ms));
}
EXPORT_SYMBOL(devfreq_monitor_start);

/**
 * devfreq_monitor_stop() - Stop load monitoring of a devfreq instance
 * @devfreq:	the devfreq instance.
 *
 * Helper function to stop devfreq device load monitoring. Function
 * to be called from governor in response to DEVFREQ_GOV_STOP
 * event when device is removed from devfreq framework.
 */
void devfreq_monitor_stop(struct devfreq *devfreq)
{
	if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
		return;

	cancel_delayed_work_sync(&devfreq->work);
}
EXPORT_SYMBOL(devfreq_monitor_stop);

/**
 * devfreq_monitor_suspend() - Suspend load monitoring of a devfreq instance
 * @devfreq:	the devfreq instance.
 *
 * Helper function to suspend devfreq device load monitoring. Function
 * to be called from governor in response to DEVFREQ_GOV_SUSPEND
 * event or when polling interval is set to zero.
 *
 * Note: Though this function is same as devfreq_monitor_stop(),
 * intentionally kept separate to provide hooks for collecting
 * transition statistics.
 */
void devfreq_monitor_suspend(struct devfreq *devfreq)
{
	mutex_lock(&devfreq->lock);
	if (devfreq->stop_polling) {
		mutex_unlock(&devfreq->lock);
		return;
	}

	devfreq_update_status(devfreq, devfreq->previous_freq);
	devfreq->stop_polling = true;
	mutex_unlock(&devfreq->lock);

	if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
		return;

	cancel_delayed_work_sync(&devfreq->work);
}
EXPORT_SYMBOL(devfreq_monitor_suspend);

/**
 * devfreq_monitor_resume() - Resume load monitoring of a devfreq instance
 * @devfreq:    the devfreq instance.
 *
 * Helper function to resume devfreq device load monitoring. Function
 * to be called from governor in response to DEVFREQ_GOV_RESUME
 * event or when polling interval is set to non-zero.
 */
void devfreq_monitor_resume(struct devfreq *devfreq)
{
	unsigned long freq;

	mutex_lock(&devfreq->lock);

	if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
		goto out_update;

	if (!devfreq->stop_polling)
		goto out;

	if (!delayed_work_pending(&devfreq->work) &&
			devfreq->profile->polling_ms)
		queue_delayed_work(devfreq_wq, &devfreq->work,
			msecs_to_jiffies(devfreq->profile->polling_ms));

out_update:
	devfreq->stats.last_update = get_jiffies_64();
	devfreq->stop_polling = false;

	if (devfreq->profile->get_cur_freq &&
		!devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
		devfreq->previous_freq = freq;

out:
	mutex_unlock(&devfreq->lock);
}
EXPORT_SYMBOL(devfreq_monitor_resume);

/**
 * devfreq_update_interval() - Update device devfreq monitoring interval
 * @devfreq:    the devfreq instance.
 * @delay:      new polling interval to be set.
 *
 * Helper function to set new load monitoring polling interval. Function
 * to be called from governor in response to DEVFREQ_GOV_UPDATE_INTERVAL event.
 */
void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay)
{
	unsigned int cur_delay = devfreq->profile->polling_ms;
	unsigned int new_delay = *delay;

	mutex_lock(&devfreq->lock);
	devfreq->profile->polling_ms = new_delay;

	if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN))
		goto out;

	if (devfreq->stop_polling)
		goto out;

	/* if new delay is zero, stop polling */
	if (!new_delay) {
		mutex_unlock(&devfreq->lock);
		cancel_delayed_work_sync(&devfreq->work);
		return;
	}

	/* if current delay is zero, start polling with new delay */
	if (!cur_delay) {
		queue_delayed_work(devfreq_wq, &devfreq->work,
			msecs_to_jiffies(devfreq->profile->polling_ms));
		goto out;
	}

	/* if current delay is greater than new delay, restart polling */
	if (cur_delay > new_delay) {
		mutex_unlock(&devfreq->lock);
		cancel_delayed_work_sync(&devfreq->work);
		mutex_lock(&devfreq->lock);
		if (!devfreq->stop_polling)
			queue_delayed_work(devfreq_wq, &devfreq->work,
				msecs_to_jiffies(devfreq->profile->polling_ms));
	}
out:
	mutex_unlock(&devfreq->lock);
}
EXPORT_SYMBOL(devfreq_update_interval);

/**
 * devfreq_notifier_call() - Notify that the device frequency requirements
 *			     has been changed out of devfreq framework.
 * @nb:		the notifier_block (supposed to be devfreq->nb)
 * @type:	not used
 * @devp:	not used
 *
 * Called by a notifier that uses devfreq->nb.
 */
static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
				 void *devp)
{
	struct devfreq *devfreq = container_of(nb, struct devfreq, nb);
	int err = -EINVAL;

	mutex_lock(&devfreq->lock);

	devfreq->scaling_min_freq = find_available_min_freq(devfreq);
	if (!devfreq->scaling_min_freq)
		goto out;

	devfreq->scaling_max_freq = find_available_max_freq(devfreq);
	if (!devfreq->scaling_max_freq) {
		devfreq->scaling_max_freq = ULONG_MAX;
		goto out;
	}

	err = update_devfreq(devfreq);

out:
	mutex_unlock(&devfreq->lock);
	if (err)
		dev_err(devfreq->dev.parent,
			"failed to update frequency from OPP notifier (%d)\n",
			err);

	return NOTIFY_OK;
}

/**
 * qos_notifier_call() - Common handler for QoS constraints.
 * @devfreq:    the devfreq instance.
 */
static int qos_notifier_call(struct devfreq *devfreq)
{
	int err;

	mutex_lock(&devfreq->lock);
	err = update_devfreq(devfreq);
	mutex_unlock(&devfreq->lock);
	if (err)
		dev_err(devfreq->dev.parent,
			"failed to update frequency from PM QoS (%d)\n",
			err);

	return NOTIFY_OK;
}

/**
 * qos_min_notifier_call() - Callback for QoS min_freq changes.
 * @nb:		Should be devfreq->nb_min
 */
static int qos_min_notifier_call(struct notifier_block *nb,
					 unsigned long val, void *ptr)
{
	return qos_notifier_call(container_of(nb, struct devfreq, nb_min));
}

/**
 * qos_max_notifier_call() - Callback for QoS max_freq changes.
 * @nb:		Should be devfreq->nb_max
 */
static int qos_max_notifier_call(struct notifier_block *nb,
					 unsigned long val, void *ptr)
{
	return qos_notifier_call(container_of(nb, struct devfreq, nb_max));
}

/**
 * devfreq_dev_release() - Callback for struct device to release the device.
 * @dev:	the devfreq device
 *
 * Remove devfreq from the list and release its resources.
 */
static void devfreq_dev_release(struct device *dev)
{
	struct devfreq *devfreq = to_devfreq(dev);
	int err;

	mutex_lock(&devfreq_list_lock);
	list_del(&devfreq->node);
	mutex_unlock(&devfreq_list_lock);

	err = dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
					 DEV_PM_QOS_MAX_FREQUENCY);
	if (err && err != -ENOENT)
		dev_warn(dev->parent,
			"Failed to remove max_freq notifier: %d\n", err);
	err = dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
					 DEV_PM_QOS_MIN_FREQUENCY);
	if (err && err != -ENOENT)
		dev_warn(dev->parent,
			"Failed to remove min_freq notifier: %d\n", err);

	if (dev_pm_qos_request_active(&devfreq->user_max_freq_req)) {
		err = dev_pm_qos_remove_request(&devfreq->user_max_freq_req);
		if (err < 0)
			dev_warn(dev->parent,
				"Failed to remove max_freq request: %d\n", err);
	}
	if (dev_pm_qos_request_active(&devfreq->user_min_freq_req)) {
		err = dev_pm_qos_remove_request(&devfreq->user_min_freq_req);
		if (err < 0)
			dev_warn(dev->parent,
				"Failed to remove min_freq request: %d\n", err);
	}

	if (devfreq->profile->exit)
		devfreq->profile->exit(devfreq->dev.parent);

	if (devfreq->opp_table)
		dev_pm_opp_put_opp_table(devfreq->opp_table);

	mutex_destroy(&devfreq->lock);
	kfree(devfreq);
}

static void create_sysfs_files(struct devfreq *devfreq,
				const struct devfreq_governor *gov);
static void remove_sysfs_files(struct devfreq *devfreq,
				const struct devfreq_governor *gov);

/**
 * devfreq_add_device() - Add devfreq feature to the device
 * @dev:	the device to add devfreq feature.
 * @profile:	device-specific profile to run devfreq.
 * @governor_name:	name of the policy to choose frequency.
 * @data:	private data for the governor. The devfreq framework does not
 *		touch this value.
 */
struct devfreq *devfreq_add_device(struct device *dev,
				   struct devfreq_dev_profile *profile,
				   const char *governor_name,
				   void *data)
{
	struct devfreq *devfreq;
	struct devfreq_governor *governor;
	unsigned long min_freq, max_freq;
	int err = 0;

	if (!dev || !profile || !governor_name) {
		dev_err(dev, "%s: Invalid parameters.\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&devfreq_list_lock);
	devfreq = find_device_devfreq(dev);
	mutex_unlock(&devfreq_list_lock);
	if (!IS_ERR(devfreq)) {
		dev_err(dev, "%s: devfreq device already exists!\n",
			__func__);
		err = -EINVAL;
		goto err_out;
	}

	devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL);
	if (!devfreq) {
		err = -ENOMEM;
		goto err_out;
	}

	mutex_init(&devfreq->lock);
	mutex_lock(&devfreq->lock);
	devfreq->dev.parent = dev;
	devfreq->dev.class = devfreq_class;
	devfreq->dev.release = devfreq_dev_release;
	INIT_LIST_HEAD(&devfreq->node);
	devfreq->profile = profile;
	devfreq->previous_freq = profile->initial_freq;
	devfreq->last_status.current_frequency = profile->initial_freq;
	devfreq->data = data;
	devfreq->nb.notifier_call = devfreq_notifier_call;

	if (devfreq->profile->timer < 0
		|| devfreq->profile->timer >= DEVFREQ_TIMER_NUM) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}

	if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
		mutex_unlock(&devfreq->lock);
		err = set_freq_table(devfreq);
		if (err < 0)
			goto err_dev;
		mutex_lock(&devfreq->lock);
	}

	devfreq->scaling_min_freq = find_available_min_freq(devfreq);
	if (!devfreq->scaling_min_freq) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}

	devfreq->scaling_max_freq = find_available_max_freq(devfreq);
	if (!devfreq->scaling_max_freq) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}

	devfreq_get_freq_range(devfreq, &min_freq, &max_freq);

	devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);
	devfreq->opp_table = dev_pm_opp_get_opp_table(dev);
	if (IS_ERR(devfreq->opp_table))
		devfreq->opp_table = NULL;

	atomic_set(&devfreq->suspend_count, 0);

	dev_set_name(&devfreq->dev, "%s", dev_name(dev));
	err = device_register(&devfreq->dev);
	if (err) {
		mutex_unlock(&devfreq->lock);
		put_device(&devfreq->dev);
		goto err_out;
	}

	devfreq->stats.trans_table = devm_kzalloc(&devfreq->dev,
			array3_size(sizeof(unsigned int),
				    devfreq->profile->max_state,
				    devfreq->profile->max_state),
			GFP_KERNEL);
	if (!devfreq->stats.trans_table) {
		mutex_unlock(&devfreq->lock);
		err = -ENOMEM;
		goto err_devfreq;
	}

	devfreq->stats.time_in_state = devm_kcalloc(&devfreq->dev,
			devfreq->profile->max_state,
			sizeof(*devfreq->stats.time_in_state),
			GFP_KERNEL);
	if (!devfreq->stats.time_in_state) {
		mutex_unlock(&devfreq->lock);
		err = -ENOMEM;
		goto err_devfreq;
	}

	devfreq->stats.total_trans = 0;
	devfreq->stats.last_update = get_jiffies_64();

	srcu_init_notifier_head(&devfreq->transition_notifier_list);

	mutex_unlock(&devfreq->lock);

	err = dev_pm_qos_add_request(dev, &devfreq->user_min_freq_req,
				     DEV_PM_QOS_MIN_FREQUENCY, 0);
	if (err < 0)
		goto err_devfreq;
	err = dev_pm_qos_add_request(dev, &devfreq->user_max_freq_req,
				     DEV_PM_QOS_MAX_FREQUENCY,
				     PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
	if (err < 0)
		goto err_devfreq;

	devfreq->nb_min.notifier_call = qos_min_notifier_call;
	err = dev_pm_qos_add_notifier(dev, &devfreq->nb_min,
				      DEV_PM_QOS_MIN_FREQUENCY);
	if (err)
		goto err_devfreq;

	devfreq->nb_max.notifier_call = qos_max_notifier_call;
	err = dev_pm_qos_add_notifier(dev, &devfreq->nb_max,
				      DEV_PM_QOS_MAX_FREQUENCY);
	if (err)
		goto err_devfreq;

	mutex_lock(&devfreq_list_lock);

	governor = try_then_request_governor(governor_name);
	if (IS_ERR(governor)) {
		dev_err(dev, "%s: Unable to find governor for the device\n",
			__func__);
		err = PTR_ERR(governor);
		goto err_init;
	}

	devfreq->governor = governor;
	err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START,
						NULL);
	if (err) {
		dev_err_probe(dev, err,
			"%s: Unable to start governor for the device\n",
			 __func__);
		goto err_init;
	}
	create_sysfs_files(devfreq, devfreq->governor);

	list_add(&devfreq->node, &devfreq_list);

	mutex_unlock(&devfreq_list_lock);

	if (devfreq->profile->is_cooling_device) {
		devfreq->cdev = devfreq_cooling_em_register(devfreq, NULL);
		if (IS_ERR(devfreq->cdev))
			devfreq->cdev = NULL;
	}

	return devfreq;

err_init:
	mutex_unlock(&devfreq_list_lock);
err_devfreq:
	devfreq_remove_device(devfreq);
	devfreq = NULL;
err_dev:
	kfree(devfreq);
err_out:
	return ERR_PTR(err);
}
EXPORT_SYMBOL(devfreq_add_device);

/**
 * devfreq_remove_device() - Remove devfreq feature from a device.
 * @devfreq:	the devfreq instance to be removed
 *
 * The opposite of devfreq_add_device().
 */
int devfreq_remove_device(struct devfreq *devfreq)
{
	if (!devfreq)
		return -EINVAL;

	devfreq_cooling_unregister(devfreq->cdev);

	if (devfreq->governor) {
		devfreq->governor->event_handler(devfreq,
						 DEVFREQ_GOV_STOP, NULL);
		remove_sysfs_files(devfreq, devfreq->governor);
	}

	device_unregister(&devfreq->dev);

	return 0;
}
EXPORT_SYMBOL(devfreq_remove_device);

static int devm_devfreq_dev_match(struct device *dev, void *res, void *data)
{
	struct devfreq **r = res;

	if (WARN_ON(!r || !*r))
		return 0;

	return *r == data;
}

static void devm_devfreq_dev_release(struct device *dev, void *res)
{
	devfreq_remove_device(*(struct devfreq **)res);
}

/**
 * devm_devfreq_add_device() - Resource-managed devfreq_add_device()
 * @dev:	the device to add devfreq feature.
 * @profile:	device-specific profile to run devfreq.
 * @governor_name:	name of the policy to choose frequency.
 * @data:	private data for the governor. The devfreq framework does not
 *		touch this value.
 *
 * This function manages automatically the memory of devfreq device using device
 * resource management and simplify the free operation for memory of devfreq
 * device.
 */
struct devfreq *devm_devfreq_add_device(struct device *dev,
					struct devfreq_dev_profile *profile,
					const char *governor_name,
					void *data)
{
	struct devfreq **ptr, *devfreq;

	ptr = devres_alloc(devm_devfreq_dev_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return ERR_PTR(-ENOMEM);

	devfreq = devfreq_add_device(dev, profile, governor_name, data);
	if (IS_ERR(devfreq)) {
		devres_free(ptr);
		return devfreq;
	}

	*ptr = devfreq;
	devres_add(dev, ptr);

	return devfreq;
}
EXPORT_SYMBOL(devm_devfreq_add_device);

#ifdef CONFIG_OF
/*
 * devfreq_get_devfreq_by_node - Get the devfreq device from devicetree
 * @node - pointer to device_node
 *
 * return the instance of devfreq device
 */
struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node)
{
	struct devfreq *devfreq;

	if (!node)
		return ERR_PTR(-EINVAL);

	mutex_lock(&devfreq_list_lock);
	list_for_each_entry(devfreq, &devfreq_list, node) {
		if (devfreq->dev.parent
			&& devfreq->dev.parent->of_node == node) {
			mutex_unlock(&devfreq_list_lock);
			return devfreq;
		}
	}
	mutex_unlock(&devfreq_list_lock);

	return ERR_PTR(-ENODEV);
}

/*
 * devfreq_get_devfreq_by_phandle - Get the devfreq device from devicetree
 * @dev - instance to the given device
 * @phandle_name - name of property holding a phandle value
 * @index - index into list of devfreq
 *
 * return the instance of devfreq device
 */
struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
					const char *phandle_name, int index)
{
	struct device_node *node;
	struct devfreq *devfreq;

	if (!dev || !phandle_name)
		return ERR_PTR(-EINVAL);

	if (!dev->of_node)
		return ERR_PTR(-EINVAL);

	node = of_parse_phandle(dev->of_node, phandle_name, index);
	if (!node)
		return ERR_PTR(-ENODEV);

	devfreq = devfreq_get_devfreq_by_node(node);
	of_node_put(node);

	return devfreq;
}

#else
struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node)
{
	return ERR_PTR(-ENODEV);
}

struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
					const char *phandle_name, int index)
{
	return ERR_PTR(-ENODEV);
}
#endif /* CONFIG_OF */
EXPORT_SYMBOL_GPL(devfreq_get_devfreq_by_node);
EXPORT_SYMBOL_GPL(devfreq_get_devfreq_by_phandle);

/**
 * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device()
 * @dev:	the device from which to remove devfreq feature.
 * @devfreq:	the devfreq instance to be removed
 */
void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq)
{
	WARN_ON(devres_release(dev, devm_devfreq_dev_release,
			       devm_devfreq_dev_match, devfreq));
}
EXPORT_SYMBOL(devm_devfreq_remove_device);

/**
 * devfreq_suspend_device() - Suspend devfreq of a device.
 * @devfreq: the devfreq instance to be suspended
 *
 * This function is intended to be called by the pm callbacks
 * (e.g., runtime_suspend, suspend) of the device driver that
 * holds the devfreq.
 */
int devfreq_suspend_device(struct devfreq *devfreq)
{
	int ret;

	if (!devfreq)
		return -EINVAL;

	if (atomic_inc_return(&devfreq->suspend_count) > 1)
		return 0;

	if (devfreq->governor) {
		ret = devfreq->governor->event_handler(devfreq,
					DEVFREQ_GOV_SUSPEND, NULL);
		if (ret)
			return ret;
	}

	if (devfreq->suspend_freq) {
		mutex_lock(&devfreq->lock);
		ret = devfreq_set_target(devfreq, devfreq->suspend_freq, 0);
		mutex_unlock(&devfreq->lock);
		if (ret)
			return ret;
	}

	return 0;
}
EXPORT_SYMBOL(devfreq_suspend_device);

/**
 * devfreq_resume_device() - Resume devfreq of a device.
 * @devfreq: the devfreq instance to be resumed
 *
 * This function is intended to be called by the pm callbacks
 * (e.g., runtime_resume, resume) of the device driver that
 * holds the devfreq.
 */
int devfreq_resume_device(struct devfreq *devfreq)
{
	int ret;

	if (!devfreq)
		return -EINVAL;

	if (atomic_dec_return(&devfreq->suspend_count) >= 1)
		return 0;

	if (devfreq->resume_freq) {
		mutex_lock(&devfreq->lock);
		ret = devfreq_set_target(devfreq, devfreq->resume_freq, 0);
		mutex_unlock(&devfreq->lock);
		if (ret)
			return ret;
	}

	if (devfreq->governor) {
		ret = devfreq->governor->event_handler(devfreq,
					DEVFREQ_GOV_RESUME, NULL);
		if (ret)
			return ret;
	}

	return 0;
}
EXPORT_SYMBOL(devfreq_resume_device);

/**
 * devfreq_suspend() - Suspend devfreq governors and devices
 *
 * Called during system wide Suspend/Hibernate cycles for suspending governors
 * and devices preserving the state for resume. On some platforms the devfreq
 * device must have precise state (frequency) after resume in order to provide
 * fully operating setup.
 */
void devfreq_suspend(void)
{
	struct devfreq *devfreq;
	int ret;

	mutex_lock(&devfreq_list_lock);
	list_for_each_entry(devfreq, &devfreq_list, node) {
		ret = devfreq_suspend_device(devfreq);
		if (ret)
			dev_err(&devfreq->dev,
				"failed to suspend devfreq device\n");
	}
	mutex_unlock(&devfreq_list_lock);
}

/**
 * devfreq_resume() - Resume devfreq governors and devices
 *
 * Called during system wide Suspend/Hibernate cycle for resuming governors and
 * devices that are suspended with devfreq_suspend().
 */
void devfreq_resume(void)
{
	struct devfreq *devfreq;
	int ret;

	mutex_lock(&devfreq_list_lock);
	list_for_each_entry(devfreq, &devfreq_list, node) {
		ret = devfreq_resume_device(devfreq);
		if (ret)
			dev_warn(&devfreq->dev,
				 "failed to resume devfreq device\n");
	}
	mutex_unlock(&devfreq_list_lock);
}

/**
 * devfreq_add_governor() - Add devfreq governor
 * @governor:	the devfreq governor to be added
 */
int devfreq_add_governor(struct devfreq_governor *governor)
{
	struct devfreq_governor *g;
	struct devfreq *devfreq;
	int err = 0;

	if (!governor) {
		pr_err("%s: Invalid parameters.\n", __func__);
		return -EINVAL;
	}

	mutex_lock(&devfreq_list_lock);
	g = find_devfreq_governor(governor->name);
	if (!IS_ERR(g)) {
		pr_err("%s: governor %s already registered\n", __func__,
		       g->name);
		err = -EINVAL;
		goto err_out;
	}

	list_add(&governor->node, &devfreq_governor_list);

	list_for_each_entry(devfreq, &devfreq_list, node) {
		int ret = 0;
		struct device *dev = devfreq->dev.parent;

		if (!strncmp(devfreq->governor->name, governor->name,
			     DEVFREQ_NAME_LEN)) {
			/* The following should never occur */
			if (devfreq->governor) {
				dev_warn(dev,
					 "%s: Governor %s already present\n",
					 __func__, devfreq->governor->name);
				ret = devfreq->governor->event_handler(devfreq,
							DEVFREQ_GOV_STOP, NULL);
				if (ret) {
					dev_warn(dev,
						 "%s: Governor %s stop = %d\n",
						 __func__,
						 devfreq->governor->name, ret);
				}
				/* Fall through */
			}
			devfreq->governor = governor;
			ret = devfreq->governor->event_handler(devfreq,
						DEVFREQ_GOV_START, NULL);
			if (ret) {
				dev_warn(dev, "%s: Governor %s start=%d\n",
					 __func__, devfreq->governor->name,
					 ret);
			}
		}
	}

err_out:
	mutex_unlock(&devfreq_list_lock);

	return err;
}
EXPORT_SYMBOL(devfreq_add_governor);

/**
 * devfreq_remove_governor() - Remove devfreq feature from a device.
 * @governor:	the devfreq governor to be removed
 */
int devfreq_remove_governor(struct devfreq_governor *governor)
{
	struct devfreq_governor *g;
	struct devfreq *devfreq;
	int err = 0;

	if (!governor) {
		pr_err("%s: Invalid parameters.\n", __func__);
		return -EINVAL;
	}

	mutex_lock(&devfreq_list_lock);
	g = find_devfreq_governor(governor->name);
	if (IS_ERR(g)) {
		pr_err("%s: governor %s not registered\n", __func__,
		       governor->name);
		err = PTR_ERR(g);
		goto err_out;
	}
	list_for_each_entry(devfreq, &devfreq_list, node) {
		int ret;
		struct device *dev = devfreq->dev.parent;

		if (!strncmp(devfreq->governor->name, governor->name,
			     DEVFREQ_NAME_LEN)) {
			/* we should have a devfreq governor! */
			if (!devfreq->governor) {
				dev_warn(dev, "%s: Governor %s NOT present\n",
					 __func__, governor->name);
				continue;
				/* Fall through */
			}
			ret = devfreq->governor->event_handler(devfreq,
						DEVFREQ_GOV_STOP, NULL);
			if (ret) {
				dev_warn(dev, "%s: Governor %s stop=%d\n",
					 __func__, devfreq->governor->name,
					 ret);
			}
			devfreq->governor = NULL;
		}
	}

	list_del(&governor->node);
err_out:
	mutex_unlock(&devfreq_list_lock);

	return err;
}
EXPORT_SYMBOL(devfreq_remove_governor);

static ssize_t name_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	return sprintf(buf, "%s\n", dev_name(df->dev.parent));
}
static DEVICE_ATTR_RO(name);

static ssize_t governor_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct devfreq *df = to_devfreq(dev);

	if (!df->governor)
		return -EINVAL;

	return sprintf(buf, "%s\n", df->governor->name);
}

static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	int ret;
	char str_governor[DEVFREQ_NAME_LEN + 1];
	const struct devfreq_governor *governor, *prev_governor;

	if (!df->governor)
		return -EINVAL;

	ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
	if (ret != 1)
		return -EINVAL;

	mutex_lock(&devfreq_list_lock);
	governor = try_then_request_governor(str_governor);
	if (IS_ERR(governor)) {
		ret = PTR_ERR(governor);
		goto out;
	}
	if (df->governor == governor) {
		ret = 0;
		goto out;
	} else if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)
		|| IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE)) {
		ret = -EINVAL;
		goto out;
	}

	/*
	 * Stop the current governor and remove the specific sysfs files
	 * which depend on current governor.
	 */
	ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
	if (ret) {
		dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
			 __func__, df->governor->name, ret);
		goto out;
	}
	remove_sysfs_files(df, df->governor);

	/*
	 * Start the new governor and create the specific sysfs files
	 * which depend on the new governor.
	 */
	prev_governor = df->governor;
	df->governor = governor;
	ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
	if (ret) {
		dev_warn(dev, "%s: Governor %s not started(%d)\n",
			 __func__, df->governor->name, ret);

		/* Restore previous governor */
		df->governor = prev_governor;
		ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
		if (ret) {
			dev_err(dev,
				"%s: reverting to Governor %s failed (%d)\n",
				__func__, prev_governor->name, ret);
			df->governor = NULL;
			goto out;
		}
	}

	/*
	 * Create the sysfs files for the new governor. But if failed to start
	 * the new governor, restore the sysfs files of previous governor.
	 */
	create_sysfs_files(df, df->governor);

out:
	mutex_unlock(&devfreq_list_lock);

	if (!ret)
		ret = count;
	return ret;
}
static DEVICE_ATTR_RW(governor);

static ssize_t available_governors_show(struct device *d,
					struct device_attribute *attr,
					char *buf)
{
	struct devfreq *df = to_devfreq(d);
	ssize_t count = 0;

	if (!df->governor)
		return -EINVAL;

	mutex_lock(&devfreq_list_lock);

	/*
	 * The devfreq with immutable governor (e.g., passive) shows
	 * only own governor.
	 */
	if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)) {
		count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
				  "%s ", df->governor->name);
	/*
	 * The devfreq device shows the registered governor except for
	 * immutable governors such as passive governor .
	 */
	} else {
		struct devfreq_governor *governor;

		list_for_each_entry(governor, &devfreq_governor_list, node) {
			if (IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE))
				continue;
			count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
					   "%s ", governor->name);
		}
	}

	mutex_unlock(&devfreq_list_lock);

	/* Truncate the trailing space */
	if (count)
		count--;

	count += sprintf(&buf[count], "\n");

	return count;
}
static DEVICE_ATTR_RO(available_governors);

static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	unsigned long freq;
	struct devfreq *df = to_devfreq(dev);

	if (!df->profile)
		return -EINVAL;

	if (df->profile->get_cur_freq &&
		!df->profile->get_cur_freq(df->dev.parent, &freq))
		return sprintf(buf, "%lu\n", freq);

	return sprintf(buf, "%lu\n", df->previous_freq);
}
static DEVICE_ATTR_RO(cur_freq);

static ssize_t target_freq_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct devfreq *df = to_devfreq(dev);

	return sprintf(buf, "%lu\n", df->previous_freq);
}
static DEVICE_ATTR_RO(target_freq);

static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long value;
	int ret;

	/*
	 * Protect against theoretical sysfs writes between
	 * device_add and dev_pm_qos_add_request
	 */
	if (!dev_pm_qos_request_active(&df->user_min_freq_req))
		return -EAGAIN;

	ret = sscanf(buf, "%lu", &value);
	if (ret != 1)
		return -EINVAL;

	/* Round down to kHz for PM QoS */
	ret = dev_pm_qos_update_request(&df->user_min_freq_req,
					value / HZ_PER_KHZ);
	if (ret < 0)
		return ret;

	return count;
}

static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long min_freq, max_freq;

	mutex_lock(&df->lock);
	devfreq_get_freq_range(df, &min_freq, &max_freq);
	mutex_unlock(&df->lock);

	return sprintf(buf, "%lu\n", min_freq);
}
static DEVICE_ATTR_RW(min_freq);

static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long value;
	int ret;

	/*
	 * Protect against theoretical sysfs writes between
	 * device_add and dev_pm_qos_add_request
	 */
	if (!dev_pm_qos_request_active(&df->user_max_freq_req))
		return -EINVAL;

	ret = sscanf(buf, "%lu", &value);
	if (ret != 1)
		return -EINVAL;

	/*
	 * PM QoS frequencies are in kHz so we need to convert. Convert by
	 * rounding upwards so that the acceptable interval never shrinks.
	 *
	 * For example if the user writes "666666666" to sysfs this value will
	 * be converted to 666667 kHz and back to 666667000 Hz before an OPP
	 * lookup, this ensures that an OPP of 666666666Hz is still accepted.
	 *
	 * A value of zero means "no limit".
	 */
	if (value)
		value = DIV_ROUND_UP(value, HZ_PER_KHZ);
	else
		value = PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;

	ret = dev_pm_qos_update_request(&df->user_max_freq_req, value);
	if (ret < 0)
		return ret;

	return count;
}

static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long min_freq, max_freq;

	mutex_lock(&df->lock);
	devfreq_get_freq_range(df, &min_freq, &max_freq);
	mutex_unlock(&df->lock);

	return sprintf(buf, "%lu\n", max_freq);
}
static DEVICE_ATTR_RW(max_freq);

static ssize_t available_frequencies_show(struct device *d,
					  struct device_attribute *attr,
					  char *buf)
{
	struct devfreq *df = to_devfreq(d);
	ssize_t count = 0;
	int i;

	if (!df->profile)
		return -EINVAL;

	mutex_lock(&df->lock);

	for (i = 0; i < df->profile->max_state; i++)
		count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
				"%lu ", df->profile->freq_table[i]);

	mutex_unlock(&df->lock);
	/* Truncate the trailing space */
	if (count)
		count--;

	count += sprintf(&buf[count], "\n");

	return count;
}
static DEVICE_ATTR_RO(available_frequencies);

static ssize_t trans_stat_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	ssize_t len;
	int i, j;
	unsigned int max_state;

	if (!df->profile)
		return -EINVAL;
	max_state = df->profile->max_state;

	if (max_state == 0)
		return sprintf(buf, "Not Supported.\n");

	mutex_lock(&df->lock);
	if (!df->stop_polling &&
			devfreq_update_status(df, df->previous_freq)) {
		mutex_unlock(&df->lock);
		return 0;
	}
	mutex_unlock(&df->lock);

	len = sprintf(buf, "     From  :   To\n");
	len += sprintf(buf + len, "           :");
	for (i = 0; i < max_state; i++)
		len += sprintf(buf + len, "%10lu",
				df->profile->freq_table[i]);

	len += sprintf(buf + len, "   time(ms)\n");

	for (i = 0; i < max_state; i++) {
		if (df->profile->freq_table[i]
					== df->previous_freq) {
			len += sprintf(buf + len, "*");
		} else {
			len += sprintf(buf + len, " ");
		}
		len += sprintf(buf + len, "%10lu:",
				df->profile->freq_table[i]);
		for (j = 0; j < max_state; j++)
			len += sprintf(buf + len, "%10u",
				df->stats.trans_table[(i * max_state) + j]);

		len += sprintf(buf + len, "%10llu\n", (u64)
			jiffies64_to_msecs(df->stats.time_in_state[i]));
	}

	len += sprintf(buf + len, "Total transition : %u\n",
					df->stats.total_trans);
	return len;
}

static ssize_t trans_stat_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	int err, value;

	if (!df->profile)
		return -EINVAL;

	if (df->profile->max_state == 0)
		return count;

	err = kstrtoint(buf, 10, &value);
	if (err || value != 0)
		return -EINVAL;

	mutex_lock(&df->lock);
	memset(df->stats.time_in_state, 0, (df->profile->max_state *
					sizeof(*df->stats.time_in_state)));
	memset(df->stats.trans_table, 0, array3_size(sizeof(unsigned int),
					df->profile->max_state,
					df->profile->max_state));
	df->stats.total_trans = 0;
	df->stats.last_update = get_jiffies_64();
	mutex_unlock(&df->lock);

	return count;
}
static DEVICE_ATTR_RW(trans_stat);

static struct attribute *devfreq_attrs[] = {
	&dev_attr_name.attr,
	&dev_attr_governor.attr,
	&dev_attr_available_governors.attr,
	&dev_attr_cur_freq.attr,
	&dev_attr_available_frequencies.attr,
	&dev_attr_target_freq.attr,
	&dev_attr_min_freq.attr,
	&dev_attr_max_freq.attr,
	&dev_attr_trans_stat.attr,
	NULL,
};
ATTRIBUTE_GROUPS(devfreq);

static ssize_t polling_interval_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct devfreq *df = to_devfreq(dev);

	if (!df->profile)
		return -EINVAL;

	return sprintf(buf, "%d\n", df->profile->polling_ms);
}

static ssize_t polling_interval_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned int value;
	int ret;

	if (!df->governor)
		return -EINVAL;

	ret = sscanf(buf, "%u", &value);
	if (ret != 1)
		return -EINVAL;

	df->governor->event_handler(df, DEVFREQ_GOV_UPDATE_INTERVAL, &value);
	ret = count;

	return ret;
}
static DEVICE_ATTR_RW(polling_interval);

static ssize_t timer_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct devfreq *df = to_devfreq(dev);

	if (!df->profile)
		return -EINVAL;

	return sprintf(buf, "%s\n", timer_name[df->profile->timer]);
}

static ssize_t timer_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	char str_timer[DEVFREQ_NAME_LEN + 1];
	int timer = -1;
	int ret = 0, i;

	if (!df->governor || !df->profile)
		return -EINVAL;

	ret = sscanf(buf, "%16s", str_timer);
	if (ret != 1)
		return -EINVAL;

	for (i = 0; i < DEVFREQ_TIMER_NUM; i++) {
		if (!strncmp(timer_name[i], str_timer, DEVFREQ_NAME_LEN)) {
			timer = i;
			break;
		}
	}

	if (timer < 0) {
		ret = -EINVAL;
		goto out;
	}

	if (df->profile->timer == timer) {
		ret = 0;
		goto out;
	}

	mutex_lock(&df->lock);
	df->profile->timer = timer;
	mutex_unlock(&df->lock);

	ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
	if (ret) {
		dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
			 __func__, df->governor->name, ret);
		goto out;
	}

	ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
	if (ret)
		dev_warn(dev, "%s: Governor %s not started(%d)\n",
			 __func__, df->governor->name, ret);
out:
	return ret ? ret : count;
}
static DEVICE_ATTR_RW(timer);

#define CREATE_SYSFS_FILE(df, name)					\
{									\
	int ret;							\
	ret = sysfs_create_file(&df->dev.kobj, &dev_attr_##name.attr);	\
	if (ret < 0) {							\
		dev_warn(&df->dev,					\
			"Unable to create attr(%s)\n", "##name");	\
	}								\
}									\

/* Create the specific sysfs files which depend on each governor. */
static void create_sysfs_files(struct devfreq *devfreq,
				const struct devfreq_governor *gov)
{
	if (IS_SUPPORTED_ATTR(gov->attrs, POLLING_INTERVAL))
		CREATE_SYSFS_FILE(devfreq, polling_interval);
	if (IS_SUPPORTED_ATTR(gov->attrs, TIMER))
		CREATE_SYSFS_FILE(devfreq, timer);
}

/* Remove the specific sysfs files which depend on each governor. */
static void remove_sysfs_files(struct devfreq *devfreq,
				const struct devfreq_governor *gov)
{
	if (IS_SUPPORTED_ATTR(gov->attrs, POLLING_INTERVAL))
		sysfs_remove_file(&devfreq->dev.kobj,
				&dev_attr_polling_interval.attr);
	if (IS_SUPPORTED_ATTR(gov->attrs, TIMER))
		sysfs_remove_file(&devfreq->dev.kobj, &dev_attr_timer.attr);
}

/**
 * devfreq_summary_show() - Show the summary of the devfreq devices
 * @s:		seq_file instance to show the summary of devfreq devices
 * @data:	not used
 *
 * Show the summary of the devfreq devices via 'devfreq_summary' debugfs file.
 * It helps that user can know the detailed information of the devfreq devices.
 *
 * Return 0 always because it shows the information without any data change.
 */
static int devfreq_summary_show(struct seq_file *s, void *data)
{
	struct devfreq *devfreq;
	struct devfreq *p_devfreq = NULL;
	unsigned long cur_freq, min_freq, max_freq;
	unsigned int polling_ms;
	unsigned int timer;

	seq_printf(s, "%-30s %-30s %-15s %-10s %10s %12s %12s %12s\n",
			"dev",
			"parent_dev",
			"governor",
			"timer",
			"polling_ms",
			"cur_freq_Hz",
			"min_freq_Hz",
			"max_freq_Hz");
	seq_printf(s, "%30s %30s %15s %10s %10s %12s %12s %12s\n",
			"------------------------------",
			"------------------------------",
			"---------------",
			"----------",
			"----------",
			"------------",
			"------------",
			"------------");

	mutex_lock(&devfreq_list_lock);

	list_for_each_entry_reverse(devfreq, &devfreq_list, node) {
#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
		if (!strncmp(devfreq->governor->name, DEVFREQ_GOV_PASSIVE,
							DEVFREQ_NAME_LEN)) {
			struct devfreq_passive_data *data = devfreq->data;

			if (data)
				p_devfreq = data->parent;
		} else {
			p_devfreq = NULL;
		}
#endif

		mutex_lock(&devfreq->lock);
		cur_freq = devfreq->previous_freq;
		devfreq_get_freq_range(devfreq, &min_freq, &max_freq);
		timer = devfreq->profile->timer;

		if (IS_SUPPORTED_ATTR(devfreq->governor->attrs, POLLING_INTERVAL))
			polling_ms = devfreq->profile->polling_ms;
		else
			polling_ms = 0;
		mutex_unlock(&devfreq->lock);

		seq_printf(s,
			"%-30s %-30s %-15s %-10s %10d %12ld %12ld %12ld\n",
			dev_name(&devfreq->dev),
			p_devfreq ? dev_name(&p_devfreq->dev) : "null",
			devfreq->governor->name,
			polling_ms ? timer_name[timer] : "null",
			polling_ms,
			cur_freq,
			min_freq,
			max_freq);
	}

	mutex_unlock(&devfreq_list_lock);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(devfreq_summary);

static int __init devfreq_init(void)
{
	devfreq_class = class_create(THIS_MODULE, "devfreq");
	if (IS_ERR(devfreq_class)) {
		pr_err("%s: couldn't create class\n", __FILE__);
		return PTR_ERR(devfreq_class);
	}

	devfreq_wq = create_freezable_workqueue("devfreq_wq");
	if (!devfreq_wq) {
		class_destroy(devfreq_class);
		pr_err("%s: couldn't create workqueue\n", __FILE__);
		return -ENOMEM;
	}
	devfreq_class->dev_groups = devfreq_groups;

	devfreq_debugfs = debugfs_create_dir("devfreq", NULL);
	debugfs_create_file("devfreq_summary", 0444,
				devfreq_debugfs, NULL,
				&devfreq_summary_fops);

	return 0;
}
subsys_initcall(devfreq_init);

/*
 * The following are helper functions for devfreq user device drivers with
 * OPP framework.
 */

/**
 * devfreq_recommended_opp() - Helper function to get proper OPP for the
 *			     freq value given to target callback.
 * @dev:	The devfreq user device. (parent of devfreq)
 * @freq:	The frequency given to target function
 * @flags:	Flags handed from devfreq framework.
 *
 * The callers are required to call dev_pm_opp_put() for the returned OPP after
 * use.
 */
struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
					   unsigned long *freq,
					   u32 flags)
{
	struct dev_pm_opp *opp;

	if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) {
		/* The freq is an upper bound. opp should be lower */
		opp = dev_pm_opp_find_freq_floor(dev, freq);

		/* If not available, use the closest opp */
		if (opp == ERR_PTR(-ERANGE))
			opp = dev_pm_opp_find_freq_ceil(dev, freq);
	} else {
		/* The freq is an lower bound. opp should be higher */
		opp = dev_pm_opp_find_freq_ceil(dev, freq);

		/* If not available, use the closest opp */
		if (opp == ERR_PTR(-ERANGE))
			opp = dev_pm_opp_find_freq_floor(dev, freq);
	}

	return opp;
}
EXPORT_SYMBOL(devfreq_recommended_opp);

/**
 * devfreq_register_opp_notifier() - Helper function to get devfreq notified
 *				     for any changes in the OPP availability
 *				     changes
 * @dev:	The devfreq user device. (parent of devfreq)
 * @devfreq:	The devfreq object.
 */
int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq)
{
	return dev_pm_opp_register_notifier(dev, &devfreq->nb);
}
EXPORT_SYMBOL(devfreq_register_opp_notifier);

/**
 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq
 *				       notified for any changes in the OPP
 *				       availability changes anymore.
 * @dev:	The devfreq user device. (parent of devfreq)
 * @devfreq:	The devfreq object.
 *
 * At exit() callback of devfreq_dev_profile, this must be included if
 * devfreq_recommended_opp is used.
 */
int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq)
{
	return dev_pm_opp_unregister_notifier(dev, &devfreq->nb);
}
EXPORT_SYMBOL(devfreq_unregister_opp_notifier);

static void devm_devfreq_opp_release(struct device *dev, void *res)
{
	devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res);
}

/**
 * devm_devfreq_register_opp_notifier() - Resource-managed
 *					  devfreq_register_opp_notifier()
 * @dev:	The devfreq user device. (parent of devfreq)
 * @devfreq:	The devfreq object.
 */
int devm_devfreq_register_opp_notifier(struct device *dev,
				       struct devfreq *devfreq)
{
	struct devfreq **ptr;
	int ret;

	ptr = devres_alloc(devm_devfreq_opp_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	ret = devfreq_register_opp_notifier(dev, devfreq);
	if (ret) {
		devres_free(ptr);
		return ret;
	}

	*ptr = devfreq;
	devres_add(dev, ptr);

	return 0;
}
EXPORT_SYMBOL(devm_devfreq_register_opp_notifier);

/**
 * devm_devfreq_unregister_opp_notifier() - Resource-managed
 *					    devfreq_unregister_opp_notifier()
 * @dev:	The devfreq user device. (parent of devfreq)
 * @devfreq:	The devfreq object.
 */
void devm_devfreq_unregister_opp_notifier(struct device *dev,
					 struct devfreq *devfreq)
{
	WARN_ON(devres_release(dev, devm_devfreq_opp_release,
			       devm_devfreq_dev_match, devfreq));
}
EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier);

/**
 * devfreq_register_notifier() - Register a driver with devfreq
 * @devfreq:	The devfreq object.
 * @nb:		The notifier block to register.
 * @list:	DEVFREQ_TRANSITION_NOTIFIER.
 */
int devfreq_register_notifier(struct devfreq *devfreq,
			      struct notifier_block *nb,
			      unsigned int list)
{
	int ret = 0;

	if (!devfreq)
		return -EINVAL;

	switch (list) {
	case DEVFREQ_TRANSITION_NOTIFIER:
		ret = srcu_notifier_chain_register(
				&devfreq->transition_notifier_list, nb);
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}
EXPORT_SYMBOL(devfreq_register_notifier);

/*
 * devfreq_unregister_notifier() - Unregister a driver with devfreq
 * @devfreq:	The devfreq object.
 * @nb:		The notifier block to be unregistered.
 * @list:	DEVFREQ_TRANSITION_NOTIFIER.
 */
int devfreq_unregister_notifier(struct devfreq *devfreq,
				struct notifier_block *nb,
				unsigned int list)
{
	int ret = 0;

	if (!devfreq)
		return -EINVAL;

	switch (list) {
	case DEVFREQ_TRANSITION_NOTIFIER:
		ret = srcu_notifier_chain_unregister(
				&devfreq->transition_notifier_list, nb);
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}
EXPORT_SYMBOL(devfreq_unregister_notifier);

struct devfreq_notifier_devres {
	struct devfreq *devfreq;
	struct notifier_block *nb;
	unsigned int list;
};

static void devm_devfreq_notifier_release(struct device *dev, void *res)
{
	struct devfreq_notifier_devres *this = res;

	devfreq_unregister_notifier(this->devfreq, this->nb, this->list);
}

/**
 * devm_devfreq_register_notifier()
 *	- Resource-managed devfreq_register_notifier()
 * @dev:	The devfreq user device. (parent of devfreq)
 * @devfreq:	The devfreq object.
 * @nb:		The notifier block to be unregistered.
 * @list:	DEVFREQ_TRANSITION_NOTIFIER.
 */
int devm_devfreq_register_notifier(struct device *dev,
				struct devfreq *devfreq,
				struct notifier_block *nb,
				unsigned int list)
{
	struct devfreq_notifier_devres *ptr;
	int ret;

	ptr = devres_alloc(devm_devfreq_notifier_release, sizeof(*ptr),
				GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	ret = devfreq_register_notifier(devfreq, nb, list);
	if (ret) {
		devres_free(ptr);
		return ret;
	}

	ptr->devfreq = devfreq;
	ptr->nb = nb;
	ptr->list = list;
	devres_add(dev, ptr);

	return 0;
}
EXPORT_SYMBOL(devm_devfreq_register_notifier);

/**
 * devm_devfreq_unregister_notifier()
 *	- Resource-managed devfreq_unregister_notifier()
 * @dev:	The devfreq user device. (parent of devfreq)
 * @devfreq:	The devfreq object.
 * @nb:		The notifier block to be unregistered.
 * @list:	DEVFREQ_TRANSITION_NOTIFIER.
 */
void devm_devfreq_unregister_notifier(struct device *dev,
				      struct devfreq *devfreq,
				      struct notifier_block *nb,
				      unsigned int list)
{
	WARN_ON(devres_release(dev, devm_devfreq_notifier_release,
			       devm_devfreq_dev_match, devfreq));
}
EXPORT_SYMBOL(devm_devfreq_unregister_notifier);
