diff options
Diffstat (limited to 'include/linux/pm.h')
| -rw-r--r-- | include/linux/pm.h | 128 | 
1 files changed, 92 insertions, 36 deletions
diff --git a/include/linux/pm.h b/include/linux/pm.h index a224c7f5c37..72c0fe098a2 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -93,13 +93,23 @@ typedef struct pm_message {   *	been registered) to recover from the race condition.   *	This method is executed for all kinds of suspend transitions and is   *	followed by one of the suspend callbacks: @suspend(), @freeze(), or - *	@poweroff().  The PM core executes subsystem-level @prepare() for all - *	devices before starting to invoke suspend callbacks for any of them, so - *	generally devices may be assumed to be functional or to respond to - *	runtime resume requests while @prepare() is being executed.  However, - *	device drivers may NOT assume anything about the availability of user - *	space at that time and it is NOT valid to request firmware from within - *	@prepare() (it's too late to do that).  It also is NOT valid to allocate + *	@poweroff().  If the transition is a suspend to memory or standby (that + *	is, not related to hibernation), the return value of @prepare() may be + *	used to indicate to the PM core to leave the device in runtime suspend + *	if applicable.  Namely, if @prepare() returns a positive number, the PM + *	core will understand that as a declaration that the device appears to be + *	runtime-suspended and it may be left in that state during the entire + *	transition and during the subsequent resume if all of its descendants + *	are left in runtime suspend too.  If that happens, @complete() will be + *	executed directly after @prepare() and it must ensure the proper + *	functioning of the device after the system resume. + *	The PM core executes subsystem-level @prepare() for all devices before + *	starting to invoke suspend callbacks for any of them, so generally + *	devices may be assumed to be functional or to respond to runtime resume + *	requests while @prepare() is being executed.  However, device drivers + *	may NOT assume anything about the availability of user space at that + *	time and it is NOT valid to request firmware from within @prepare() + *	(it's too late to do that).  It also is NOT valid to allocate   *	substantial amounts of memory from @prepare() in the GFP_KERNEL mode.   *	[To work around these limitations, drivers may register suspend and   *	hibernation notifiers to be executed before the freezing of tasks.] @@ -112,7 +122,16 @@ typedef struct pm_message {   *	of the other devices that the PM core has unsuccessfully attempted to   *	suspend earlier).   *	The PM core executes subsystem-level @complete() after it has executed - *	the appropriate resume callbacks for all devices. + *	the appropriate resume callbacks for all devices.  If the corresponding + *	@prepare() at the beginning of the suspend transition returned a + *	positive number and the device was left in runtime suspend (without + *	executing any suspend and resume callbacks for it), @complete() will be + *	the only callback executed for the device during resume.  In that case, + *	@complete() must be prepared to do whatever is necessary to ensure the + *	proper functioning of the device after the system resume.  To this end, + *	@complete() can check the power.direct_complete flag of the device to + *	learn whether (unset) or not (set) the previous suspend and resume + *	callbacks have been executed for it.   *   * @suspend: Executed before putting the system into a sleep state in which the   *	contents of main memory are preserved.  The exact action to perform @@ -264,9 +283,9 @@ typedef struct pm_message {   *	registers, so that it is fully operational.   *   * @runtime_idle: Device appears to be inactive and it might be put into a - *	low-power state if all of the necessary conditions are satisfied.  Check - *	these conditions and handle the device as appropriate, possibly queueing - *	a suspend request for it.  The return value is ignored by the PM core. + *	low-power state if all of the necessary conditions are satisfied. + *	Check these conditions, and return 0 if it's appropriate to let the PM + *	core queue a suspend request for the device.   *   * Refer to Documentation/power/runtime_pm.txt for more information about the   * role of the above callbacks in device runtime power management. @@ -311,6 +330,18 @@ struct dev_pm_ops {  #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)  #endif +#ifdef CONFIG_PM_SLEEP +#define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ +	.suspend_late = suspend_fn, \ +	.resume_early = resume_fn, \ +	.freeze_late = suspend_fn, \ +	.thaw_early = resume_fn, \ +	.poweroff_late = suspend_fn, \ +	.restore_early = resume_fn, +#else +#define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) +#endif +  #ifdef CONFIG_PM_RUNTIME  #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \  	.runtime_suspend = suspend_fn, \ @@ -320,6 +351,15 @@ struct dev_pm_ops {  #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)  #endif +#ifdef CONFIG_PM +#define SET_PM_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ +	.runtime_suspend = suspend_fn, \ +	.runtime_resume = resume_fn, \ +	.runtime_idle = idle_fn, +#else +#define SET_PM_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) +#endif +  /*   * Use this if you want to use the same suspend and resume callbacks for suspend   * to RAM and hibernation. @@ -331,7 +371,7 @@ 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). + * (system 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 @@ -358,7 +398,7 @@ const struct dev_pm_ops name = { \   *   * ON		No transition.   * - * FREEZE 	System is going to hibernate, call ->prepare() and ->freeze() + * FREEZE	System is going to hibernate, call ->prepare() and ->freeze()   *		for all devices.   *   * SUSPEND	System is going to suspend, call ->prepare() and ->suspend() @@ -402,7 +442,7 @@ const struct dev_pm_ops name = { \  #define PM_EVENT_INVALID	(-1)  #define PM_EVENT_ON		0x0000 -#define PM_EVENT_FREEZE 	0x0001 +#define PM_EVENT_FREEZE		0x0001  #define PM_EVENT_SUSPEND	0x0002  #define PM_EVENT_HIBERNATE	0x0004  #define PM_EVENT_QUIESCE	0x0008 @@ -521,8 +561,11 @@ struct dev_pm_info {  	unsigned int		async_suspend:1;  	bool			is_prepared:1;	/* Owned by the PM core */  	bool			is_suspended:1;	/* Ditto */ +	bool			is_noirq_suspended:1; +	bool			is_late_suspended:1;  	bool			ignore_children:1;  	bool			early_init:1;	/* Owned by the PM core */ +	bool			direct_complete:1;	/* Owned by the PM core */  	spinlock_t		lock;  #ifdef CONFIG_PM_SLEEP  	struct list_head	entry; @@ -561,6 +604,7 @@ struct dev_pm_info {  	unsigned long		accounting_timestamp;  #endif  	struct pm_subsys_data	*subsys_data;  /* Owned by the subsystem. */ +	void (*set_latency_tolerance)(struct device *, s32);  	struct dev_pm_qos	*qos;  }; @@ -591,11 +635,11 @@ struct dev_pm_domain {   * message is implicit:   *   * ON		Driver starts working again, responding to hardware events - * 		and software requests.  The hardware may have gone through - * 		a power-off reset, or it may have maintained state from the - * 		previous suspend() which the driver will rely on while - * 		resuming.  On most platforms, there are no restrictions on - * 		availability of resources like clocks during resume(). + *		and software requests.  The hardware may have gone through + *		a power-off reset, or it may have maintained state from the + *		previous suspend() which the driver will rely on while + *		resuming.  On most platforms, there are no restrictions on + *		availability of resources like clocks during resume().   *   * Other transitions are triggered by messages sent using suspend().  All   * these transitions quiesce the driver, so that I/O queues are inactive. @@ -605,21 +649,21 @@ struct dev_pm_domain {   * differ according to the message:   *   * SUSPEND	Quiesce, enter a low power device state appropriate for - * 		the upcoming system state (such as PCI_D3hot), and enable - * 		wakeup events as appropriate. + *		the upcoming system state (such as PCI_D3hot), and enable + *		wakeup events as appropriate.   *   * HIBERNATE	Enter a low power device state appropriate for the hibernation - * 		state (eg. ACPI S4) and enable wakeup events as appropriate. + *		state (eg. ACPI S4) and enable wakeup events as appropriate.   *   * FREEZE	Quiesce operations so that a consistent image can be saved; - * 		but do NOT otherwise enter a low power device state, and do - * 		NOT emit system wakeup events. + *		but do NOT otherwise enter a low power device state, and do + *		NOT emit system wakeup events.   *   * PRETHAW	Quiesce as if for FREEZE; additionally, prepare for restoring - * 		the system from a snapshot taken after an earlier FREEZE. - * 		Some drivers will need to reset their hardware state instead - * 		of preserving it, to ensure that it's never mistaken for the - * 		state which that earlier snapshot had set up. + *		the system from a snapshot taken after an earlier FREEZE. + *		Some drivers will need to reset their hardware state instead + *		of preserving it, to ensure that it's never mistaken for the + *		state which that earlier snapshot had set up.   *   * A minimally power-aware driver treats all messages as SUSPEND, fully   * reinitializes its device during resume() -- whether or not it was reset @@ -696,14 +740,26 @@ static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void  {  } -#define pm_generic_prepare	NULL -#define pm_generic_suspend	NULL -#define pm_generic_resume	NULL -#define pm_generic_freeze	NULL -#define pm_generic_thaw		NULL -#define pm_generic_restore	NULL -#define pm_generic_poweroff	NULL -#define pm_generic_complete	NULL +#define pm_generic_prepare		NULL +#define pm_generic_suspend_late		NULL +#define pm_generic_suspend_noirq	NULL +#define pm_generic_suspend		NULL +#define pm_generic_resume_early		NULL +#define pm_generic_resume_noirq		NULL +#define pm_generic_resume		NULL +#define pm_generic_freeze_noirq		NULL +#define pm_generic_freeze_late		NULL +#define pm_generic_freeze		NULL +#define pm_generic_thaw_noirq		NULL +#define pm_generic_thaw_early		NULL +#define pm_generic_thaw			NULL +#define pm_generic_restore_noirq	NULL +#define pm_generic_restore_early	NULL +#define pm_generic_restore		NULL +#define pm_generic_poweroff_noirq	NULL +#define pm_generic_poweroff_late	NULL +#define pm_generic_poweroff		NULL +#define pm_generic_complete		NULL  #endif /* !CONFIG_PM_SLEEP */  /* How to reorder dpm_list after device_move() */  | 
