1/* 2 * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework 3 * for Non-CPU Devices. 4 * 5 * Copyright (C) 2011 Samsung Electronics 6 * MyungJoo Ham <myungjoo.ham@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13#ifndef __LINUX_DEVFREQ_H__ 14#define __LINUX_DEVFREQ_H__ 15 16#include <linux/device.h> 17#include <linux/notifier.h> 18#include <linux/pm_opp.h> 19 20#define DEVFREQ_NAME_LEN 16 21 22struct devfreq; 23 24/** 25 * struct devfreq_dev_status - Data given from devfreq user device to 26 * governors. Represents the performance 27 * statistics. 28 * @total_time: The total time represented by this instance of 29 * devfreq_dev_status 30 * @busy_time: The time that the device was working among the 31 * total_time. 32 * @current_frequency: The operating frequency. 33 * @private_data: An entry not specified by the devfreq framework. 34 * A device and a specific governor may have their 35 * own protocol with private_data. However, because 36 * this is governor-specific, a governor using this 37 * will be only compatible with devices aware of it. 38 */ 39struct devfreq_dev_status { 40 /* both since the last measure */ 41 unsigned long total_time; 42 unsigned long busy_time; 43 unsigned long current_frequency; 44 void *private_data; 45}; 46 47/* 48 * The resulting frequency should be at most this. (this bound is the 49 * least upper bound; thus, the resulting freq should be lower or same) 50 * If the flag is not set, the resulting frequency should be at most the 51 * bound (greatest lower bound) 52 */ 53#define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 54 55/** 56 * struct devfreq_dev_profile - Devfreq's user device profile 57 * @initial_freq: The operating frequency when devfreq_add_device() is 58 * called. 59 * @polling_ms: The polling interval in ms. 0 disables polling. 60 * @target: The device should set its operating frequency at 61 * freq or lowest-upper-than-freq value. If freq is 62 * higher than any operable frequency, set maximum. 63 * Before returning, target function should set 64 * freq at the current frequency. 65 * The "flags" parameter's possible values are 66 * explained above with "DEVFREQ_FLAG_*" macros. 67 * @get_dev_status: The device should provide the current performance 68 * status to devfreq, which is used by governors. 69 * @get_cur_freq: The device should provide the current frequency 70 * at which it is operating. 71 * @exit: An optional callback that is called when devfreq 72 * is removing the devfreq object due to error or 73 * from devfreq_remove_device() call. If the user 74 * has registered devfreq->nb at a notifier-head, 75 * this is the time to unregister it. 76 * @freq_table: Optional list of frequencies to support statistics. 77 * @max_state: The size of freq_table. 78 */ 79struct devfreq_dev_profile { 80 unsigned long initial_freq; 81 unsigned int polling_ms; 82 83 int (*target)(struct device *dev, unsigned long *freq, u32 flags); 84 int (*get_dev_status)(struct device *dev, 85 struct devfreq_dev_status *stat); 86 int (*get_cur_freq)(struct device *dev, unsigned long *freq); 87 void (*exit)(struct device *dev); 88 89 unsigned int *freq_table; 90 unsigned int max_state; 91}; 92 93/** 94 * struct devfreq_governor - Devfreq policy governor 95 * @node: list node - contains registered devfreq governors 96 * @name: Governor's name 97 * @get_target_freq: Returns desired operating frequency for the device. 98 * Basically, get_target_freq will run 99 * devfreq_dev_profile.get_dev_status() to get the 100 * status of the device (load = busy_time / total_time). 101 * If no_central_polling is set, this callback is called 102 * only with update_devfreq() notified by OPP. 103 * @event_handler: Callback for devfreq core framework to notify events 104 * to governors. Events include per device governor 105 * init and exit, opp changes out of devfreq, suspend 106 * and resume of per device devfreq during device idle. 107 * 108 * Note that the callbacks are called with devfreq->lock locked by devfreq. 109 */ 110struct devfreq_governor { 111 struct list_head node; 112 113 const char name[DEVFREQ_NAME_LEN]; 114 int (*get_target_freq)(struct devfreq *this, unsigned long *freq); 115 int (*event_handler)(struct devfreq *devfreq, 116 unsigned int event, void *data); 117}; 118 119/** 120 * struct devfreq - Device devfreq structure 121 * @node: list node - contains the devices with devfreq that have been 122 * registered. 123 * @lock: a mutex to protect accessing devfreq. 124 * @dev: device registered by devfreq class. dev.parent is the device 125 * using devfreq. 126 * @profile: device-specific devfreq profile 127 * @governor: method how to choose frequency based on the usage. 128 * @governor_name: devfreq governor name for use with this devfreq 129 * @nb: notifier block used to notify devfreq object that it should 130 * reevaluate operable frequencies. Devfreq users may use 131 * devfreq.nb to the corresponding register notifier call chain. 132 * @work: delayed work for load monitoring. 133 * @previous_freq: previously configured frequency value. 134 * @data: Private data of the governor. The devfreq framework does not 135 * touch this. 136 * @min_freq: Limit minimum frequency requested by user (0: none) 137 * @max_freq: Limit maximum frequency requested by user (0: none) 138 * @stop_polling: devfreq polling status of a device. 139 * @total_trans: Number of devfreq transitions 140 * @trans_table: Statistics of devfreq transitions 141 * @time_in_state: Statistics of devfreq states 142 * @last_stat_updated: The last time stat updated 143 * 144 * This structure stores the devfreq information for a give device. 145 * 146 * Note that when a governor accesses entries in struct devfreq in its 147 * functions except for the context of callbacks defined in struct 148 * devfreq_governor, the governor should protect its access with the 149 * struct mutex lock in struct devfreq. A governor may use this mutex 150 * to protect its own private data in void *data as well. 151 */ 152struct devfreq { 153 struct list_head node; 154 155 struct mutex lock; 156 struct device dev; 157 struct devfreq_dev_profile *profile; 158 const struct devfreq_governor *governor; 159 char governor_name[DEVFREQ_NAME_LEN]; 160 struct notifier_block nb; 161 struct delayed_work work; 162 163 unsigned long previous_freq; 164 165 void *data; /* private data for governors */ 166 167 unsigned long min_freq; 168 unsigned long max_freq; 169 bool stop_polling; 170 171 /* information for device frequency transition */ 172 unsigned int total_trans; 173 unsigned int *trans_table; 174 unsigned long *time_in_state; 175 unsigned long last_stat_updated; 176}; 177 178#if defined(CONFIG_PM_DEVFREQ) 179extern struct devfreq *devfreq_add_device(struct device *dev, 180 struct devfreq_dev_profile *profile, 181 const char *governor_name, 182 void *data); 183extern int devfreq_remove_device(struct devfreq *devfreq); 184extern struct devfreq *devm_devfreq_add_device(struct device *dev, 185 struct devfreq_dev_profile *profile, 186 const char *governor_name, 187 void *data); 188extern void devm_devfreq_remove_device(struct device *dev, 189 struct devfreq *devfreq); 190 191/* Supposed to be called by PM callbacks */ 192extern int devfreq_suspend_device(struct devfreq *devfreq); 193extern int devfreq_resume_device(struct devfreq *devfreq); 194 195/* Helper functions for devfreq user device driver with OPP. */ 196extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, 197 unsigned long *freq, u32 flags); 198extern int devfreq_register_opp_notifier(struct device *dev, 199 struct devfreq *devfreq); 200extern int devfreq_unregister_opp_notifier(struct device *dev, 201 struct devfreq *devfreq); 202extern int devm_devfreq_register_opp_notifier(struct device *dev, 203 struct devfreq *devfreq); 204extern void devm_devfreq_unregister_opp_notifier(struct device *dev, 205 struct devfreq *devfreq); 206 207#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) 208/** 209 * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq 210 * and devfreq_add_device 211 * @upthreshold: If the load is over this value, the frequency jumps. 212 * Specify 0 to use the default. Valid value = 0 to 100. 213 * @downdifferential: If the load is under upthreshold - downdifferential, 214 * the governor may consider slowing the frequency down. 215 * Specify 0 to use the default. Valid value = 0 to 100. 216 * downdifferential < upthreshold must hold. 217 * 218 * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor, 219 * the governor uses the default values. 220 */ 221struct devfreq_simple_ondemand_data { 222 unsigned int upthreshold; 223 unsigned int downdifferential; 224}; 225#endif 226 227#else /* !CONFIG_PM_DEVFREQ */ 228static inline struct devfreq *devfreq_add_device(struct device *dev, 229 struct devfreq_dev_profile *profile, 230 const char *governor_name, 231 void *data) 232{ 233 return ERR_PTR(-ENOSYS); 234} 235 236static inline int devfreq_remove_device(struct devfreq *devfreq) 237{ 238 return 0; 239} 240 241static inline struct devfreq *devm_devfreq_add_device(struct device *dev, 242 struct devfreq_dev_profile *profile, 243 const char *governor_name, 244 void *data) 245{ 246 return ERR_PTR(-ENOSYS); 247} 248 249static inline void devm_devfreq_remove_device(struct device *dev, 250 struct devfreq *devfreq) 251{ 252} 253 254static inline int devfreq_suspend_device(struct devfreq *devfreq) 255{ 256 return 0; 257} 258 259static inline int devfreq_resume_device(struct devfreq *devfreq) 260{ 261 return 0; 262} 263 264static inline struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, 265 unsigned long *freq, u32 flags) 266{ 267 return ERR_PTR(-EINVAL); 268} 269 270static inline int devfreq_register_opp_notifier(struct device *dev, 271 struct devfreq *devfreq) 272{ 273 return -EINVAL; 274} 275 276static inline int devfreq_unregister_opp_notifier(struct device *dev, 277 struct devfreq *devfreq) 278{ 279 return -EINVAL; 280} 281 282static inline int devm_devfreq_register_opp_notifier(struct device *dev, 283 struct devfreq *devfreq) 284{ 285 return -EINVAL; 286} 287 288static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, 289 struct devfreq *devfreq) 290{ 291} 292#endif /* CONFIG_PM_DEVFREQ */ 293 294#endif /* __LINUX_DEVFREQ_H__ */ 295