Device Frequency Scaling¶
Introduction¶
This framework provides a standard kernel interface for Dynamic Voltage andFrequency Switching on arbitrary devices.
It exposes controls for adjusting frequency through sysfs files which aresimilar to the cpufreq subsystem.
Devices for which current usage can be measured can have their frequencyautomatically adjusted by governors.
API¶
Device drivers need to initialize adevfreq_profile and call thedevfreq_add_device() function to create adevfreq instance.
- structdevfreq_dev_status¶
Data given from devfreq user device to governors. Represents the performance statistics.
Definition:
struct devfreq_dev_status { unsigned long total_time; unsigned long busy_time; unsigned long current_frequency; void *private_data;};Members
total_timeThe total time represented by this instance ofdevfreq_dev_status
busy_timeThe time that the device was working among thetotal_time.
current_frequencyThe operating frequency.
private_dataAn entry not specified by the devfreq framework.A device and a specific governor may have theirown protocol with private_data. However, becausethis is governor-specific, a governor using thiswill be only compatible with devices aware of it.
- structdevfreq_dev_profile¶
Devfreq’s user device profile
Definition:
struct devfreq_dev_profile { unsigned long initial_freq; unsigned int polling_ms; enum devfreq_timer timer; int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); unsigned long *freq_table; unsigned int max_state; bool is_cooling_device; const struct attribute_group **dev_groups;};Members
initial_freqThe operating frequency when
devfreq_add_device()iscalled.polling_msThe polling interval in ms. 0 disables polling.
timerTimer type is either deferrable or delayed timer.
targetThe device should set its operating frequency atfreq or lowest-upper-than-freq value. If freq ishigher than any operable frequency, set maximum.Before returning, target function should setfreq at the current frequency.The “flags” parameter’s possible values areexplained above with “DEVFREQ_FLAG_*” macros.
get_dev_statusThe device should provide the current performancestatus to devfreq. Governors are recommended not touse this directly. Instead, governors are recommendedto use
devfreq_update_stats()along withdevfreq.last_status.get_cur_freqThe device should provide the current frequencyat which it is operating.
exitAn optional callback that is called when devfreqis removing the devfreq object due to error orfrom
devfreq_remove_device()call. If the userhas registered devfreq->nb at a notifier-head,this is the time to unregister it.freq_tableOptional list of frequencies to support statisticsand freq_table must be generated in ascending order.
max_stateThe size of freq_table.
is_cooling_deviceA self-explanatory boolean giving the device acooling effect property.
dev_groupsOptional device-specific sysfs attribute groups that tobe attached to the devfreq device.
- structdevfreq_stats¶
Statistics of devfreq device behavior
Definition:
struct devfreq_stats { unsigned int total_trans; unsigned int *trans_table; u64 *time_in_state; u64 last_update;};Members
total_transNumber of devfreq transitions.
trans_tableStatistics of devfreq transitions.
time_in_stateStatistics of devfreq states.
last_updateThe last time stats were updated.
- structdevfreq¶
Device devfreq structure
Definition:
struct devfreq { struct list_head node; struct mutex lock; struct device dev; struct devfreq_dev_profile *profile; const struct devfreq_governor *governor; struct opp_table *opp_table; struct notifier_block nb; struct delayed_work work; unsigned long *freq_table; unsigned int max_state; unsigned long previous_freq; struct devfreq_dev_status last_status; void *data; void *governor_data; struct dev_pm_qos_request user_min_freq_req; struct dev_pm_qos_request user_max_freq_req; unsigned long scaling_min_freq; unsigned long scaling_max_freq; bool stop_polling; unsigned long suspend_freq; unsigned long resume_freq; atomic_t suspend_count; struct devfreq_stats stats; struct srcu_notifier_head transition_notifier_list; struct thermal_cooling_device *cdev; struct notifier_block nb_min; struct notifier_block nb_max;};Members
nodelist node - contains the devices with devfreq that have beenregistered.
locka mutex to protect accessing devfreq.
devdevice registered by devfreq class. dev.parent is the deviceusing devfreq.
profiledevice-specific devfreq profile
governormethod how to choose frequency based on the usage.
opp_tableReference to OPP table of dev.parent, if one exists.
nbnotifier block used to notify devfreq object that it shouldreevaluate operable frequencies. Devfreq users may usedevfreq.nb to the corresponding register notifier call chain.
workdelayed work for load monitoring.
freq_tablecurrent frequency table used by the devfreq driver.
max_statecount of entry present in the frequency table.
previous_freqpreviously configured frequency value.
last_statusdevfreq user device info, performance statistics
datadevfreq driver pass to governors, governor should not change it.
governor_dataprivate data for governors, devfreq core doesn’t touch it.
user_min_freq_reqPM QoS minimum frequency request from user (via sysfs)
user_max_freq_reqPM QoS maximum frequency request from user (via sysfs)
scaling_min_freqLimit minimum frequency requested by OPP interface
scaling_max_freqLimit maximum frequency requested by OPP interface
stop_pollingdevfreq polling status of a device.
suspend_freqfrequency of a device set during suspend phase.
resume_freqfrequency of a device set in resume phase.
suspend_countsuspend requests counter for a device.
statsStatistics of devfreq device behavior
transition_notifier_listlist head of DEVFREQ_TRANSITION_NOTIFIER notifier
cdevCooling device pointer if the devfreq has cooling property
nb_minNotifier block for DEV_PM_QOS_MIN_FREQUENCY
nb_maxNotifier block for DEV_PM_QOS_MAX_FREQUENCY
Description
This structure stores the devfreq information for a given device.
Note that when a governor accesses entries instructdevfreq in itsfunctions except for the context of callbacks defined instructdevfreq_governor, the governor should protect its access with thestructmutex lock instructdevfreq. A governor may use this mutexto protect its own private data invoid*data as well.
- structdevfreq_simple_ondemand_data¶
void*datafed tostructdevfreqand devfreq_add_device
Definition:
struct devfreq_simple_ondemand_data { unsigned int upthreshold; unsigned int downdifferential;};Members
upthresholdIf the load is over this value, the frequency jumps.Specify 0 to use the default. Valid value = 0 to 100.
downdifferentialIf 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.
Description
If the fed devfreq_simple_ondemand_data pointer is NULL to the governor,the governor uses the default values.
- structdevfreq_passive_data¶
void*datafed tostructdevfreqand devfreq_add_device
Definition:
struct devfreq_passive_data { struct devfreq *parent; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); enum devfreq_parent_dev_type parent_type; struct devfreq *this; struct notifier_block nb; struct list_head cpu_data_list;};Members
parentthe devfreq instance of parent device.
get_target_freqOptional callback, Returns desired operating frequencyfor the device using passive governor. That is calledwhen passive governor should decide the next frequencyby using the new frequency of parent devfreq deviceusing governors except for passive governor.If the devfreq device has the specific method to decidethe next frequency, should use this callback.
parent_typethe parent type of the device.
thisthe devfreq instance of own device.
nbthe notifier block for DEVFREQ_TRANSITION_NOTIFIER orCPUFREQ_TRANSITION_NOTIFIER list.
cpu_data_listthe list of cpu frequency data for all cpufreq_policy.
Description
The devfreq_passive_data have to set the devfreq instance of parentdevice with governors except for the passive governor. But, don’t need toinitialize the ‘this’ and ‘nb’ field because the devfreq core will handlethem.
- structdevfreq_event_dev¶
the devfreq-event device
Definition:
struct devfreq_event_dev { struct list_head node; struct device dev; struct mutex lock; u32 enable_count; const struct devfreq_event_desc *desc;};Members
nodeContain the devfreq-event device that have been registered.
devthe device registered by devfreq-event class. dev.parent isthe device using devfreq-event.
locka mutex to protect accessing devfreq-event.
enable_countthe number of enable function have been called.
descthe description for devfreq-event device.
Description
This structure contains devfreq-event device information.
- structdevfreq_event_data¶
the devfreq-event data
Definition:
struct devfreq_event_data { unsigned long load_count; unsigned long total_count;};Members
load_countload count of devfreq-event device for the given period.
total_counttotal count of devfreq-event device for the given period.each count may represent a clock cycle, a time unit(ns/us/...), or anything the device driver wants.Generally, utilization is load_count / total_count.
Description
This structure contains the data of devfreq-event device for polling period.
- structdevfreq_event_ops¶
the operations of devfreq-event device
Definition:
struct devfreq_event_ops { int (*enable)(struct devfreq_event_dev *edev); int (*disable)(struct devfreq_event_dev *edev); int (*reset)(struct devfreq_event_dev *edev); int (*set_event)(struct devfreq_event_dev *edev); int (*get_event)(struct devfreq_event_dev *edev, struct devfreq_event_data *edata);};Members
enableEnable the devfreq-event device.
disableDisable the devfreq-event device.
resetReset all setting of the devfreq-event device.
set_eventSet the specific event type for the devfreq-event device.
get_eventGet the result of the devfreq-event devie with specificevent type.
Description
This structure contains devfreq-event device operations which can beimplemented by devfreq-event device drivers.
- structdevfreq_event_desc¶
the descriptor of devfreq-event device
Definition:
struct devfreq_event_desc { const char *name; u32 event_type; void *driver_data; const struct devfreq_event_ops *ops;};Members
namethe name of devfreq-event device.
event_typethe type of the event determined and used by driver
driver_datathe private data for devfreq-event driver.
opsthe operation to control devfreq-event device.
Description
Each devfreq-event device is described with a this structure.This structure contains the various data for devfreq-event device.The event_type describes what is going to be counted in the register.It might choose to count e.g. read requests, write data in bytes, etc.The full supported list of types is present in specyfic header in:include/dt-bindings/pmu/.
- voiddevfreq_get_freq_range(structdevfreq*devfreq,unsignedlong*min_freq,unsignedlong*max_freq)¶
Get the current freq range
Parameters
structdevfreq*devfreqthe devfreq instance
unsignedlong*min_freqthe min frequency
unsignedlong*max_freqthe max frequency
Description
This takes into consideration all constraints.
- intdevfreq_update_status(structdevfreq*devfreq,unsignedlongfreq)¶
Update statistics of devfreq behavior
Parameters
structdevfreq*devfreqthe devfreq instance
unsignedlongfreqthe update target frequency
- intdevfreq_update_target(structdevfreq*devfreq,unsignedlongfreq)¶
Reevaluate the device and configure frequency on the final stage.
Parameters
structdevfreq*devfreqthe devfreq instance.
unsignedlongfreqthe new frequency of parent device. This argumentis 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.
Parameters
structdevfreq*devfreqthe devfreq instance.
Note
- Lock devfreq->lock before calling update_devfreq
This function is exported for governors.
Parameters
structdevfreq*devfreqthe devfreq instance.
Description
Helper function for starting devfreq device load monitoring. By default,deferrable timer is used for load monitoring. But the users can change thisbehavior using the “timer” type in devfreq_dev_profile. This function will becalled by devfreq governor in response to the DEVFREQ_GOV_START eventgenerated while adding a device to the devfreq framework.
Parameters
structdevfreq*devfreqthe devfreq instance.
Description
Helper function to stop devfreq device load monitoring. Functionto be called from governor in response to DEVFREQ_GOV_STOPevent when device is removed from devfreq framework.
Parameters
structdevfreq*devfreqthe devfreq instance.
Description
Helper function to suspend devfreq device load monitoring. Functionto be called from governor in response to DEVFREQ_GOV_SUSPENDevent or when polling interval is set to zero.
Note
Though this function is same asdevfreq_monitor_stop(),intentionally kept separate to provide hooks for collectingtransition statistics.
Parameters
structdevfreq*devfreqthe devfreq instance.
Description
Helper function to resume devfreq device load monitoring. Functionto be called from governor in response to DEVFREQ_GOV_RESUMEevent or when polling interval is set to non-zero.
- voiddevfreq_update_interval(structdevfreq*devfreq,unsignedint*delay)¶
Update device devfreq monitoring interval
Parameters
structdevfreq*devfreqthe devfreq instance.
unsignedint*delaynew polling interval to be set.
Description
Helper function to set new load monitoring polling interval. Functionto be called from governor in response to DEVFREQ_GOV_UPDATE_INTERVAL event.
- structdevfreq*devfreq_add_device(structdevice*dev,structdevfreq_dev_profile*profile,constchar*governor_name,void*data)¶
Add devfreq feature to the device
Parameters
structdevice*devthe device to add devfreq feature.
structdevfreq_dev_profile*profiledevice-specific profile to run devfreq.
constchar*governor_namename of the policy to choose frequency.
void*datadevfreq driver pass to governors, governor should not change it.
Parameters
structdevfreq*devfreqthe devfreq instance to be removed
Description
The opposite ofdevfreq_add_device().
- structdevfreq*devm_devfreq_add_device(structdevice*dev,structdevfreq_dev_profile*profile,constchar*governor_name,void*data)¶
Resource-managed
devfreq_add_device()
Parameters
structdevice*devthe device to add devfreq feature.
structdevfreq_dev_profile*profiledevice-specific profile to run devfreq.
constchar*governor_namename of the policy to choose frequency.
void*datadevfreq driver pass to governors, governor should not change it.
Description
This function manages automatically the memory of devfreq device using deviceresource management and simplify the free operation for memory of devfreqdevice.
- voiddevm_devfreq_remove_device(structdevice*dev,structdevfreq*devfreq)¶
Resource-managed
devfreq_remove_device()
Parameters
structdevice*devthe device from which to remove devfreq feature.
structdevfreq*devfreqthe devfreq instance to be removed
Parameters
structdevfreq*devfreqthe devfreq instance to be suspended
Description
This function is intended to be called by the pm callbacks(e.g., runtime_suspend, suspend) of the device driver thatholds the devfreq.
Parameters
structdevfreq*devfreqthe devfreq instance to be resumed
Description
This function is intended to be called by the pm callbacks(e.g., runtime_resume, resume) of the device driver thatholds the devfreq.
- intdevfreq_add_governor(structdevfreq_governor*governor)¶
Add devfreq governor
Parameters
structdevfreq_governor*governorthe devfreq governor to be added
Parameters
structdevice*devdevice which adds devfreq governor
structdevfreq_governor*governorthe devfreq governor to be added
Description
This is a resource-managed variant ofdevfreq_add_governor().
- intdevfreq_remove_governor(structdevfreq_governor*governor)¶
Remove devfreq feature from a device.
Parameters
structdevfreq_governor*governorthe devfreq governor to be removed
- structdev_pm_opp*devfreq_recommended_opp(structdevice*dev,unsignedlong*freq,u32flags)¶
Helper function to get proper OPP for the freq value given to target callback.
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
unsignedlong*freqThe frequency given to target function
u32flagsFlags handed from devfreq framework.
Description
The callers are required to calldev_pm_opp_put() for the returned OPP afteruse.
- intdevfreq_register_opp_notifier(structdevice*dev,structdevfreq*devfreq)¶
Helper function to get devfreq notified for any changes in the OPP availability changes
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
structdevfreq*devfreqThe devfreq object.
- intdevfreq_unregister_opp_notifier(structdevice*dev,structdevfreq*devfreq)¶
Helper function to stop getting devfreq notified for any changes in the OPP availability changes anymore.
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
structdevfreq*devfreqThe devfreq object.
Description
Atexit() callback of devfreq_dev_profile, this must be included ifdevfreq_recommended_opp is used.
- intdevm_devfreq_register_opp_notifier(structdevice*dev,structdevfreq*devfreq)¶
Resource-managed
devfreq_register_opp_notifier()
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
structdevfreq*devfreqThe devfreq object.
- voiddevm_devfreq_unregister_opp_notifier(structdevice*dev,structdevfreq*devfreq)¶
Resource-managed
devfreq_unregister_opp_notifier()
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
structdevfreq*devfreqThe devfreq object.
- intdevfreq_register_notifier(structdevfreq*devfreq,structnotifier_block*nb,unsignedintlist)¶
Register a driver with devfreq
Parameters
structdevfreq*devfreqThe devfreq object.
structnotifier_block*nbThe notifier block to register.
unsignedintlistDEVFREQ_TRANSITION_NOTIFIER.
- intdevm_devfreq_register_notifier(structdevice*dev,structdevfreq*devfreq,structnotifier_block*nb,unsignedintlist)¶
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
structdevfreq*devfreqThe devfreq object.
structnotifier_block*nbThe notifier block to be unregistered.
unsignedintlistDEVFREQ_TRANSITION_NOTIFIER.
Description
Resource-managed
devfreq_register_notifier()
- voiddevm_devfreq_unregister_notifier(structdevice*dev,structdevfreq*devfreq,structnotifier_block*nb,unsignedintlist)¶
Parameters
structdevice*devThe devfreq user device. (parent of devfreq)
structdevfreq*devfreqThe devfreq object.
structnotifier_block*nbThe notifier block to be unregistered.
unsignedintlistDEVFREQ_TRANSITION_NOTIFIER.
Description
Resource-managed
devfreq_unregister_notifier()
- intdevfreq_event_enable_edev(structdevfreq_event_dev*edev)¶
Enable the devfreq-event dev and increase the enable_count of devfreq-event dev.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function increase the enable_count and enable thedevfreq-event device. The devfreq-event device should be enabled beforeusing it by devfreq device.
- intdevfreq_event_disable_edev(structdevfreq_event_dev*edev)¶
Disable the devfreq-event dev and decrease the enable_count of the devfreq-event dev.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function decrease the enable_count and disable thedevfreq-event device. After the devfreq-event device is disabled,devfreq device can’t use the devfreq-event device for get/set/resetoperations.
- booldevfreq_event_is_enabled(structdevfreq_event_dev*edev)¶
Check whether devfreq-event dev is enabled or not.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function check whether devfreq-event dev is enabled or not.If return true, the devfreq-event dev is enabeld. If return false, thedevfreq-event dev is disabled.
- intdevfreq_event_set_event(structdevfreq_event_dev*edev)¶
Set event to devfreq-event dev to start.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function set the event to the devfreq-event device to startfor getting the event data which could be various event type.
- intdevfreq_event_get_event(structdevfreq_event_dev*edev,structdevfreq_event_data*edata)¶
Get {load|total}_count from devfreq-event dev.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
structdevfreq_event_data*edatathe calculated data of devfreq-event device
Description
Note that this function get the calculated event data from devfreq-event devafter stoping the progress of whole sequence of devfreq-event dev.
- intdevfreq_event_reset_event(structdevfreq_event_dev*edev)¶
Reset all opeations of devfreq-event dev.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function stop all operations of devfreq-event dev and resetthe current event data to make the devfreq-event device into initial state.
- structdevfreq_event_dev*devfreq_event_get_edev_by_phandle(structdevice*dev,constchar*phandle_name,intindex)¶
Get the devfreq-event dev from devicetree.
Parameters
structdevice*devthe pointer to the given device
constchar*phandle_namename of property holding a phandle value
intindexthe index into list of devfreq-event device
Description
Note that this function return the pointer of devfreq-event device.
- intdevfreq_event_get_edev_count(structdevice*dev,constchar*phandle_name)¶
Get the count of devfreq-event dev
Parameters
structdevice*devthe pointer to the given device
constchar*phandle_namename of property holding a phandle value
Description
Note that this function return the count of devfreq-event devices.
- structdevfreq_event_dev*devfreq_event_add_edev(structdevice*dev,structdevfreq_event_desc*desc)¶
Add new devfreq-event device.
Parameters
structdevice*devthe device owning the devfreq-event device being created
structdevfreq_event_desc*descthe devfreq-event device’s descriptor which include essentialdata for devfreq-event device.
Description
Note that this function add new devfreq-event device to devfreq-event classlist and register the device of the devfreq-event device.
- intdevfreq_event_remove_edev(structdevfreq_event_dev*edev)¶
Remove the devfreq-event device registered.
Parameters
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function removes the registered devfreq-event device.
- structdevfreq_event_dev*devm_devfreq_event_add_edev(structdevice*dev,structdevfreq_event_desc*desc)¶
Resource-managed
devfreq_event_add_edev()
Parameters
structdevice*devthe device owning the devfreq-event device being created
structdevfreq_event_desc*descthe devfreq-event device’s descriptor which include essentialdata for devfreq-event device.
Description
Note that this function manages automatically the memory of devfreq-eventdevice using device resource management and simplify the free operationfor memory of devfreq-event device.
- voiddevm_devfreq_event_remove_edev(structdevice*dev,structdevfreq_event_dev*edev)¶
Resource-managed
devfreq_event_remove_edev()
Parameters
structdevice*devthe device owning the devfreq-event device being created
structdevfreq_event_dev*edevthe devfreq-event device
Description
Note that this function manages automatically the memory of devfreq-eventdevice using device resource management.