devfreq: add devfreq_suspend/resume() functions
authorLukasz Luba <l.luba@partner.samsung.com>
Fri, 16 Nov 2018 12:33:53 +0000 (13:33 +0100)
committerInki Dae <inki.dae@samsung.com>
Mon, 3 Dec 2018 00:56:49 +0000 (09:56 +0900)
This patch adds implementation for global suspend/resume for
devfreq framework. System suspend will next use these functions.

The patch is based on earlier work by Tobias Jakobi.

Change-Id: Id48187e492eb11f532512ecdda736309bc094af4
Suggested-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Suggested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Lukasz Luba <l.luba@partner.samsung.com>
drivers/devfreq/devfreq.c
include/linux/devfreq.h

index bb0d84aff15e86822e34fe12e84547c2a7c50da7..39b557a1b1a809a41e1529ad19a7397d43298280 100644 (file)
@@ -891,6 +891,48 @@ int devfreq_resume_device(struct devfreq *devfreq)
 }
 EXPORT_SYMBOL(devfreq_resume_device);
 
+/**
+ * devfreq_suspend() - Suspend devfreq governors and devices
+ *
+ * Called during system wide Suspend/Hibernate cycles for suspending governors
+ * and devices preserving the state for resume. On some platforms the devfreq
+ * device must have precise state (frequency) after resume in order to provide
+ * fully operating setup.
+ */
+void devfreq_suspend(void)
+{
+       struct devfreq *devfreq;
+       int ret;
+
+       mutex_lock(&devfreq_list_lock);
+       list_for_each_entry(devfreq, &devfreq_list, node) {
+               ret = devfreq_suspend_device(devfreq);
+               if (ret)
+                       dev_warn(&devfreq->dev, "device suspend failed\n");
+       }
+       mutex_unlock(&devfreq_list_lock);
+}
+
+/**
+ * devfreq_resume() - Resume devfreq governors and devices
+ *
+ * Called during system wide Suspend/Hibernate cycle for resuming governors and
+ * devices that are suspended with devfreq_suspend().
+ */
+void devfreq_resume(void)
+{
+       struct devfreq *devfreq;
+       int ret;
+
+       mutex_lock(&devfreq_list_lock);
+       list_for_each_entry(devfreq, &devfreq_list, node) {
+               ret = devfreq_resume_device(devfreq);
+               if (ret)
+                       dev_warn(&devfreq->dev, "device resume failed\n");
+       }
+       mutex_unlock(&devfreq_list_lock);
+}
+
 /**
  * devfreq_add_governor() - Add devfreq governor
  * @governor:  the devfreq governor to be added
index 0a51aa63853c230dac5c92c3ba67a54b7d5639c3..55c0deaec0f538340ed3d242b0dade3bc2c75076 100644 (file)
@@ -202,6 +202,9 @@ extern void devm_devfreq_remove_device(struct device *dev,
 extern int devfreq_suspend_device(struct devfreq *devfreq);
 extern int devfreq_resume_device(struct devfreq *devfreq);
 
+extern void devfreq_suspend(void);
+extern void devfreq_resume(void);
+
 /* Helper functions for devfreq user device driver with OPP. */
 extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
                                           unsigned long *freq, u32 flags);
@@ -320,6 +323,9 @@ static inline int devfreq_resume_device(struct devfreq *devfreq)
        return 0;
 }
 
+static inline void devfreq_suspend(void) {}
+static inline void devfreq_resume(void) {}
+
 static inline struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
                                           unsigned long *freq, u32 flags)
 {