Merge tag 'pm-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[linux-2.6-block.git] / include / linux / devfreq.h
index 6fa02a20eb63387e5b56866dc52c6a8287eb210f..2de4e2eea180d133898980f87c659f86a7fb922b 100644 (file)
 
 #define DEVFREQ_NAME_LEN 16
 
+/* DEVFREQ notifier interface */
+#define DEVFREQ_TRANSITION_NOTIFIER    (0)
+
+/* Transition notifiers of DEVFREQ_TRANSITION_NOTIFIER */
+#define        DEVFREQ_PRECHANGE               (0)
+#define DEVFREQ_POSTCHANGE             (1)
+
 struct devfreq;
 
 /**
@@ -143,6 +150,7 @@ struct devfreq_governor {
  * @trans_table:       Statistics of devfreq transitions
  * @time_in_state:     Statistics of devfreq states
  * @last_stat_updated: The last time stat updated
+ * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
  *
  * This structure stores the devfreq information for a give device.
  *
@@ -177,6 +185,13 @@ struct devfreq {
        unsigned int *trans_table;
        unsigned long *time_in_state;
        unsigned long last_stat_updated;
+
+       struct srcu_notifier_head transition_notifier_list;
+};
+
+struct devfreq_freqs {
+       unsigned long old;
+       unsigned long new;
 };
 
 #if defined(CONFIG_PM_DEVFREQ)
@@ -207,6 +222,22 @@ 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);
+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);
+extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
+                                               int index);
 
 /**
  * devfreq_update_stats() - update the last_status pointer in struct devfreq
@@ -241,6 +272,39 @@ struct devfreq_simple_ondemand_data {
 };
 #endif
 
+#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
+
 #else /* !CONFIG_PM_DEVFREQ */
 static inline struct devfreq *devfreq_add_device(struct device *dev,
                                          struct devfreq_dev_profile *profile,
@@ -307,6 +371,41 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev,
 {
 }
 
+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)
+{
+}
+
+static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
+                                                       int index)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline int devfreq_update_stats(struct devfreq *df)
 {
        return -EINVAL;