devfreq.h 8.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/*
 * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework
 *	    for Non-CPU Devices.
 *
 * Copyright (C) 2011 Samsung Electronics
 *	MyungJoo Ham <myungjoo.ham@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef __LINUX_DEVFREQ_H__
#define __LINUX_DEVFREQ_H__

#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/opp.h>

#define DEVFREQ_NAME_LEN 16

struct devfreq;

/**
 * struct devfreq_dev_status - Data given from devfreq user device to
 *			     governors. Represents the performance
 *			     statistics.
 * @total_time		The total time represented by this instance of
 *			devfreq_dev_status
 * @busy_time		The time that the device was working among the
 *			total_time.
 * @current_frequency	The operating frequency.
 * @private_data	An entry not specified by the devfreq framework.
 *			A device and a specific governor may have their
 *			own protocol with private_data. However, because
 *			this is governor-specific, a governor using this
 *			will be only compatible with devices aware of it.
 */
struct devfreq_dev_status {
	/* both since the last measure */
	unsigned long total_time;
	unsigned long busy_time;
	unsigned long current_frequency;
J
Jonathan Corbet 已提交
44
	void *private_data;
45 46
};

47 48 49 50 51 52 53 54
/*
 * The resulting frequency should be at most this. (this bound is the
 * least upper bound; thus, the resulting freq should be lower or same)
 * If the flag is not set, the resulting frequency should be at most the
 * bound (greatest lower bound)
 */
#define DEVFREQ_FLAG_LEAST_UPPER_BOUND		0x1

55 56 57 58 59 60 61 62 63 64
/**
 * struct devfreq_dev_profile - Devfreq's user device profile
 * @initial_freq	The operating frequency when devfreq_add_device() is
 *			called.
 * @polling_ms		The polling interval in ms. 0 disables polling.
 * @target		The device should set its operating frequency at
 *			freq or lowest-upper-than-freq value. If freq is
 *			higher than any operable frequency, set maximum.
 *			Before returning, target function should set
 *			freq at the current frequency.
65 66
 *			The "flags" parameter's possible values are
 *			explained above with "DEVFREQ_FLAG_*" macros.
67 68
 * @get_dev_status	The device should provide the current performance
 *			status to devfreq, which is used by governors.
69 70
 * @get_cur_freq	The device should provide the current frequency
 *			at which it is operating.
71 72 73 74 75 76 77 78 79 80
 * @exit		An optional callback that is called when devfreq
 *			is removing the devfreq object due to error or
 *			from devfreq_remove_device() call. If the user
 *			has registered devfreq->nb at a notifier-head,
 *			this is the time to unregister it.
 */
struct devfreq_dev_profile {
	unsigned long initial_freq;
	unsigned int polling_ms;

81
	int (*target)(struct device *dev, unsigned long *freq, u32 flags);
82 83
	int (*get_dev_status)(struct device *dev,
			      struct devfreq_dev_status *stat);
84
	int (*get_cur_freq)(struct device *dev, unsigned long *freq);
85 86 87 88 89 90 91 92 93 94 95 96
	void (*exit)(struct device *dev);
};

/**
 * struct devfreq_governor - Devfreq policy governor
 * @name		Governor's name
 * @get_target_freq	Returns desired operating frequency for the device.
 *			Basically, get_target_freq will run
 *			devfreq_dev_profile.get_dev_status() to get the
 *			status of the device (load = busy_time / total_time).
 *			If no_central_polling is set, this callback is called
 *			only with update_devfreq() notified by OPP.
97 98 99 100
 * @event_handler       Callback for devfreq core framework to notify events
 *                      to governors. Events include per device governor
 *                      init and exit, opp changes out of devfreq, suspend
 *                      and resume of per device devfreq during device idle.
101 102 103 104 105 106
 *
 * Note that the callbacks are called with devfreq->lock locked by devfreq.
 */
struct devfreq_governor {
	const char name[DEVFREQ_NAME_LEN];
	int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
107 108
	int (*event_handler)(struct devfreq *devfreq,
				unsigned int event, void *data);
109 110 111 112 113 114 115 116 117 118 119 120 121 122
};

/**
 * struct devfreq - Device devfreq structure
 * @node	list node - contains the devices with devfreq that have been
 *		registered.
 * @lock	a mutex to protect accessing devfreq.
 * @dev		device registered by devfreq class. dev.parent is the device
 *		using devfreq.
 * @profile	device-specific devfreq profile
 * @governor	method how to choose frequency based on the usage.
 * @nb		notifier block used to notify devfreq object that it should
 *		reevaluate operable frequencies. Devfreq users may use
 *		devfreq.nb to the corresponding register notifier call chain.
123
 * @work	delayed work for load monitoring.
124 125 126
 * @previous_freq	previously configured frequency value.
 * @data	Private data of the governor. The devfreq framework does not
 *		touch this.
127 128
 * @min_freq	Limit minimum frequency requested by user (0: none)
 * @max_freq	Limit maximum frequency requested by user (0: none)
129
 * @stop_polling	 devfreq polling status of a device.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
 *
 * This structure stores the devfreq information for a give device.
 *
 * Note that when a governor accesses entries in struct devfreq in its
 * functions except for the context of callbacks defined in struct
 * devfreq_governor, the governor should protect its access with the
 * struct mutex lock in struct devfreq. A governor may use this mutex
 * to protect its own private data in void *data as well.
 */
struct devfreq {
	struct list_head node;

	struct mutex lock;
	struct device dev;
	struct devfreq_dev_profile *profile;
	const struct devfreq_governor *governor;
	struct notifier_block nb;
147
	struct delayed_work work;
148 149 150 151 152

	unsigned long previous_freq;

	void *data; /* private data for governors */

153 154
	unsigned long min_freq;
	unsigned long max_freq;
155
	bool stop_polling;
156 157 158 159 160 161 162 163
};

#if defined(CONFIG_PM_DEVFREQ)
extern struct devfreq *devfreq_add_device(struct device *dev,
				  struct devfreq_dev_profile *profile,
				  const struct devfreq_governor *governor,
				  void *data);
extern int devfreq_remove_device(struct devfreq *devfreq);
164 165
extern int devfreq_suspend_device(struct devfreq *devfreq);
extern int devfreq_resume_device(struct devfreq *devfreq);
166 167 168

/* Helper functions for devfreq user device driver with OPP. */
extern struct opp *devfreq_recommended_opp(struct device *dev,
169
					   unsigned long *freq, u32 flags);
170 171 172 173 174
extern int devfreq_register_opp_notifier(struct device *dev,
					 struct devfreq *devfreq);
extern int devfreq_unregister_opp_notifier(struct device *dev,
					   struct devfreq *devfreq);

M
MyungJoo Ham 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE
extern const struct devfreq_governor devfreq_powersave;
#endif
#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE
extern const struct devfreq_governor devfreq_performance;
#endif
#ifdef CONFIG_DEVFREQ_GOV_USERSPACE
extern const struct devfreq_governor devfreq_userspace;
#endif
#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND
extern const struct devfreq_governor devfreq_simple_ondemand;
/**
 * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
 *	and devfreq_add_device
 * @ upthreshold	If the load is over this value, the frequency jumps.
 *			Specify 0 to use the default. Valid value = 0 to 100.
 * @ downdifferential	If the load is under upthreshold - downdifferential,
 *			the governor may consider slowing the frequency down.
 *			Specify 0 to use the default. Valid value = 0 to 100.
 *			downdifferential < upthreshold must hold.
 *
 * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor,
 * the governor uses the default values.
 */
struct devfreq_simple_ondemand_data {
	unsigned int upthreshold;
	unsigned int downdifferential;
};
#endif

205 206 207 208
#else /* !CONFIG_PM_DEVFREQ */
static struct devfreq *devfreq_add_device(struct device *dev,
					  struct devfreq_dev_profile *profile,
					  struct devfreq_governor *governor,
209
					  void *data)
210 211 212 213
{
	return NULL;
}

214
static int devfreq_remove_device(struct devfreq *devfreq)
215 216 217 218
{
	return 0;
}

219 220 221 222 223 224 225 226 227 228
static int devfreq_suspend_device(struct devfreq *devfreq)
{
	return 0;
}

static int devfreq_resume_device(struct devfreq *devfreq)
{
	return 0;
}

229
static struct opp *devfreq_recommended_opp(struct device *dev,
230
					   unsigned long *freq, u32 flags)
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
{
	return -EINVAL;
}

static int devfreq_register_opp_notifier(struct device *dev,
					 struct devfreq *devfreq)
{
	return -EINVAL;
}

static int devfreq_unregister_opp_notifier(struct device *dev,
					   struct devfreq *devfreq)
{
	return -EINVAL;
}

M
MyungJoo Ham 已提交
247 248 249 250 251
#define devfreq_powersave	NULL
#define devfreq_performance	NULL
#define devfreq_userspace	NULL
#define devfreq_simple_ondemand	NULL

252 253 254
#endif /* CONFIG_PM_DEVFREQ */

#endif /* __LINUX_DEVFREQ_H__ */