Merge branch 'pm-domains' into pm-for-linus
authorRafael J. Wysocki <rjw@sisk.pl>
Fri, 21 Oct 2011 22:21:52 +0000 (00:21 +0200)
committerRafael J. Wysocki <rjw@sisk.pl>
Fri, 21 Oct 2011 22:21:52 +0000 (00:21 +0200)
* pm-domains:
  ARM: mach-shmobile: sh7372 A4R support (v4)
  ARM: mach-shmobile: sh7372 A3SP support (v4)
  PM / Sleep: Mark devices involved in wakeup signaling during suspend

1  2 
drivers/base/power/main.c
include/linux/pm.h

@@@ -46,7 -46,6 +46,7 @@@ LIST_HEAD(dpm_prepared_list)
  LIST_HEAD(dpm_suspended_list);
  LIST_HEAD(dpm_noirq_list);
  
 +struct suspend_stats suspend_stats;
  static DEFINE_MUTEX(dpm_list_mtx);
  static pm_message_t pm_transition;
  
@@@ -66,7 -65,6 +66,7 @@@ void device_pm_init(struct device *dev
        spin_lock_init(&dev->power.lock);
        pm_runtime_init(dev);
        INIT_LIST_HEAD(&dev->power.entry);
 +      dev->power.power_state = PMSG_INVALID;
  }
  
  /**
@@@ -98,7 -96,6 +98,7 @@@ void device_pm_add(struct device *dev
                dev_warn(dev, "parent %s should not be sleeping\n",
                        dev_name(dev->parent));
        list_add_tail(&dev->power.entry, &dpm_list);
 +      dev_pm_qos_constraints_init(dev);
        mutex_unlock(&dpm_list_mtx);
  }
  
@@@ -112,7 -109,6 +112,7 @@@ void device_pm_remove(struct device *de
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
        complete_all(&dev->power.completion);
        mutex_lock(&dpm_list_mtx);
 +      dev_pm_qos_constraints_destroy(dev);
        list_del_init(&dev->power.entry);
        mutex_unlock(&dpm_list_mtx);
        device_wakeup_disable(dev);
@@@ -468,12 -464,8 +468,12 @@@ void dpm_resume_noirq(pm_message_t stat
                mutex_unlock(&dpm_list_mtx);
  
                error = device_resume_noirq(dev, state);
 -              if (error)
 +              if (error) {
 +                      suspend_stats.failed_resume_noirq++;
 +                      dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
 +                      dpm_save_failed_dev(dev_name(dev));
                        pm_dev_err(dev, state, " early", error);
 +              }
  
                mutex_lock(&dpm_list_mtx);
                put_device(dev);
@@@ -634,12 -626,8 +634,12 @@@ void dpm_resume(pm_message_t state
                        mutex_unlock(&dpm_list_mtx);
  
                        error = device_resume(dev, state, false);
 -                      if (error)
 +                      if (error) {
 +                              suspend_stats.failed_resume++;
 +                              dpm_save_failed_step(SUSPEND_RESUME);
 +                              dpm_save_failed_dev(dev_name(dev));
                                pm_dev_err(dev, state, "", error);
 +                      }
  
                        mutex_lock(&dpm_list_mtx);
                }
@@@ -814,9 -802,6 +814,9 @@@ int dpm_suspend_noirq(pm_message_t stat
                mutex_lock(&dpm_list_mtx);
                if (error) {
                        pm_dev_err(dev, state, " late", error);
 +                      suspend_stats.failed_suspend_noirq++;
 +                      dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
 +                      dpm_save_failed_dev(dev_name(dev));
                        put_device(dev);
                        break;
                }
@@@ -917,7 -902,11 +917,11 @@@ static int __device_suspend(struct devi
        }
  
   End:
-       dev->power.is_suspended = !error;
+       if (!error) {
+               dev->power.is_suspended = true;
+               if (dev->power.wakeup_path && dev->parent)
+                       dev->parent->power.wakeup_path = true;
+       }
  
        device_unlock(dev);
        complete_all(&dev->power.completion);
@@@ -938,10 -927,8 +942,10 @@@ static void async_suspend(void *data, a
        int error;
  
        error = __device_suspend(dev, pm_transition, true);
 -      if (error)
 +      if (error) {
 +              dpm_save_failed_dev(dev_name(dev));
                pm_dev_err(dev, pm_transition, " async", error);
 +      }
  
        put_device(dev);
  }
@@@ -984,7 -971,6 +988,7 @@@ int dpm_suspend(pm_message_t state
                mutex_lock(&dpm_list_mtx);
                if (error) {
                        pm_dev_err(dev, state, "", error);
 +                      dpm_save_failed_dev(dev_name(dev));
                        put_device(dev);
                        break;
                }
        async_synchronize_full();
        if (!error)
                error = async_error;
 -      if (!error)
 +      if (error) {
 +              suspend_stats.failed_suspend++;
 +              dpm_save_failed_step(SUSPEND_SUSPEND);
 +      } else
                dpm_show_time(starttime, state, NULL);
        return error;
  }
@@@ -1020,6 -1003,8 +1024,8 @@@ static int device_prepare(struct devic
  
        device_lock(dev);
  
+       dev->power.wakeup_path = device_may_wakeup(dev);
        if (dev->pm_domain) {
                pm_dev_dbg(dev, state, "preparing power domain ");
                if (dev->pm_domain->ops.prepare)
@@@ -1109,10 -1094,7 +1115,10 @@@ int dpm_suspend_start(pm_message_t stat
        int error;
  
        error = dpm_prepare(state);
 -      if (!error)
 +      if (error) {
 +              suspend_stats.failed_prepare++;
 +              dpm_save_failed_step(SUSPEND_PREPARE);
 +      } else
                error = dpm_suspend(state);
        return error;
  }
diff --combined include/linux/pm.h
@@@ -326,7 -326,6 +326,7 @@@ extern struct dev_pm_ops generic_subsys
   *                    requested by a driver.
   */
  
 +#define PM_EVENT_INVALID      (-1)
  #define PM_EVENT_ON           0x0000
  #define PM_EVENT_FREEZE       0x0001
  #define PM_EVENT_SUSPEND      0x0002
  #define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND)
  #define PM_EVENT_AUTO_RESUME  (PM_EVENT_AUTO | PM_EVENT_RESUME)
  
 +#define PMSG_INVALID  ((struct pm_message){ .event = PM_EVENT_INVALID, })
  #define PMSG_ON               ((struct pm_message){ .event = PM_EVENT_ON, })
  #define PMSG_FREEZE   ((struct pm_message){ .event = PM_EVENT_FREEZE, })
  #define PMSG_QUIESCE  ((struct pm_message){ .event = PM_EVENT_QUIESCE, })
  #define PMSG_AUTO_RESUME      ((struct pm_message) \
                                        { .event = PM_EVENT_AUTO_RESUME, })
  
 +#define PMSG_IS_AUTO(msg)     (((msg).event & PM_EVENT_AUTO) != 0)
 +
  /**
   * Device run-time power management status.
   *
@@@ -452,6 -448,7 +452,7 @@@ struct dev_pm_info 
        struct list_head        entry;
        struct completion       completion;
        struct wakeup_source    *wakeup;
+       bool                    wakeup_path:1;
  #else
        unsigned int            should_wakeup:1;
  #endif
        unsigned long           accounting_timestamp;
  #endif
        struct pm_subsys_data   *subsys_data;  /* Owned by the subsystem. */
 +      struct pm_qos_constraints *constraints;
  };
  
  extern void update_pm_runtime_accounting(struct device *dev);