diff options
author | Ravi Jain <raviajain@google.com> | 2022-12-01 13:23:31 +0800 |
---|---|---|
committer | Ravi Jain <raviajain@google.com> | 2022-12-06 09:32:32 +0000 |
commit | 6ed38f65b7e0e3e412d4c2f2c45f9d01875cf94e (patch) | |
tree | 4e4353880b85401be978b640d5bf23531cf5eab3 | |
parent | a5637a3f0013729b6952ca7eae088bf11891e4ed (diff) | |
download | common-6ed38f65b7e0e3e412d4c2f2c45f9d01875cf94e.tar.gz |
touch: gti: Added wakelock_nosync supportandroid-t-qpr2-beta-2_r0.5android-t-qpr2-beta-2_r0.3
1. Merged resume and suspend work to update_state_work.
2. Modified wakelock logic to not require use of cancel_work_sync.
3. Added error_handling to wakelock calls.
4. Replaced use of completion bit to use of flush_workqueue in wakelock.
Test: Tested on L10 and T6 for resume/suspend.
Bug: 230827813
Change-Id: Ife27f2ea03aa578a40c14496340b84ff5533ab42
Signed-off-by: Ravi Jain <raviajain@google.com>
-rw-r--r-- | goog_touch_interface.c | 111 | ||||
-rw-r--r-- | goog_touch_interface.h | 17 |
2 files changed, 77 insertions, 51 deletions
diff --git a/goog_touch_interface.c b/goog_touch_interface.c index 70890a3..2dc73ce 100644 --- a/goog_touch_interface.c +++ b/goog_touch_interface.c @@ -1397,12 +1397,14 @@ static void goog_set_display_state(struct goog_touch_interface *gti, switch (display_state) { case GTI_DISPLAY_STATE_OFF: GOOG_INFO("screen-off.\n"); - goog_pm_wake_unlock(gti, GTI_PM_WAKELOCK_TYPE_SCREEN_ON); + ret = goog_pm_wake_unlock_nosync(gti, GTI_PM_WAKELOCK_TYPE_SCREEN_ON); + if (ret < 0) GOOG_INFO("Error while obtaining screen_on wakelock: %d!\n", ret); break; case GTI_DISPLAY_STATE_ON: GOOG_INFO("screen-on.\n"); - goog_pm_wake_lock(gti, GTI_PM_WAKELOCK_TYPE_SCREEN_ON, false); + ret = goog_pm_wake_lock_nosync(gti, GTI_PM_WAKELOCK_TYPE_SCREEN_ON, false); + if (ret < 0) GOOG_INFO("Error while obtaining screen_on wakelock: %d!\n", ret); break; default: @@ -2659,12 +2661,10 @@ void goog_init_options(struct goog_touch_interface *gti, } } -int goog_pm_wake_lock(struct goog_touch_interface *gti, +int goog_pm_wake_lock_nosync(struct goog_touch_interface *gti, enum gti_pm_wakelock_type type, bool skip_pm_resume) { struct gti_pm* pm = NULL; - int ret = 0; - bool wait_resume = false; if ((gti == NULL) || !gti->pm.enabled) return -ENODEV; @@ -2693,37 +2693,35 @@ int goog_pm_wake_lock(struct goog_touch_interface *gti, if (skip_pm_resume) { mutex_unlock(&pm->lock_mutex); - return ret; + return 0; } - /* - * When triggering a wake, wait up to one second to resume. - * SCREEN_ON does not need to wait. - */ - if (type != GTI_PM_WAKELOCK_TYPE_SCREEN_ON) - wait_resume = true; - + pm->new_state = GTI_PM_RESUME; + pm->update_state = true; + queue_work(pm->event_wq, &pm->state_update_work); mutex_unlock(&pm->lock_mutex); + return 0; +} +EXPORT_SYMBOL(goog_pm_wake_lock_nosync); - /* Complete or cancel any outstanding transitions */ - cancel_work_sync(&pm->suspend_work); - cancel_work_sync(&pm->resume_work); - - queue_work(pm->event_wq, &pm->resume_work); +int goog_pm_wake_lock(struct goog_touch_interface *gti, + enum gti_pm_wakelock_type type, bool skip_pm_resume) +{ + struct gti_pm* pm = NULL; + int ret = 0; - if (wait_resume) { - wait_for_completion_timeout(&pm->bus_resumed, msecs_to_jiffies(MSEC_PER_SEC)); - if (pm->state != GTI_PM_RESUME) { - GOOG_ERR("Failed to wake the touch bus.\n"); - ret = -ETIMEDOUT; - } - } + if ((gti == NULL) || !gti->pm.enabled) + return -ENODEV; + pm = >i->pm; + ret = goog_pm_wake_lock_nosync(gti, type, skip_pm_resume); + if (ret < 0) return ret; + flush_workqueue(pm->event_wq); return ret; } EXPORT_SYMBOL(goog_pm_wake_lock); -int goog_pm_wake_unlock(struct goog_touch_interface *gti, +int goog_pm_wake_unlock_nosync(struct goog_touch_interface *gti, enum gti_pm_wakelock_type type) { struct gti_pm* pm = NULL; @@ -2745,19 +2743,31 @@ int goog_pm_wake_unlock(struct goog_touch_interface *gti, pm->locks &= ~type; if (pm->locks == 0) { - mutex_unlock(&pm->lock_mutex); - /* Complete or cancel any outstanding transitions */ - cancel_work_sync(&pm->suspend_work); - cancel_work_sync(&pm->resume_work); - - mutex_lock(&pm->lock_mutex); - if (pm->locks == 0) - queue_work(pm->event_wq, &pm->suspend_work); + pm->new_state = GTI_PM_SUSPEND; + pm->update_state = true; + queue_work(pm->event_wq, &pm->state_update_work); } mutex_unlock(&pm->lock_mutex); return ret; } +EXPORT_SYMBOL(goog_pm_wake_unlock_nosync); + +int goog_pm_wake_unlock(struct goog_touch_interface *gti, + enum gti_pm_wakelock_type type) +{ + struct gti_pm* pm = NULL; + int ret = 0; + + if ((gti == NULL) || !gti->pm.enabled) + return -ENODEV; + pm = >i->pm; + + ret = goog_pm_wake_unlock_nosync(gti, type); + if (ret < 0) return ret; + flush_workqueue(pm->event_wq); + return ret; +} EXPORT_SYMBOL(goog_pm_wake_unlock); bool goog_pm_wake_check_locked(struct goog_touch_interface *gti, @@ -2779,9 +2789,8 @@ u32 goog_pm_wake_get_locks(struct goog_touch_interface *gti) } EXPORT_SYMBOL(goog_pm_wake_get_locks); -static void goog_pm_suspend_work(struct work_struct *work) +static void goog_pm_suspend(struct gti_pm *pm) { - struct gti_pm *pm = container_of(work, struct gti_pm, suspend_work); struct goog_touch_interface *gti = container_of(pm, struct goog_touch_interface, pm); int ret = 0; @@ -2795,7 +2804,6 @@ static void goog_pm_suspend_work(struct work_struct *work) GOOG_INFO("irq_index: %llu, input_index: %llu.\n", gti->irq_index, gti->input_index); pm->state = GTI_PM_SUSPEND; - reinit_completion(&pm->bus_resumed); if (pm->suspend) pm->suspend(gti->vendor_dev); @@ -2813,9 +2821,8 @@ static void goog_pm_suspend_work(struct work_struct *work) pm_relax(gti->dev); } -static void goog_pm_resume_work(struct work_struct *work) +static void goog_pm_resume(struct gti_pm *pm) { - struct gti_pm *pm = container_of(work, struct gti_pm, resume_work); struct goog_touch_interface *gti = container_of(pm, struct goog_touch_interface, pm); int ret = 0; @@ -2837,8 +2844,26 @@ static void goog_pm_resume_work(struct work_struct *work) if (pm->resume) pm->resume(gti->vendor_dev); +} + +void goog_pm_state_update_work(struct work_struct *work) { + struct gti_pm *pm = container_of(work, struct gti_pm, state_update_work); + enum gti_pm_state new_state; - complete_all(&pm->bus_resumed); + mutex_lock(&pm->lock_mutex); + while (pm->update_state) { + pm->update_state = false; + new_state = pm->new_state; + mutex_unlock(&pm->lock_mutex); + if (new_state != pm->state) { + if (new_state == GTI_PM_RESUME) + goog_pm_resume(pm); + else + goog_pm_suspend(pm); + } + mutex_lock(&pm->lock_mutex); + } + mutex_unlock(&pm->lock_mutex); } int goog_pm_register_notification(struct goog_touch_interface *gti, @@ -2918,11 +2943,7 @@ static int goog_pm_probe(struct goog_touch_interface *gti) } mutex_init(&pm->lock_mutex); - INIT_WORK(&pm->suspend_work, goog_pm_suspend_work); - INIT_WORK(&pm->resume_work, goog_pm_resume_work); - - init_completion(&pm->bus_resumed); - complete_all(&pm->bus_resumed); + INIT_WORK(&pm->state_update_work, goog_pm_state_update_work); /* init pm_qos. */ cpu_latency_qos_add_request(>i->pm_qos_req, PM_QOS_DEFAULT_VALUE); diff --git a/goog_touch_interface.h b/goog_touch_interface.h index 4ab8351..ab8ea7e 100644 --- a/goog_touch_interface.h +++ b/goog_touch_interface.h @@ -469,26 +469,27 @@ struct gti_optional_configuration { /** * struct gti_pm - power manager for GTI. - * @suspend_work: a work to run suspend. - * @resume_work: a work to run resume. + * @state_update_work: a work to update pm state. * @event_wq: a work queue to run suspend/resume work. - * @bus_resumed: a completion for waiting for resume is done. * @locks: the lock state. * @lock_mutex: protect the lock state. * @state: GTI pm state. + * @new_state: New GTI pm state to be updated to. + * @enabled: Boolean value to represent if GTI PM is active. + * @update_state: Boolean value if state needs to be updated. * @resume: callback for notifying resume. * @suspend: callback for notifying suspend. */ struct gti_pm { - struct work_struct suspend_work; - struct work_struct resume_work; + struct work_struct state_update_work; struct workqueue_struct *event_wq; - struct completion bus_resumed; u32 locks; struct mutex lock_mutex; enum gti_pm_state state; + enum gti_pm_state new_state; bool enabled; + bool update_state; int (*resume)(struct device *dev); int (*suspend)(struct device *dev); @@ -659,8 +660,12 @@ struct goog_touch_interface *goog_touch_interface_probe( struct gti_optional_configuration *options); int goog_touch_interface_remove(struct goog_touch_interface *gti); +int goog_pm_wake_lock_nosync(struct goog_touch_interface *gti, + enum gti_pm_wakelock_type type, bool skip_pm_resume); int goog_pm_wake_lock(struct goog_touch_interface *gti, enum gti_pm_wakelock_type type, bool skip_pm_resume); +int goog_pm_wake_unlock_nosync(struct goog_touch_interface *gti, + enum gti_pm_wakelock_type type); int goog_pm_wake_unlock(struct goog_touch_interface *gti, enum gti_pm_wakelock_type type); bool goog_pm_wake_check_locked(struct goog_touch_interface *gti, |