diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/pm.h | 58 | ||||
| -rw-r--r-- | include/linux/pm_wakeup.h | 22 | ||||
| -rw-r--r-- | include/linux/suspend.h | 4 | 
3 files changed, 75 insertions, 9 deletions
diff --git a/include/linux/pm.h b/include/linux/pm.h index e4982ac3fbbc..d6dd6f612b8d 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -110,6 +110,10 @@ typedef struct pm_message {   *	Subsystem-level @suspend() is executed for all devices after invoking   *	subsystem-level @prepare() for all of them.   * + * @suspend_late: Continue operations started by @suspend().  For a number of + *	devices @suspend_late() may point to the same callback routine as the + *	runtime suspend callback. + *   * @resume: Executed after waking the system up from a sleep state in which the   *	contents of main memory were preserved.  The exact action to perform   *	depends on the device's subsystem, but generally the driver is expected @@ -122,6 +126,10 @@ typedef struct pm_message {   *	Subsystem-level @resume() is executed for all devices after invoking   *	subsystem-level @resume_noirq() for all of them.   * + * @resume_early: Prepare to execute @resume().  For a number of devices + *	@resume_early() may point to the same callback routine as the runtime + *	resume callback. + *   * @freeze: Hibernation-specific, executed before creating a hibernation image.   *	Analogous to @suspend(), but it should not enable the device to signal   *	wakeup events or change its power state.  The majority of subsystems @@ -131,6 +139,10 @@ typedef struct pm_message {   *	Subsystem-level @freeze() is executed for all devices after invoking   *	subsystem-level @prepare() for all of them.   * + * @freeze_late: Continue operations started by @freeze().  Analogous to + *	@suspend_late(), but it should not enable the device to signal wakeup + *	events or change its power state. + *   * @thaw: Hibernation-specific, executed after creating a hibernation image OR   *	if the creation of an image has failed.  Also executed after a failing   *	attempt to restore the contents of main memory from such an image. @@ -140,15 +152,23 @@ typedef struct pm_message {   *	subsystem-level @thaw_noirq() for all of them.  It also may be executed   *	directly after @freeze() in case of a transition error.   * + * @thaw_early: Prepare to execute @thaw().  Undo the changes made by the + *	preceding @freeze_late(). + *   * @poweroff: Hibernation-specific, executed after saving a hibernation image.   *	Analogous to @suspend(), but it need not save the device's settings in   *	memory.   *	Subsystem-level @poweroff() is executed for all devices after invoking   *	subsystem-level @prepare() for all of them.   * + * @poweroff_late: Continue operations started by @poweroff().  Analogous to + *	@suspend_late(), but it need not save the device's settings in memory. + *   * @restore: Hibernation-specific, executed after restoring the contents of main   *	memory from a hibernation image, analogous to @resume().   * + * @restore_early: Prepare to execute @restore(), analogous to @resume_early(). + *   * @suspend_noirq: Complete the actions started by @suspend().  Carry out any   *	additional operations required for suspending the device that might be   *	racing with its driver's interrupt handler, which is guaranteed not to @@ -158,9 +178,10 @@ typedef struct pm_message {   *	@suspend_noirq() has returned successfully.  If the device can generate   *	system wakeup signals and is enabled to wake up the system, it should be   *	configured to do so at that time.  However, depending on the platform - *	and device's subsystem, @suspend() may be allowed to put the device into - *	the low-power state and configure it to generate wakeup signals, in - *	which case it generally is not necessary to define @suspend_noirq(). + *	and device's subsystem, @suspend() or @suspend_late() may be allowed to + *	put the device into the low-power state and configure it to generate + *	wakeup signals, in which case it generally is not necessary to define + *	@suspend_noirq().   *   * @resume_noirq: Prepare for the execution of @resume() by carrying out any   *	operations required for resuming the device that might be racing with @@ -171,9 +192,9 @@ typedef struct pm_message {   *	additional operations required for freezing the device that might be   *	racing with its driver's interrupt handler, which is guaranteed not to   *	run while @freeze_noirq() is being executed. - *	The power state of the device should not be changed by either @freeze() - *	or @freeze_noirq() and it should not be configured to signal system - *	wakeup by any of these callbacks. + *	The power state of the device should not be changed by either @freeze(), + *	or @freeze_late(), or @freeze_noirq() and it should not be configured to + *	signal system wakeup by any of these callbacks.   *   * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any   *	operations required for thawing the device that might be racing with its @@ -249,6 +270,12 @@ struct dev_pm_ops {  	int (*thaw)(struct device *dev);  	int (*poweroff)(struct device *dev);  	int (*restore)(struct device *dev); +	int (*suspend_late)(struct device *dev); +	int (*resume_early)(struct device *dev); +	int (*freeze_late)(struct device *dev); +	int (*thaw_early)(struct device *dev); +	int (*poweroff_late)(struct device *dev); +	int (*restore_early)(struct device *dev);  	int (*suspend_noirq)(struct device *dev);  	int (*resume_noirq)(struct device *dev);  	int (*freeze_noirq)(struct device *dev); @@ -293,6 +320,15 @@ const struct dev_pm_ops name = { \  /*   * Use this for defining a set of PM operations to be used in all situations   * (sustem suspend, hibernation or runtime PM). + * NOTE: In general, system suspend callbacks, .suspend() and .resume(), should + * be different from the corresponding runtime PM callbacks, .runtime_suspend(), + * and .runtime_resume(), because .runtime_suspend() always works on an already + * quiescent device, while .suspend() should assume that the device may be doing + * something when it is called (it should ensure that the device will be + * quiescent after it has returned).  Therefore it's better to point the "late" + * suspend and "early" resume callback pointers, .suspend_late() and + * .resume_early(), to the same routines as .runtime_suspend() and + * .runtime_resume(), respectively (and analogously for hibernation).   */  #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \  const struct dev_pm_ops name = { \ @@ -584,13 +620,13 @@ struct dev_pm_domain {  #ifdef CONFIG_PM_SLEEP  extern void device_pm_lock(void); -extern void dpm_resume_noirq(pm_message_t state); +extern void dpm_resume_start(pm_message_t state);  extern void dpm_resume_end(pm_message_t state);  extern void dpm_resume(pm_message_t state);  extern void dpm_complete(pm_message_t state);  extern void device_pm_unlock(void); -extern int dpm_suspend_noirq(pm_message_t state); +extern int dpm_suspend_end(pm_message_t state);  extern int dpm_suspend_start(pm_message_t state);  extern int dpm_suspend(pm_message_t state);  extern int dpm_prepare(pm_message_t state); @@ -605,17 +641,23 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);  extern int device_pm_wait_for_dev(struct device *sub, struct device *dev);  extern int pm_generic_prepare(struct device *dev); +extern int pm_generic_suspend_late(struct device *dev);  extern int pm_generic_suspend_noirq(struct device *dev);  extern int pm_generic_suspend(struct device *dev); +extern int pm_generic_resume_early(struct device *dev);  extern int pm_generic_resume_noirq(struct device *dev);  extern int pm_generic_resume(struct device *dev);  extern int pm_generic_freeze_noirq(struct device *dev); +extern int pm_generic_freeze_late(struct device *dev);  extern int pm_generic_freeze(struct device *dev);  extern int pm_generic_thaw_noirq(struct device *dev); +extern int pm_generic_thaw_early(struct device *dev);  extern int pm_generic_thaw(struct device *dev);  extern int pm_generic_restore_noirq(struct device *dev); +extern int pm_generic_restore_early(struct device *dev);  extern int pm_generic_restore(struct device *dev);  extern int pm_generic_poweroff_noirq(struct device *dev); +extern int pm_generic_poweroff_late(struct device *dev);  extern int pm_generic_poweroff(struct device *dev);  extern void pm_generic_complete(struct device *dev); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index a32da962d693..d9f05113e5fb 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -41,7 +41,7 @@   * @active: Status of the wakeup source.   */  struct wakeup_source { -	char 			*name; +	const char 		*name;  	struct list_head	entry;  	spinlock_t		lock;  	struct timer_list	timer; @@ -73,7 +73,9 @@ static inline bool device_may_wakeup(struct device *dev)  }  /* drivers/base/power/wakeup.c */ +extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name);  extern struct wakeup_source *wakeup_source_create(const char *name); +extern void wakeup_source_drop(struct wakeup_source *ws);  extern void wakeup_source_destroy(struct wakeup_source *ws);  extern void wakeup_source_add(struct wakeup_source *ws);  extern void wakeup_source_remove(struct wakeup_source *ws); @@ -103,11 +105,16 @@ static inline bool device_can_wakeup(struct device *dev)  	return dev->power.can_wakeup;  } +static inline void wakeup_source_prepare(struct wakeup_source *ws, +					 const char *name) {} +  static inline struct wakeup_source *wakeup_source_create(const char *name)  {  	return NULL;  } +static inline void wakeup_source_drop(struct wakeup_source *ws) {} +  static inline void wakeup_source_destroy(struct wakeup_source *ws) {}  static inline void wakeup_source_add(struct wakeup_source *ws) {} @@ -165,4 +172,17 @@ static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {}  #endif /* !CONFIG_PM_SLEEP */ +static inline void wakeup_source_init(struct wakeup_source *ws, +				      const char *name) +{ +	wakeup_source_prepare(ws, name); +	wakeup_source_add(ws); +} + +static inline void wakeup_source_trash(struct wakeup_source *ws) +{ +	wakeup_source_remove(ws); +	wakeup_source_drop(ws); +} +  #endif /* _LINUX_PM_WAKEUP_H */ diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 91784a4f8608..ac1c114c499d 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -42,8 +42,10 @@ enum suspend_stat_step {  	SUSPEND_FREEZE = 1,  	SUSPEND_PREPARE,  	SUSPEND_SUSPEND, +	SUSPEND_SUSPEND_LATE,  	SUSPEND_SUSPEND_NOIRQ,  	SUSPEND_RESUME_NOIRQ, +	SUSPEND_RESUME_EARLY,  	SUSPEND_RESUME  }; @@ -53,8 +55,10 @@ struct suspend_stats {  	int	failed_freeze;  	int	failed_prepare;  	int	failed_suspend; +	int	failed_suspend_late;  	int	failed_suspend_noirq;  	int	failed_resume; +	int	failed_resume_early;  	int	failed_resume_noirq;  #define	REC_FAILED_NUM	2  	int	last_failed_dev;  | 
