@@ -49,6 +49,11 @@ static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
4949enum freeze_state __read_mostly suspend_freeze_state ;
5050static DEFINE_SPINLOCK (suspend_freeze_lock );
5151
52+ static bool sys_sync_completed = false;
53+ static void sys_sync_work_func (struct work_struct * work );
54+ static DECLARE_WORK (sys_sync_work , sys_sync_work_func );
55+ static DECLARE_WAIT_QUEUE_HEAD (sys_sync_wait );
56+
5257void freeze_set_ops (const struct platform_freeze_ops * ops )
5358{
5459 lock_system_sleep ();
@@ -480,6 +485,55 @@ static void suspend_finish(void)
480485 pm_restore_console ();
481486}
482487
488+ /**
489+ * Sync the filesystem in seperate workqueue.
490+ * Then check it finishing or not periodically and
491+ * abort if any wakeup source comes in. That can reduce
492+ * the wakeup latency
493+ *
494+ */
495+ static void sys_sync_work_func (struct work_struct * work )
496+ {
497+ printk (KERN_INFO "PM: Syncing filesystems ... \n" );
498+ sys_sync ();
499+ sys_sync_completed = true;
500+ wake_up (& sys_sync_wait );
501+ }
502+
503+ static int sys_sync_queue (void )
504+ {
505+ int work_status = work_busy (& sys_sync_work );
506+
507+ /*Check if the previous work still running.*/
508+ if (!(work_status & WORK_BUSY_PENDING )) {
509+ if (work_status & WORK_BUSY_RUNNING ) {
510+ while (wait_event_timeout (sys_sync_wait , sys_sync_completed ,
511+ msecs_to_jiffies (100 )) == 0 ) {
512+ if (pm_wakeup_pending ()) {
513+ pr_info ("PM: Pre-Syncing abort\n" );
514+ goto abort ;
515+ }
516+ }
517+ pr_info ("PM: Pre-Syncing done\n" );
518+ }
519+ sys_sync_completed = false;
520+ schedule_work (& sys_sync_work );
521+ }
522+
523+ while (wait_event_timeout (sys_sync_wait , sys_sync_completed ,
524+ msecs_to_jiffies (100 )) == 0 ) {
525+ if (pm_wakeup_pending ()) {
526+ pr_info ("PM: Syncing abort\n" );
527+ goto abort ;
528+ }
529+ }
530+
531+ pr_info ("PM: Syncing done\n" );
532+ return 0 ;
533+ abort :
534+ return - EAGAIN ;
535+ }
536+
483537/**
484538 * enter_state - Do common work needed to enter system sleep state.
485539 * @state: System sleep state to enter.
@@ -513,7 +567,10 @@ static int enter_state(suspend_state_t state)
513567#ifndef CONFIG_SUSPEND_SKIP_SYNC
514568 trace_suspend_resume (TPS ("sync_filesystems" ), 0 , true);
515569 printk (KERN_INFO "PM: Syncing filesystems ... " );
516- sys_sync ();
570+ error = sys_sync_queue ();
571+ if (error ) {
572+ goto Unlock ;
573+ }
517574 printk ("done.\n" );
518575 trace_suspend_resume (TPS ("sync_filesystems" ), 0 , false);
519576#endif
0 commit comments