Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework
0004  *      for Non-CPU Devices.
0005  *
0006  * Copyright (C) 2011 Samsung Electronics
0007  *  MyungJoo Ham <myungjoo.ham@samsung.com>
0008  */
0009 
0010 #ifndef __LINUX_DEVFREQ_H__
0011 #define __LINUX_DEVFREQ_H__
0012 
0013 #include <linux/device.h>
0014 #include <linux/notifier.h>
0015 #include <linux/pm_opp.h>
0016 #include <linux/pm_qos.h>
0017 
0018 /* DEVFREQ governor name */
0019 #define DEVFREQ_GOV_SIMPLE_ONDEMAND "simple_ondemand"
0020 #define DEVFREQ_GOV_PERFORMANCE     "performance"
0021 #define DEVFREQ_GOV_POWERSAVE       "powersave"
0022 #define DEVFREQ_GOV_USERSPACE       "userspace"
0023 #define DEVFREQ_GOV_PASSIVE     "passive"
0024 
0025 /* DEVFREQ notifier interface */
0026 #define DEVFREQ_TRANSITION_NOTIFIER (0)
0027 
0028 /* Transition notifiers of DEVFREQ_TRANSITION_NOTIFIER */
0029 #define DEVFREQ_PRECHANGE       (0)
0030 #define DEVFREQ_POSTCHANGE      (1)
0031 
0032 /* DEVFREQ work timers */
0033 enum devfreq_timer {
0034     DEVFREQ_TIMER_DEFERRABLE = 0,
0035     DEVFREQ_TIMER_DELAYED,
0036     DEVFREQ_TIMER_NUM,
0037 };
0038 
0039 struct devfreq;
0040 struct devfreq_governor;
0041 struct devfreq_cpu_data;
0042 struct thermal_cooling_device;
0043 
0044 /**
0045  * struct devfreq_dev_status - Data given from devfreq user device to
0046  *               governors. Represents the performance
0047  *               statistics.
0048  * @total_time:     The total time represented by this instance of
0049  *          devfreq_dev_status
0050  * @busy_time:      The time that the device was working among the
0051  *          total_time.
0052  * @current_frequency:  The operating frequency.
0053  * @private_data:   An entry not specified by the devfreq framework.
0054  *          A device and a specific governor may have their
0055  *          own protocol with private_data. However, because
0056  *          this is governor-specific, a governor using this
0057  *          will be only compatible with devices aware of it.
0058  */
0059 struct devfreq_dev_status {
0060     /* both since the last measure */
0061     unsigned long total_time;
0062     unsigned long busy_time;
0063     unsigned long current_frequency;
0064     void *private_data;
0065 };
0066 
0067 /*
0068  * The resulting frequency should be at most this. (this bound is the
0069  * least upper bound; thus, the resulting freq should be lower or same)
0070  * If the flag is not set, the resulting frequency should be at most the
0071  * bound (greatest lower bound)
0072  */
0073 #define DEVFREQ_FLAG_LEAST_UPPER_BOUND      0x1
0074 
0075 /**
0076  * struct devfreq_dev_profile - Devfreq's user device profile
0077  * @initial_freq:   The operating frequency when devfreq_add_device() is
0078  *          called.
0079  * @polling_ms:     The polling interval in ms. 0 disables polling.
0080  * @timer:      Timer type is either deferrable or delayed timer.
0081  * @target:     The device should set its operating frequency at
0082  *          freq or lowest-upper-than-freq value. If freq is
0083  *          higher than any operable frequency, set maximum.
0084  *          Before returning, target function should set
0085  *          freq at the current frequency.
0086  *          The "flags" parameter's possible values are
0087  *          explained above with "DEVFREQ_FLAG_*" macros.
0088  * @get_dev_status: The device should provide the current performance
0089  *          status to devfreq. Governors are recommended not to
0090  *          use this directly. Instead, governors are recommended
0091  *          to use devfreq_update_stats() along with
0092  *          devfreq.last_status.
0093  * @get_cur_freq:   The device should provide the current frequency
0094  *          at which it is operating.
0095  * @exit:       An optional callback that is called when devfreq
0096  *          is removing the devfreq object due to error or
0097  *          from devfreq_remove_device() call. If the user
0098  *          has registered devfreq->nb at a notifier-head,
0099  *          this is the time to unregister it.
0100  * @freq_table:     Optional list of frequencies to support statistics
0101  *          and freq_table must be generated in ascending order.
0102  * @max_state:      The size of freq_table.
0103  *
0104  * @is_cooling_device: A self-explanatory boolean giving the device a
0105  *                     cooling effect property.
0106  */
0107 struct devfreq_dev_profile {
0108     unsigned long initial_freq;
0109     unsigned int polling_ms;
0110     enum devfreq_timer timer;
0111     bool is_cooling_device;
0112 
0113     int (*target)(struct device *dev, unsigned long *freq, u32 flags);
0114     int (*get_dev_status)(struct device *dev,
0115                   struct devfreq_dev_status *stat);
0116     int (*get_cur_freq)(struct device *dev, unsigned long *freq);
0117     void (*exit)(struct device *dev);
0118 
0119     unsigned long *freq_table;
0120     unsigned int max_state;
0121 };
0122 
0123 /**
0124  * struct devfreq_stats - Statistics of devfreq device behavior
0125  * @total_trans:    Number of devfreq transitions.
0126  * @trans_table:    Statistics of devfreq transitions.
0127  * @time_in_state:  Statistics of devfreq states.
0128  * @last_update:    The last time stats were updated.
0129  */
0130 struct devfreq_stats {
0131     unsigned int total_trans;
0132     unsigned int *trans_table;
0133     u64 *time_in_state;
0134     u64 last_update;
0135 };
0136 
0137 /**
0138  * struct devfreq - Device devfreq structure
0139  * @node:   list node - contains the devices with devfreq that have been
0140  *      registered.
0141  * @lock:   a mutex to protect accessing devfreq.
0142  * @dev:    device registered by devfreq class. dev.parent is the device
0143  *      using devfreq.
0144  * @profile:    device-specific devfreq profile
0145  * @governor:   method how to choose frequency based on the usage.
0146  * @opp_table:  Reference to OPP table of dev.parent, if one exists.
0147  * @nb:     notifier block used to notify devfreq object that it should
0148  *      reevaluate operable frequencies. Devfreq users may use
0149  *      devfreq.nb to the corresponding register notifier call chain.
0150  * @work:   delayed work for load monitoring.
0151  * @freq_table:     current frequency table used by the devfreq driver.
0152  * @max_state:      count of entry present in the frequency table.
0153  * @previous_freq:  previously configured frequency value.
0154  * @last_status:    devfreq user device info, performance statistics
0155  * @data:   Private data of the governor. The devfreq framework does not
0156  *      touch this.
0157  * @user_min_freq_req:  PM QoS minimum frequency request from user (via sysfs)
0158  * @user_max_freq_req:  PM QoS maximum frequency request from user (via sysfs)
0159  * @scaling_min_freq:   Limit minimum frequency requested by OPP interface
0160  * @scaling_max_freq:   Limit maximum frequency requested by OPP interface
0161  * @stop_polling:    devfreq polling status of a device.
0162  * @suspend_freq:    frequency of a device set during suspend phase.
0163  * @resume_freq:     frequency of a device set in resume phase.
0164  * @suspend_count:   suspend requests counter for a device.
0165  * @stats:  Statistics of devfreq device behavior
0166  * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
0167  * @cdev:   Cooling device pointer if the devfreq has cooling property
0168  * @nb_min:     Notifier block for DEV_PM_QOS_MIN_FREQUENCY
0169  * @nb_max:     Notifier block for DEV_PM_QOS_MAX_FREQUENCY
0170  *
0171  * This structure stores the devfreq information for a given device.
0172  *
0173  * Note that when a governor accesses entries in struct devfreq in its
0174  * functions except for the context of callbacks defined in struct
0175  * devfreq_governor, the governor should protect its access with the
0176  * struct mutex lock in struct devfreq. A governor may use this mutex
0177  * to protect its own private data in ``void *data`` as well.
0178  */
0179 struct devfreq {
0180     struct list_head node;
0181 
0182     struct mutex lock;
0183     struct device dev;
0184     struct devfreq_dev_profile *profile;
0185     const struct devfreq_governor *governor;
0186     struct opp_table *opp_table;
0187     struct notifier_block nb;
0188     struct delayed_work work;
0189 
0190     unsigned long *freq_table;
0191     unsigned int max_state;
0192 
0193     unsigned long previous_freq;
0194     struct devfreq_dev_status last_status;
0195 
0196     void *data; /* private data for governors */
0197 
0198     struct dev_pm_qos_request user_min_freq_req;
0199     struct dev_pm_qos_request user_max_freq_req;
0200     unsigned long scaling_min_freq;
0201     unsigned long scaling_max_freq;
0202     bool stop_polling;
0203 
0204     unsigned long suspend_freq;
0205     unsigned long resume_freq;
0206     atomic_t suspend_count;
0207 
0208     /* information for device frequency transitions */
0209     struct devfreq_stats stats;
0210 
0211     struct srcu_notifier_head transition_notifier_list;
0212 
0213     /* Pointer to the cooling device if used for thermal mitigation */
0214     struct thermal_cooling_device *cdev;
0215 
0216     struct notifier_block nb_min;
0217     struct notifier_block nb_max;
0218 };
0219 
0220 struct devfreq_freqs {
0221     unsigned long old;
0222     unsigned long new;
0223 };
0224 
0225 #if defined(CONFIG_PM_DEVFREQ)
0226 struct devfreq *devfreq_add_device(struct device *dev,
0227                 struct devfreq_dev_profile *profile,
0228                 const char *governor_name,
0229                 void *data);
0230 int devfreq_remove_device(struct devfreq *devfreq);
0231 struct devfreq *devm_devfreq_add_device(struct device *dev,
0232                 struct devfreq_dev_profile *profile,
0233                 const char *governor_name,
0234                 void *data);
0235 void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq);
0236 
0237 /* Supposed to be called by PM callbacks */
0238 int devfreq_suspend_device(struct devfreq *devfreq);
0239 int devfreq_resume_device(struct devfreq *devfreq);
0240 
0241 void devfreq_suspend(void);
0242 void devfreq_resume(void);
0243 
0244 /* update_devfreq() - Reevaluate the device and configure frequency */
0245 int update_devfreq(struct devfreq *devfreq);
0246 
0247 /* Helper functions for devfreq user device driver with OPP. */
0248 struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
0249                 unsigned long *freq, u32 flags);
0250 int devfreq_register_opp_notifier(struct device *dev,
0251                 struct devfreq *devfreq);
0252 int devfreq_unregister_opp_notifier(struct device *dev,
0253                 struct devfreq *devfreq);
0254 int devm_devfreq_register_opp_notifier(struct device *dev,
0255                 struct devfreq *devfreq);
0256 void devm_devfreq_unregister_opp_notifier(struct device *dev,
0257                 struct devfreq *devfreq);
0258 int devfreq_register_notifier(struct devfreq *devfreq,
0259                 struct notifier_block *nb,
0260                 unsigned int list);
0261 int devfreq_unregister_notifier(struct devfreq *devfreq,
0262                 struct notifier_block *nb,
0263                 unsigned int list);
0264 int devm_devfreq_register_notifier(struct device *dev,
0265                 struct devfreq *devfreq,
0266                 struct notifier_block *nb,
0267                 unsigned int list);
0268 void devm_devfreq_unregister_notifier(struct device *dev,
0269                 struct devfreq *devfreq,
0270                 struct notifier_block *nb,
0271                 unsigned int list);
0272 struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node);
0273 struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
0274                 const char *phandle_name, int index);
0275 
0276 #if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
0277 /**
0278  * struct devfreq_simple_ondemand_data - ``void *data`` fed to struct devfreq
0279  *  and devfreq_add_device
0280  * @upthreshold:    If the load is over this value, the frequency jumps.
0281  *          Specify 0 to use the default. Valid value = 0 to 100.
0282  * @downdifferential:   If the load is under upthreshold - downdifferential,
0283  *          the governor may consider slowing the frequency down.
0284  *          Specify 0 to use the default. Valid value = 0 to 100.
0285  *          downdifferential < upthreshold must hold.
0286  *
0287  * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor,
0288  * the governor uses the default values.
0289  */
0290 struct devfreq_simple_ondemand_data {
0291     unsigned int upthreshold;
0292     unsigned int downdifferential;
0293 };
0294 #endif
0295 
0296 #if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
0297 enum devfreq_parent_dev_type {
0298     DEVFREQ_PARENT_DEV,
0299     CPUFREQ_PARENT_DEV,
0300 };
0301 
0302 /**
0303  * struct devfreq_passive_data - ``void *data`` fed to struct devfreq
0304  *  and devfreq_add_device
0305  * @parent: the devfreq instance of parent device.
0306  * @get_target_freq:    Optional callback, Returns desired operating frequency
0307  *          for the device using passive governor. That is called
0308  *          when passive governor should decide the next frequency
0309  *          by using the new frequency of parent devfreq device
0310  *          using governors except for passive governor.
0311  *          If the devfreq device has the specific method to decide
0312  *          the next frequency, should use this callback.
0313  * @parent_type:    the parent type of the device.
0314  * @this:       the devfreq instance of own device.
0315  * @nb:         the notifier block for DEVFREQ_TRANSITION_NOTIFIER or
0316  *          CPUFREQ_TRANSITION_NOTIFIER list.
0317  * @cpu_data_list:  the list of cpu frequency data for all cpufreq_policy.
0318  *
0319  * The devfreq_passive_data have to set the devfreq instance of parent
0320  * device with governors except for the passive governor. But, don't need to
0321  * initialize the 'this' and 'nb' field because the devfreq core will handle
0322  * them.
0323  */
0324 struct devfreq_passive_data {
0325     /* Should set the devfreq instance of parent device */
0326     struct devfreq *parent;
0327 
0328     /* Optional callback to decide the next frequency of passvice device */
0329     int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
0330 
0331     /* Should set the type of parent device */
0332     enum devfreq_parent_dev_type parent_type;
0333 
0334     /* For passive governor's internal use. Don't need to set them */
0335     struct devfreq *this;
0336     struct notifier_block nb;
0337     struct list_head cpu_data_list;
0338 };
0339 #endif
0340 
0341 #else /* !CONFIG_PM_DEVFREQ */
0342 static inline struct devfreq *devfreq_add_device(struct device *dev,
0343                     struct devfreq_dev_profile *profile,
0344                     const char *governor_name,
0345                     void *data)
0346 {
0347     return ERR_PTR(-ENOSYS);
0348 }
0349 
0350 static inline int devfreq_remove_device(struct devfreq *devfreq)
0351 {
0352     return 0;
0353 }
0354 
0355 static inline struct devfreq *devm_devfreq_add_device(struct device *dev,
0356                     struct devfreq_dev_profile *profile,
0357                     const char *governor_name,
0358                     void *data)
0359 {
0360     return ERR_PTR(-ENOSYS);
0361 }
0362 
0363 static inline void devm_devfreq_remove_device(struct device *dev,
0364                     struct devfreq *devfreq)
0365 {
0366 }
0367 
0368 static inline int devfreq_suspend_device(struct devfreq *devfreq)
0369 {
0370     return 0;
0371 }
0372 
0373 static inline int devfreq_resume_device(struct devfreq *devfreq)
0374 {
0375     return 0;
0376 }
0377 
0378 static inline void devfreq_suspend(void) {}
0379 static inline void devfreq_resume(void) {}
0380 
0381 static inline struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
0382                     unsigned long *freq, u32 flags)
0383 {
0384     return ERR_PTR(-EINVAL);
0385 }
0386 
0387 static inline int devfreq_register_opp_notifier(struct device *dev,
0388                     struct devfreq *devfreq)
0389 {
0390     return -EINVAL;
0391 }
0392 
0393 static inline int devfreq_unregister_opp_notifier(struct device *dev,
0394                     struct devfreq *devfreq)
0395 {
0396     return -EINVAL;
0397 }
0398 
0399 static inline int devm_devfreq_register_opp_notifier(struct device *dev,
0400                     struct devfreq *devfreq)
0401 {
0402     return -EINVAL;
0403 }
0404 
0405 static inline void devm_devfreq_unregister_opp_notifier(struct device *dev,
0406                     struct devfreq *devfreq)
0407 {
0408 }
0409 
0410 static inline int devfreq_register_notifier(struct devfreq *devfreq,
0411                     struct notifier_block *nb,
0412                     unsigned int list)
0413 {
0414     return 0;
0415 }
0416 
0417 static inline int devfreq_unregister_notifier(struct devfreq *devfreq,
0418                     struct notifier_block *nb,
0419                     unsigned int list)
0420 {
0421     return 0;
0422 }
0423 
0424 static inline int devm_devfreq_register_notifier(struct device *dev,
0425                     struct devfreq *devfreq,
0426                     struct notifier_block *nb,
0427                     unsigned int list)
0428 {
0429     return 0;
0430 }
0431 
0432 static inline void devm_devfreq_unregister_notifier(struct device *dev,
0433                     struct devfreq *devfreq,
0434                     struct notifier_block *nb,
0435                     unsigned int list)
0436 {
0437 }
0438 
0439 static inline struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node)
0440 {
0441     return ERR_PTR(-ENODEV);
0442 }
0443 
0444 static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
0445                     const char *phandle_name, int index)
0446 {
0447     return ERR_PTR(-ENODEV);
0448 }
0449 
0450 static inline int devfreq_update_stats(struct devfreq *df)
0451 {
0452     return -EINVAL;
0453 }
0454 #endif /* CONFIG_PM_DEVFREQ */
0455 
0456 #endif /* __LINUX_DEVFREQ_H__ */