}
 
 static DEVICE_ATTR(wakeup_last_time_ms, 0444, wakeup_last_time_show, NULL);
+
+#ifdef CONFIG_PM_AUTOSLEEP
+static ssize_t wakeup_prevent_sleep_time_show(struct device *dev,
+                                             struct device_attribute *attr,
+                                             char *buf)
+{
+       s64 msec = 0;
+       bool enabled = false;
+
+       spin_lock_irq(&dev->power.lock);
+       if (dev->power.wakeup) {
+               msec = ktime_to_ms(dev->power.wakeup->prevent_sleep_time);
+               enabled = true;
+       }
+       spin_unlock_irq(&dev->power.lock);
+       return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n");
+}
+
+static DEVICE_ATTR(wakeup_prevent_sleep_time_ms, 0444,
+                  wakeup_prevent_sleep_time_show, NULL);
+#endif /* CONFIG_PM_AUTOSLEEP */
 #endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_PM_ADVANCED_DEBUG
        &dev_attr_wakeup_total_time_ms.attr,
        &dev_attr_wakeup_max_time_ms.attr,
        &dev_attr_wakeup_last_time_ms.attr,
+#ifdef CONFIG_PM_AUTOSLEEP
+       &dev_attr_wakeup_prevent_sleep_time_ms.attr,
+#endif
 #endif
        NULL,
 };
 
        ws->active = true;
        ws->active_count++;
        ws->last_time = ktime_get();
+       if (ws->autosleep_enabled)
+               ws->start_prevent_time = ws->last_time;
 
        /* Increment the counter of events in progress. */
        cec = atomic_inc_return(&combined_event_count);
 }
 EXPORT_SYMBOL_GPL(pm_stay_awake);
 
+#ifdef CONFIG_PM_AUTOSLEEP
+static void update_prevent_sleep_time(struct wakeup_source *ws, ktime_t now)
+{
+       ktime_t delta = ktime_sub(now, ws->start_prevent_time);
+       ws->prevent_sleep_time = ktime_add(ws->prevent_sleep_time, delta);
+}
+#else
+static inline void update_prevent_sleep_time(struct wakeup_source *ws,
+                                            ktime_t now) {}
+#endif
+
 /**
  * wakup_source_deactivate - Mark given wakeup source as inactive.
  * @ws: Wakeup source to handle.
        del_timer(&ws->timer);
        ws->timer_expires = 0;
 
+       if (ws->autosleep_enabled)
+               update_prevent_sleep_time(ws, now);
+
        /*
         * Increment the counter of registered wakeup events and decrement the
         * couter of wakeup events in progress simultaneously.
        return events_check_enabled;
 }
 
+#ifdef CONFIG_PM_AUTOSLEEP
+/**
+ * pm_wakep_autosleep_enabled - Modify autosleep_enabled for all wakeup sources.
+ * @enabled: Whether to set or to clear the autosleep_enabled flags.
+ */
+void pm_wakep_autosleep_enabled(bool set)
+{
+       struct wakeup_source *ws;
+       ktime_t now = ktime_get();
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
+               spin_lock_irq(&ws->lock);
+               if (ws->autosleep_enabled != set) {
+                       ws->autosleep_enabled = set;
+                       if (ws->active) {
+                               if (set)
+                                       ws->start_prevent_time = now;
+                               else
+                                       update_prevent_sleep_time(ws, now);
+                       }
+               }
+               spin_unlock_irq(&ws->lock);
+       }
+       rcu_read_unlock();
+}
+#endif /* CONFIG_PM_AUTOSLEEP */
+
 static struct dentry *wakeup_sources_stats_dentry;
 
 /**
        ktime_t max_time;
        unsigned long active_count;
        ktime_t active_time;
+       ktime_t prevent_sleep_time;
        int ret;
 
        spin_lock_irqsave(&ws->lock, flags);
 
        total_time = ws->total_time;
        max_time = ws->max_time;
+       prevent_sleep_time = ws->prevent_sleep_time;
        active_count = ws->active_count;
        if (ws->active) {
-               active_time = ktime_sub(ktime_get(), ws->last_time);
+               ktime_t now = ktime_get();
+
+               active_time = ktime_sub(now, ws->last_time);
                total_time = ktime_add(total_time, active_time);
                if (active_time.tv64 > max_time.tv64)
                        max_time = active_time;
+
+               if (ws->autosleep_enabled)
+                       prevent_sleep_time = ktime_add(prevent_sleep_time,
+                               ktime_sub(now, ws->start_prevent_time));
        } else {
                active_time = ktime_set(0, 0);
        }
 
        ret = seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t"
-                       "%lld\t\t%lld\t\t%lld\t\t%lld\n",
+                       "%lld\t\t%lld\t\t%lld\t\t%lld\t\t%lld\n",
                        ws->name, active_count, ws->event_count,
                        ws->wakeup_count, ws->expire_count,
                        ktime_to_ms(active_time), ktime_to_ms(total_time),
-                       ktime_to_ms(max_time), ktime_to_ms(ws->last_time));
+                       ktime_to_ms(max_time), ktime_to_ms(ws->last_time),
+                       ktime_to_ms(prevent_sleep_time));
 
        spin_unlock_irqrestore(&ws->lock, flags);
 
 
        seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
                "expire_count\tactive_since\ttotal_time\tmax_time\t"
-               "last_change\n");
+               "last_change\tprevent_suspend_time\n");
 
        rcu_read_lock();
        list_for_each_entry_rcu(ws, &wakeup_sources, entry)
 
  * @total_time: Total time this wakeup source has been active.
  * @max_time: Maximum time this wakeup source has been continuously active.
  * @last_time: Monotonic clock when the wakeup source's was touched last time.
+ * @prevent_sleep_time: Total time this source has been preventing autosleep.
  * @event_count: Number of signaled wakeup events.
  * @active_count: Number of times the wakeup sorce was activated.
  * @relax_count: Number of times the wakeup sorce was deactivated.
        ktime_t total_time;
        ktime_t max_time;
        ktime_t last_time;
+       ktime_t start_prevent_time;
+       ktime_t prevent_sleep_time;
        unsigned long           event_count;
        unsigned long           active_count;
        unsigned long           relax_count;
        unsigned long           expire_count;
        unsigned long           wakeup_count;
        bool                    active:1;
+       bool                    autosleep_enabled:1;
 };
 
 #ifdef CONFIG_PM_SLEEP