devfreq.h 13.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * 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>
18
#include <linux/pm_opp.h>
19 20 21

#define DEVFREQ_NAME_LEN 16

22 23 24 25 26 27 28
/* DEVFREQ notifier interface */
#define DEVFREQ_TRANSITION_NOTIFIER	(0)

/* Transition notifiers of DEVFREQ_TRANSITION_NOTIFIER */
#define	DEVFREQ_PRECHANGE		(0)
#define DEVFREQ_POSTCHANGE		(1)

29 30 31 32 33 34
struct devfreq;

/**
 * struct devfreq_dev_status - Data given from devfreq user device to
 *			     governors. Represents the performance
 *			     statistics.
35
 * @total_time:		The total time represented by this instance of
36
 *			devfreq_dev_status
37
 * @busy_time:		The time that the device was working among the
38
 *			total_time.
39 40
 * @current_frequency:	The operating frequency.
 * @private_data:	An entry not specified by the devfreq framework.
41 42 43 44 45 46 47 48 49 50
 *			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 已提交
51
	void *private_data;
52 53
};

54 55 56 57 58 59 60 61
/*
 * 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

62 63
/**
 * struct devfreq_dev_profile - Devfreq's user device profile
64
 * @initial_freq:	The operating frequency when devfreq_add_device() is
65
 *			called.
66 67
 * @polling_ms:		The polling interval in ms. 0 disables polling.
 * @target:		The device should set its operating frequency at
68 69 70 71
 *			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.
72 73
 *			The "flags" parameter's possible values are
 *			explained above with "DEVFREQ_FLAG_*" macros.
74
 * @get_dev_status:	The device should provide the current performance
75 76 77 78
 *			status to devfreq. Governors are recommended not to
 *			use this directly. Instead, governors are recommended
 *			to use devfreq_update_stats() along with
 *			devfreq.last_status.
79
 * @get_cur_freq:	The device should provide the current frequency
80
 *			at which it is operating.
81
 * @exit:		An optional callback that is called when devfreq
82 83 84 85
 *			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.
86 87
 * @freq_table:	Optional list of frequencies to support statistics.
 * @max_state:	The size of freq_table.
88 89 90 91 92
 */
struct devfreq_dev_profile {
	unsigned long initial_freq;
	unsigned int polling_ms;

93
	int (*target)(struct device *dev, unsigned long *freq, u32 flags);
94 95
	int (*get_dev_status)(struct device *dev,
			      struct devfreq_dev_status *stat);
96
	int (*get_cur_freq)(struct device *dev, unsigned long *freq);
97
	void (*exit)(struct device *dev);
98

99
	unsigned long *freq_table;
100
	unsigned int max_state;
101 102 103 104
};

/**
 * struct devfreq_governor - Devfreq policy governor
105
 * @node:		list node - contains registered devfreq governors
106
 * @name:		Governor's name
107 108
 * @immutable:		Immutable flag for governor. If the value is 1,
 *			this govenror is never changeable to other governor.
109
 * @get_target_freq:	Returns desired operating frequency for the device.
110 111 112 113 114
 *			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.
115
 * @event_handler:      Callback for devfreq core framework to notify events
116 117 118
 *                      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.
119 120 121 122
 *
 * Note that the callbacks are called with devfreq->lock locked by devfreq.
 */
struct devfreq_governor {
123 124
	struct list_head node;

125
	const char name[DEVFREQ_NAME_LEN];
126
	const unsigned int immutable;
127
	int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
128 129
	int (*event_handler)(struct devfreq *devfreq,
				unsigned int event, void *data);
130 131 132 133
};

/**
 * struct devfreq - Device devfreq structure
134
 * @node:	list node - contains the devices with devfreq that have been
135
 *		registered.
136 137
 * @lock:	a mutex to protect accessing devfreq.
 * @dev:	device registered by devfreq class. dev.parent is the device
138
 *		using devfreq.
139 140
 * @profile:	device-specific devfreq profile
 * @governor:	method how to choose frequency based on the usage.
141
 * @governor_name:	devfreq governor name for use with this devfreq
142
 * @nb:		notifier block used to notify devfreq object that it should
143 144
 *		reevaluate operable frequencies. Devfreq users may use
 *		devfreq.nb to the corresponding register notifier call chain.
145 146 147
 * @work:	delayed work for load monitoring.
 * @previous_freq:	previously configured frequency value.
 * @data:	Private data of the governor. The devfreq framework does not
148
 *		touch this.
149 150 151
 * @min_freq:	Limit minimum frequency requested by user (0: none)
 * @max_freq:	Limit maximum frequency requested by user (0: none)
 * @stop_polling:	 devfreq polling status of a device.
152 153 154 155
 * @total_trans:	Number of devfreq transitions
 * @trans_table:	Statistics of devfreq transitions
 * @time_in_state:	Statistics of devfreq states
 * @last_stat_updated:	The last time stat updated
156
 * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
 *
 * 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;
173
	char governor_name[DEVFREQ_NAME_LEN];
174
	struct notifier_block nb;
175
	struct delayed_work work;
176 177

	unsigned long previous_freq;
178
	struct devfreq_dev_status last_status;
179 180 181

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

182 183
	unsigned long min_freq;
	unsigned long max_freq;
184
	bool stop_polling;
185

186
	/* information for device frequency transition */
187 188 189 190
	unsigned int total_trans;
	unsigned int *trans_table;
	unsigned long *time_in_state;
	unsigned long last_stat_updated;
191 192 193 194 195 196 197

	struct srcu_notifier_head transition_notifier_list;
};

struct devfreq_freqs {
	unsigned long old;
	unsigned long new;
198 199 200 201 202
};

#if defined(CONFIG_PM_DEVFREQ)
extern struct devfreq *devfreq_add_device(struct device *dev,
				  struct devfreq_dev_profile *profile,
203
				  const char *governor_name,
204 205
				  void *data);
extern int devfreq_remove_device(struct devfreq *devfreq);
206 207 208 209 210 211
extern struct devfreq *devm_devfreq_add_device(struct device *dev,
				  struct devfreq_dev_profile *profile,
				  const char *governor_name,
				  void *data);
extern void devm_devfreq_remove_device(struct device *dev,
				  struct devfreq *devfreq);
212

213
/* Supposed to be called by PM callbacks */
214 215
extern int devfreq_suspend_device(struct devfreq *devfreq);
extern int devfreq_resume_device(struct devfreq *devfreq);
216 217

/* Helper functions for devfreq user device driver with OPP. */
218
extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
219
					   unsigned long *freq, u32 flags);
220 221 222 223
extern int devfreq_register_opp_notifier(struct device *dev,
					 struct devfreq *devfreq);
extern int devfreq_unregister_opp_notifier(struct device *dev,
					   struct devfreq *devfreq);
224 225 226 227
extern int devm_devfreq_register_opp_notifier(struct device *dev,
					      struct devfreq *devfreq);
extern void devm_devfreq_unregister_opp_notifier(struct device *dev,
						struct devfreq *devfreq);
228 229 230 231 232 233 234 235 236 237 238 239 240 241
extern int devfreq_register_notifier(struct devfreq *devfreq,
					struct notifier_block *nb,
					unsigned int list);
extern int devfreq_unregister_notifier(struct devfreq *devfreq,
					struct notifier_block *nb,
					unsigned int list);
extern int devm_devfreq_register_notifier(struct device *dev,
				struct devfreq *devfreq,
				struct notifier_block *nb,
				unsigned int list);
extern void devm_devfreq_unregister_notifier(struct device *dev,
				struct devfreq *devfreq,
				struct notifier_block *nb,
				unsigned int list);
242 243 244
extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
						int index);

245 246 247
/**
 * devfreq_update_stats() - update the last_status pointer in struct devfreq
 * @df:		the devfreq instance whose status needs updating
248 249 250 251
 *
 *  Governors are recommended to use this function along with last_status,
 * which allows other entities to reuse the last_status without affecting
 * the values fetched later by governors.
252 253 254 255 256 257
 */
static inline int devfreq_update_stats(struct devfreq *df)
{
	return df->profile->get_dev_status(df->dev.parent, &df->last_status);
}

258
#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
M
MyungJoo Ham 已提交
259 260 261
/**
 * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
 *	and devfreq_add_device
262
 * @upthreshold:	If the load is over this value, the frequency jumps.
M
MyungJoo Ham 已提交
263
 *			Specify 0 to use the default. Valid value = 0 to 100.
264
 * @downdifferential:	If the load is under upthreshold - downdifferential,
M
MyungJoo Ham 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277
 *			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

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
/**
 * struct devfreq_passive_data - void *data fed to struct devfreq
 *	and devfreq_add_device
 * @parent:	the devfreq instance of parent device.
 * @get_target_freq:	Optional callback, Returns desired operating frequency
 *			for the device using passive governor. That is called
 *			when passive governor should decide the next frequency
 *			by using the new frequency of parent devfreq device
 *			using governors except for passive governor.
 *			If the devfreq device has the specific method to decide
 *			the next frequency, should use this callback.
 * @this:	the devfreq instance of own device.
 * @nb:		the notifier block for DEVFREQ_TRANSITION_NOTIFIER list
 *
 * The devfreq_passive_data have to set the devfreq instance of parent
 * device with governors except for the passive governor. But, don't need to
 * initialize the 'this' and 'nb' field because the devfreq core will handle
 * them.
 */
struct devfreq_passive_data {
	/* Should set the devfreq instance of parent device */
	struct devfreq *parent;

	/* Optional callback to decide the next frequency of passvice device */
	int (*get_target_freq)(struct devfreq *this, unsigned long *freq);

	/* For passive governor's internal use. Don't need to set them */
	struct devfreq *this;
	struct notifier_block nb;
};
#endif

311
#else /* !CONFIG_PM_DEVFREQ */
312
static inline struct devfreq *devfreq_add_device(struct device *dev,
313
					  struct devfreq_dev_profile *profile,
314
					  const char *governor_name,
315
					  void *data)
316
{
317
	return ERR_PTR(-ENOSYS);
318 319
}

320
static inline int devfreq_remove_device(struct devfreq *devfreq)
321 322 323 324
{
	return 0;
}

325 326 327 328 329 330 331 332 333 334 335 336 337
static inline struct devfreq *devm_devfreq_add_device(struct device *dev,
					struct devfreq_dev_profile *profile,
					const char *governor_name,
					void *data)
{
	return ERR_PTR(-ENOSYS);
}

static inline void devm_devfreq_remove_device(struct device *dev,
					struct devfreq *devfreq)
{
}

338
static inline int devfreq_suspend_device(struct devfreq *devfreq)
339 340 341 342
{
	return 0;
}

343
static inline int devfreq_resume_device(struct devfreq *devfreq)
344 345 346 347
{
	return 0;
}

348
static inline struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
349
					   unsigned long *freq, u32 flags)
350
{
351
	return ERR_PTR(-EINVAL);
352 353
}

354
static inline int devfreq_register_opp_notifier(struct device *dev,
355 356 357 358 359
					 struct devfreq *devfreq)
{
	return -EINVAL;
}

360
static inline int devfreq_unregister_opp_notifier(struct device *dev,
361 362 363 364 365
					   struct devfreq *devfreq)
{
	return -EINVAL;
}

366 367 368 369 370 371 372 373 374 375
static inline int devm_devfreq_register_opp_notifier(struct device *dev,
						     struct devfreq *devfreq)
{
	return -EINVAL;
}

static inline void devm_devfreq_unregister_opp_notifier(struct device *dev,
							struct devfreq *devfreq)
{
}
376

377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
static inline int devfreq_register_notifier(struct devfreq *devfreq,
					struct notifier_block *nb,
					unsigned int list)
{
	return 0;
}

static inline int devfreq_unregister_notifier(struct devfreq *devfreq,
					struct notifier_block *nb,
					unsigned int list)
{
	return 0;
}

static inline int devm_devfreq_register_notifier(struct device *dev,
				struct devfreq *devfreq,
				struct notifier_block *nb,
				unsigned int list)
{
	return 0;
}

static inline void devm_devfreq_unregister_notifier(struct device *dev,
				struct devfreq *devfreq,
				struct notifier_block *nb,
				unsigned int list)
{
}

406 407 408 409 410 411
static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
							int index)
{
	return ERR_PTR(-ENODEV);
}

412 413 414 415
static inline int devfreq_update_stats(struct devfreq *df)
{
	return -EINVAL;
}
416 417 418
#endif /* CONFIG_PM_DEVFREQ */

#endif /* __LINUX_DEVFREQ_H__ */