regulator: Add support for RICOH PMIC RC5T583 regulator
[linux-2.6.git] / include / linux / pm.h
index 1d4e2d2..f7c84c9 100644 (file)
 #define _LINUX_PM_H
 
 #include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
 
 /*
  * Callbacks for platform drivers to implement.
@@ -36,6 +41,12 @@ extern void (*pm_power_off_prepare)(void);
 
 struct device;
 
+#ifdef CONFIG_PM
+extern const char power_group_name[];          /* = "power" */
+#else
+#define power_group_name       NULL
+#endif
+
 typedef struct pm_message {
        int event;
 } pm_message_t;
@@ -165,6 +176,29 @@ typedef struct pm_message {
  * It is allowed to unregister devices while the above callbacks are being
  * executed.  However, it is not allowed to unregister a device from within any
  * of its own callbacks.
+ *
+ * There also are the following callbacks related to run-time power management
+ * of devices:
+ *
+ * @runtime_suspend: Prepare the device for a condition in which it won't be
+ *     able to communicate with the CPU(s) and RAM due to power management.
+ *     This need not mean that the device should be put into a low power state.
+ *     For example, if the device is behind a link which is about to be turned
+ *     off, the device may remain at full power.  If the device does go to low
+ *     power and is capable of generating run-time wake-up events, remote
+ *     wake-up (i.e., a hardware mechanism allowing the device to request a
+ *     change of its power state via a wake-up event, such as PCI PME) should
+ *     be enabled for it.
+ *
+ * @runtime_resume: Put the device into the fully active state in response to a
+ *     wake-up event generated by hardware or at the request of software.  If
+ *     necessary, put the device into the full power state and restore its
+ *     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.
  */
 
 struct dev_pm_ops {
@@ -182,8 +216,64 @@ struct dev_pm_ops {
        int (*thaw_noirq)(struct device *dev);
        int (*poweroff_noirq)(struct device *dev);
        int (*restore_noirq)(struct device *dev);
+       int (*runtime_suspend)(struct device *dev);
+       int (*runtime_resume)(struct device *dev);
+       int (*runtime_idle)(struct device *dev);
 };
 
+#ifdef CONFIG_PM_SLEEP
+#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
+       .suspend = suspend_fn, \
+       .resume = resume_fn, \
+       .freeze = suspend_fn, \
+       .thaw = resume_fn, \
+       .poweroff = suspend_fn, \
+       .restore = resume_fn,
+#else
+#define SET_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, \
+       .runtime_resume = resume_fn, \
+       .runtime_idle = idle_fn,
+#else
+#define SET_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.
+ */
+#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
+const struct dev_pm_ops name = { \
+       SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
+}
+
+/*
+ * Use this for defining a set of PM operations to be used in all situations
+ * (sustem suspend, hibernation or runtime PM).
+ */
+#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
+const struct dev_pm_ops name = { \
+       SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
+       SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
+}
+
+/*
+ * Use this for subsystems (bus types, device types, device classes) that don't
+ * need any special suspend/resume handling in addition to invoking the PM
+ * callbacks provided by device drivers supporting both the system sleep PM and
+ * runtime PM, make the pm member point to generic_subsys_pm_ops.
+ */
+#ifdef CONFIG_PM
+extern struct dev_pm_ops generic_subsys_pm_ops;
+#define GENERIC_SUBSYS_PM_OPS  (&generic_subsys_pm_ops)
+#else
+#define GENERIC_SUBSYS_PM_OPS  NULL
+#endif
+
 /**
  * PM_EVENT_ messages
  *
@@ -277,52 +367,113 @@ struct dev_pm_ops {
                                        { .event = PM_EVENT_AUTO_RESUME, })
 
 /**
- * Device power management states
+ * Device run-time power management status.
+ *
+ * These status labels are used internally by the PM core to indicate the
+ * current status of a device with respect to the PM core operations.  They do
+ * not reflect the actual power state of the device or its status as seen by the
+ * driver.
+ *
+ * RPM_ACTIVE          Device is fully operational.  Indicates that the device
+ *                     bus type's ->runtime_resume() callback has completed
+ *                     successfully.
+ *
+ * RPM_SUSPENDED       Device bus type's ->runtime_suspend() callback has
+ *                     completed successfully.  The device is regarded as
+ *                     suspended.
  *
- * These state labels are used internally by the PM core to indicate the current
- * status of a device with respect to the PM core operations.
+ * RPM_RESUMING                Device bus type's ->runtime_resume() callback is being
+ *                     executed.
  *
- * DPM_ON              Device is regarded as operational.  Set this way
- *                     initially and when ->complete() is about to be called.
- *                     Also set when ->prepare() fails.
+ * RPM_SUSPENDING      Device bus type's ->runtime_suspend() callback is being
+ *                     executed.
+ */
+
+enum rpm_status {
+       RPM_ACTIVE = 0,
+       RPM_RESUMING,
+       RPM_SUSPENDED,
+       RPM_SUSPENDING,
+};
+
+/**
+ * Device run-time power management request types.
  *
- * DPM_PREPARING       Device is going to be prepared for a PM transition.  Set
- *                     when ->prepare() is about to be called.
+ * RPM_REQ_NONE                Do nothing.
  *
- * DPM_RESUMING                Device is going to be resumed.  Set when ->resume(),
- *                     ->thaw(), or ->restore() is about to be called.
+ * RPM_REQ_IDLE                Run the device bus type's ->runtime_idle() callback
  *
- * DPM_SUSPENDING      Device has been prepared for a power transition.  Set
- *                     when ->prepare() has just succeeded.
+ * RPM_REQ_SUSPEND     Run the device bus type's ->runtime_suspend() callback
  *
- * DPM_OFF             Device is regarded as inactive.  Set immediately after
- *                     ->suspend(), ->freeze(), or ->poweroff() has succeeded.
- *                     Also set when ->resume()_noirq, ->thaw_noirq(), or
- *                     ->restore_noirq() is about to be called.
+ * RPM_REQ_AUTOSUSPEND Same as RPM_REQ_SUSPEND, but not until the device has
+ *                     been inactive for as long as power.autosuspend_delay
  *
- * DPM_OFF_IRQ         Device is in a "deep sleep".  Set immediately after
- *                     ->suspend_noirq(), ->freeze_noirq(), or
- *                     ->poweroff_noirq() has just succeeded.
+ * RPM_REQ_RESUME      Run the device bus type's ->runtime_resume() callback
  */
 
-enum dpm_state {
-       DPM_INVALID,
-       DPM_ON,
-       DPM_PREPARING,
-       DPM_RESUMING,
-       DPM_SUSPENDING,
-       DPM_OFF,
-       DPM_OFF_IRQ,
+enum rpm_request {
+       RPM_REQ_NONE = 0,
+       RPM_REQ_IDLE,
+       RPM_REQ_SUSPEND,
+       RPM_REQ_AUTOSUSPEND,
+       RPM_REQ_RESUME,
 };
 
+struct wakeup_source;
+
 struct dev_pm_info {
        pm_message_t            power_state;
-       unsigned                can_wakeup:1;
-       unsigned                should_wakeup:1;
-       enum dpm_state          status;         /* Owned by the PM core */
-#ifdef CONFIG_PM_SLEEP
+       unsigned int            can_wakeup:1;
+       unsigned int            async_suspend:1;
+       bool                    is_prepared:1;  /* Owned by the PM core */
+       bool                    is_suspended:1; /* Ditto */
+       spinlock_t              lock;
+#ifdef CONFIG_PM_SLEEP
        struct list_head        entry;
+       struct completion       completion;
+       struct wakeup_source    *wakeup;
+#else
+       unsigned int            should_wakeup:1;
+#endif
+#ifdef CONFIG_PM_RUNTIME
+       struct timer_list       suspend_timer;
+       unsigned long           timer_expires;
+       struct work_struct      work;
+       wait_queue_head_t       wait_queue;
+       atomic_t                usage_count;
+       atomic_t                child_count;
+       unsigned int            disable_depth:3;
+       unsigned int            ignore_children:1;
+       unsigned int            idle_notification:1;
+       unsigned int            request_pending:1;
+       unsigned int            deferred_resume:1;
+       unsigned int            run_wake:1;
+       unsigned int            runtime_auto:1;
+       unsigned int            no_callbacks:1;
+       unsigned int            irq_safe:1;
+       unsigned int            use_autosuspend:1;
+       unsigned int            timer_autosuspends:1;
+       enum rpm_request        request;
+       enum rpm_status         runtime_status;
+       int                     runtime_error;
+       int                     autosuspend_delay;
+       unsigned long           last_busy;
+       unsigned long           active_jiffies;
+       unsigned long           suspended_jiffies;
+       unsigned long           accounting_timestamp;
 #endif
+       void                    *subsys_data;  /* Owned by the subsystem. */
+};
+
+extern void update_pm_runtime_accounting(struct device *dev);
+
+/*
+ * Power domains provide callbacks that are executed during system suspend,
+ * hibernation, system resume and during runtime PM transitions along with
+ * subsystem-level and driver-level callbacks.
+ */
+struct dev_pm_domain {
+       struct dev_pm_ops       ops;
 };
 
 /*
@@ -381,15 +532,16 @@ struct dev_pm_info {
 
 #ifdef CONFIG_PM_SLEEP
 extern void device_pm_lock(void);
-extern int sysdev_resume(void);
-extern void device_power_up(pm_message_t state);
-extern void device_resume(pm_message_t state);
+extern void dpm_resume_noirq(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 sysdev_suspend(pm_message_t state);
-extern int device_power_down(pm_message_t state);
-extern int device_suspend(pm_message_t state);
-extern int device_prepare_suspend(pm_message_t state);
+extern int dpm_suspend_noirq(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);
 
 extern void __suspend_report_result(const char *function, void *fn, int ret);
 
@@ -398,18 +550,48 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
                __suspend_report_result(__func__, fn, ret);             \
        } while (0)
 
+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_noirq(struct device *dev);
+extern int pm_generic_suspend(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(struct device *dev);
+extern int pm_generic_thaw_noirq(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(struct device *dev);
+extern int pm_generic_poweroff_noirq(struct device *dev);
+extern int pm_generic_poweroff(struct device *dev);
+extern void pm_generic_complete(struct device *dev);
+
 #else /* !CONFIG_PM_SLEEP */
 
 #define device_pm_lock() do {} while (0)
 #define device_pm_unlock() do {} while (0)
 
-static inline int device_suspend(pm_message_t state)
+static inline int dpm_suspend_start(pm_message_t state)
 {
        return 0;
 }
 
 #define suspend_report_result(fn, ret)         do {} while (0)
 
+static inline int device_pm_wait_for_dev(struct device *a, struct device *b)
+{
+       return 0;
+}
+
+#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
 #endif /* !CONFIG_PM_SLEEP */
 
 /* How to reorder dpm_list after device_move() */
@@ -420,13 +602,4 @@ enum dpm_order {
        DPM_ORDER_DEV_LAST,
 };
 
-/*
- * Global Power Management flags
- * Used to keep APM and ACPI from both being active
- */
-extern unsigned int    pm_flags;
-
-#define PM_APM 1
-#define PM_ACPI        2
-
 #endif /* _LINUX_PM_H */