is read-only.  If the device is not enabled to wake up the
                system from sleep states, this attribute is not present.
 
-What:          /sys/devices/.../power/wakeup_hit_count
-Date:          September 2010
+What:          /sys/devices/.../power/wakeup_abort_count
+Date:          February 2012
 Contact:       Rafael J. Wysocki <rjw@sisk.pl>
 Description:
-               The /sys/devices/.../wakeup_hit_count attribute contains the
+               The /sys/devices/.../wakeup_abort_count attribute contains the
                number of times the processing of a wakeup event associated with
-               the device might prevent the system from entering a sleep state.
-               This attribute is read-only.  If the device is not enabled to
-               wake up the system from sleep states, this attribute is not
-               present.
+               the device might have aborted system transition into a sleep
+               state in progress.  This attribute is read-only.  If the device
+               is not enabled to wake up the system from sleep states, this
+               attribute is not present.
+
+What:          /sys/devices/.../power/wakeup_expire_count
+Date:          February 2012
+Contact:       Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+               The /sys/devices/.../wakeup_expire_count attribute contains the
+               number of times a wakeup event associated with the device has
+               been reported with a timeout that expired.  This attribute is
+               read-only.  If the device is not enabled to wake up the system
+               from sleep states, this attribute is not present.
 
 What:          /sys/devices/.../power/wakeup_active
 Date:          September 2010
 
 
 static DEVICE_ATTR(wakeup_active_count, 0444, wakeup_active_count_show, NULL);
 
-static ssize_t wakeup_hit_count_show(struct device *dev,
-                               struct device_attribute *attr, char *buf)
+static ssize_t wakeup_abort_count_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       unsigned long count = 0;
+       bool enabled = false;
+
+       spin_lock_irq(&dev->power.lock);
+       if (dev->power.wakeup) {
+               count = dev->power.wakeup->wakeup_count;
+               enabled = true;
+       }
+       spin_unlock_irq(&dev->power.lock);
+       return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n");
+}
+
+static DEVICE_ATTR(wakeup_abort_count, 0444, wakeup_abort_count_show, NULL);
+
+static ssize_t wakeup_expire_count_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
 {
        unsigned long count = 0;
        bool enabled = false;
 
        spin_lock_irq(&dev->power.lock);
        if (dev->power.wakeup) {
-               count = dev->power.wakeup->hit_count;
+               count = dev->power.wakeup->expire_count;
                enabled = true;
        }
        spin_unlock_irq(&dev->power.lock);
        return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n");
 }
 
-static DEVICE_ATTR(wakeup_hit_count, 0444, wakeup_hit_count_show, NULL);
+static DEVICE_ATTR(wakeup_expire_count, 0444, wakeup_expire_count_show, NULL);
 
 static ssize_t wakeup_active_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
        &dev_attr_wakeup.attr,
        &dev_attr_wakeup_count.attr,
        &dev_attr_wakeup_active_count.attr,
-       &dev_attr_wakeup_hit_count.attr,
+       &dev_attr_wakeup_abort_count.attr,
+       &dev_attr_wakeup_expire_count.attr,
        &dev_attr_wakeup_active.attr,
        &dev_attr_wakeup_total_time_ms.attr,
        &dev_attr_wakeup_max_time_ms.attr,
 
  * If set, the suspend/hibernate code will abort transitions to a sleep state
  * if wakeup events are registered during or immediately before the transition.
  */
-bool events_check_enabled;
+bool events_check_enabled __read_mostly;
 
 /*
  * Combined counters of registered wakeup events and wakeup events in progress.
        atomic_inc(&combined_event_count);
 }
 
+/**
+ * wakeup_source_report_event - Report wakeup event using the given source.
+ * @ws: Wakeup source to report the event for.
+ */
+static void wakeup_source_report_event(struct wakeup_source *ws)
+{
+       ws->event_count++;
+       /* This is racy, but the counter is approximate anyway. */
+       if (events_check_enabled)
+               ws->wakeup_count++;
+
+       if (!ws->active)
+               wakeup_source_activate(ws);
+}
+
 /**
  * __pm_stay_awake - Notify the PM core of a wakeup event.
  * @ws: Wakeup source object associated with the source of the event.
 
        spin_lock_irqsave(&ws->lock, flags);
 
-       ws->event_count++;
-       if (!ws->active)
-               wakeup_source_activate(ws);
-
+       wakeup_source_report_event(ws);
        del_timer(&ws->timer);
        ws->timer_expires = 0;
 
        if (ktime_to_ns(duration) > ktime_to_ns(ws->max_time))
                ws->max_time = duration;
 
+       ws->last_time = now;
        del_timer(&ws->timer);
        ws->timer_expires = 0;
 
        spin_lock_irqsave(&ws->lock, flags);
 
        if (ws->active && ws->timer_expires
-           && time_after_eq(jiffies, ws->timer_expires))
+           && time_after_eq(jiffies, ws->timer_expires)) {
                wakeup_source_deactivate(ws);
+               ws->expire_count++;
+       }
 
        spin_unlock_irqrestore(&ws->lock, flags);
 }
 
        spin_lock_irqsave(&ws->lock, flags);
 
-       ws->event_count++;
-       if (!ws->active)
-               wakeup_source_activate(ws);
+       wakeup_source_report_event(ws);
 
        if (!msec) {
                wakeup_source_deactivate(ws);
 }
 EXPORT_SYMBOL_GPL(pm_wakeup_event);
 
-/**
- * pm_wakeup_update_hit_counts - Update hit counts of all active wakeup sources.
- */
-static void pm_wakeup_update_hit_counts(void)
-{
-       unsigned long flags;
-       struct wakeup_source *ws;
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
-               spin_lock_irqsave(&ws->lock, flags);
-               if (ws->active)
-                       ws->hit_count++;
-               spin_unlock_irqrestore(&ws->lock, flags);
-       }
-       rcu_read_unlock();
-}
-
 /**
  * pm_wakeup_pending - Check if power transition in progress should be aborted.
  *
                events_check_enabled = !ret;
        }
        spin_unlock_irqrestore(&events_lock, flags);
-       if (ret)
-               pm_wakeup_update_hit_counts();
        return ret;
 }
 
                split_counters(&cnt, &inpr);
                if (inpr == 0 || signal_pending(current))
                        break;
-               pm_wakeup_update_hit_counts();
 
                schedule();
        }
                events_check_enabled = true;
        }
        spin_unlock_irq(&events_lock);
-       if (!events_check_enabled)
-               pm_wakeup_update_hit_counts();
        return events_check_enabled;
 }
 
                active_time = ktime_set(0, 0);
        }
 
-       ret = seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t"
+       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",
-                       ws->name, active_count, ws->event_count, ws->hit_count,
+                       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));
 
 {
        struct wakeup_source *ws;
 
-       seq_puts(m, "name\t\tactive_count\tevent_count\thit_count\t"
-               "active_since\ttotal_time\tmax_time\tlast_change\n");
+       seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
+               "expire_count\tactive_since\ttotal_time\tmax_time\t"
+               "last_change\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 activated last time.
+ * @last_time: Monotonic clock when the wakeup source's was touched last time.
  * @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.
- * @hit_count: Number of times the wakeup sorce might abort system suspend.
+ * @expire_count: Number of times the wakeup source's timeout has expired.
+ * @wakeup_count: Number of times the wakeup source might abort suspend.
  * @active: Status of the wakeup source.
+ * @has_timeout: The wakeup source has been activated with a timeout.
  */
 struct wakeup_source {
        const char              *name;
        unsigned long           event_count;
        unsigned long           active_count;
        unsigned long           relax_count;
-       unsigned long           hit_count;
-       unsigned int            active:1;
+       unsigned long           expire_count;
+       unsigned long           wakeup_count;
+       bool                    active:1;
 };
 
 #ifdef CONFIG_PM_SLEEP