MALI: midgard: RK: add wake_lock for delayed_work_to_power_off_gpu
authorchenzhen <chenzhen@rock-chips.com>
Mon, 20 Feb 2017 02:13:34 +0000 (10:13 +0800)
committerchenzhen <chenzhen@rock-chips.com>
Wed, 15 Mar 2017 01:45:49 +0000 (09:45 +0800)
To ensure that the work is executed before system being suspended.

Change-Id: Iec1bd114dfff53e2464540f09ced66cf6be81d1a
Signed-off-by: chenzhen <chenzhen@rock-chips.com>
drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c
drivers/gpu/arm/midgard/platform/rk/mali_kbase_rk.h

index bcf7971a5fdb8270f591bade1fa75eb28207be01..a6e2f9be980fc6d1fc9c1937763dbc609ea66733 100644 (file)
@@ -50,6 +50,7 @@ static inline int rk_pm_enable_regulator(struct kbase_device *kbdev)
 {
        return 0;
 }
+
 static inline void rk_pm_disable_regulator(struct kbase_device *kbdev)
 {
 }
@@ -85,6 +86,7 @@ static void rk_pm_power_off_delay_work(struct work_struct *work)
 
        platform->is_powered = false;
        KBASE_TIMELINE_GPU_POWER(kbdev, 0);
+       wake_unlock(&platform->wake_lock);
 }
 
 static int kbase_platform_rk_init(struct kbase_device *kbdev)
@@ -109,21 +111,30 @@ static int kbase_platform_rk_init(struct kbase_device *kbdev)
        platform->power_off_wq = create_freezable_workqueue("gpu_power_off_wq");
        if (!platform->power_off_wq) {
                E("couldn't create workqueue");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_wq;
        }
        INIT_DEFERRABLE_WORK(&platform->work, rk_pm_power_off_delay_work);
+
+       wake_lock_init(&platform->wake_lock, WAKE_LOCK_SUSPEND, "gpu");
+
        platform->utilisation_period = DEFAULT_UTILISATION_PERIOD_IN_MS;
 
        ret = kbase_platform_rk_create_sysfs_files(kbdev->dev);
        if (ret) {
                E("fail to create sysfs_files. ret = %d.", ret);
-               goto EXIT;
+               goto err_sysfs_files;
        }
 
        kbdev->platform_context = (void *)platform;
        pm_runtime_enable(kbdev->dev);
 
-EXIT:
+       return 0;
+
+err_sysfs_files:
+       wake_lock_destroy(&platform->wake_lock);
+       destroy_workqueue(platform->power_off_wq);
+err_wq:
        return ret;
 }
 
@@ -136,6 +147,7 @@ static void kbase_platform_rk_term(struct kbase_device *kbdev)
        kbdev->platform_context = NULL;
 
        if (platform) {
+               wake_lock_destroy(&platform->wake_lock);
                destroy_workqueue(platform->power_off_wq);
                platform->is_powered = false;
                platform->kbdev = NULL;
@@ -204,6 +216,7 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
 
        platform->is_powered = true;
        KBASE_TIMELINE_GPU_POWER(kbdev, 1);
+       wake_lock(&platform->wake_lock);
 
        return ret;
 }
index e1623806abe8b07d84bff60d6a5c6cd6675489b5..6eab25014d2184f739dacc17749ea05b3af2a12a 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _MALI_KBASE_RK_H_
 #define _MALI_KBASE_RK_H_
 
+#include <linux/wakelock.h>
+
 /*---------------------------------------------------------------------------*/
 
 #define DEFAULT_UTILISATION_PERIOD_IN_MS (100)
@@ -30,10 +32,20 @@ struct rk_context {
         * and 'power_off_callback'.
         */
        bool is_powered;
+
        struct kbase_device *kbdev;
+
        struct workqueue_struct *power_off_wq;
+       /* delayed_work_to_power_off_gpu. */
        struct delayed_work work;
        unsigned int delay_ms;
+
+       /*
+        * WAKE_LOCK_SUSPEND for ensuring to run
+        * delayed_work_to_power_off_gpu before suspend.
+        */
+       struct wake_lock wake_lock;
+
        /* debug only, the period in ms to count gpu_utilisation. */
        unsigned int utilisation_period;
 };