summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/acpi/acpi_bus.h3
-rw-r--r--include/linux/acpi.h6
-rw-r--r--include/linux/clk-provider.h31
-rw-r--r--include/linux/cpuidle.h7
-rw-r--r--include/linux/pm.h36
-rw-r--r--include/linux/pm_runtime.h6
-rw-r--r--include/linux/suspend.h7
7 files changed, 82 insertions, 14 deletions
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 84a2e29a2314..7417a16c8d86 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -261,7 +261,8 @@ struct acpi_device_power_flags {
u32 inrush_current:1; /* Serialize Dx->D0 */
u32 power_removed:1; /* Optimize Dx->D0 */
u32 ignore_parent:1; /* Power is independent of parent power state */
- u32 reserved:27;
+ u32 dsw_present:1; /* _DSW present? */
+ u32 reserved:26;
};
struct acpi_device_power_state {
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a8f2cd66c8b..4c007262e891 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -554,14 +554,20 @@ static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
int acpi_dev_suspend_late(struct device *dev);
int acpi_dev_resume_early(struct device *dev);
int acpi_subsys_prepare(struct device *dev);
+void acpi_subsys_complete(struct device *dev);
int acpi_subsys_suspend_late(struct device *dev);
int acpi_subsys_resume_early(struct device *dev);
+int acpi_subsys_suspend(struct device *dev);
+int acpi_subsys_freeze(struct device *dev);
#else
static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
+static inline void acpi_subsys_complete(struct device *dev) {}
static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; }
static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
+static inline int acpi_subsys_suspend(struct device *dev) { return 0; }
+static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
#endif
#if defined(CONFIG_ACPI) && defined(CONFIG_PM)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 511917416fb0..fb4eca6907cd 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -413,6 +413,37 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
+/**
+ * struct clk_fractional_divider - adjustable fractional divider clock
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ * @reg: register containing the divider
+ * @mshift: shift to the numerator bit field
+ * @mwidth: width of the numerator bit field
+ * @nshift: shift to the denominator bit field
+ * @nwidth: width of the denominator bit field
+ * @lock: register lock
+ *
+ * Clock with adjustable fractional divider affecting its output frequency.
+ */
+
+struct clk_fractional_divider {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 mshift;
+ u32 mmask;
+ u8 nshift;
+ u32 nmask;
+ u8 flags;
+ spinlock_t *lock;
+};
+
+extern const struct clk_ops clk_fractional_divider_ops;
+struct clk *clk_register_fractional_divider(struct device *dev,
+ const char *name, const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
+ u8 clk_divider_flags, spinlock_t *lock);
+
/***
* struct clk_composite - aggregate clock of mux, divider and gate clocks
*
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index b0238cba440b..c51a436135c4 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -120,8 +120,6 @@ struct cpuidle_driver {
#ifdef CONFIG_CPU_IDLE
extern void disable_cpuidle(void);
-extern int cpuidle_enabled(struct cpuidle_driver *drv,
- struct cpuidle_device *dev);
extern int cpuidle_select(struct cpuidle_driver *drv,
struct cpuidle_device *dev);
extern int cpuidle_enter(struct cpuidle_driver *drv,
@@ -145,13 +143,11 @@ extern void cpuidle_resume(void);
extern int cpuidle_enable_device(struct cpuidle_device *dev);
extern void cpuidle_disable_device(struct cpuidle_device *dev);
extern int cpuidle_play_dead(void);
+extern void cpuidle_use_deepest_state(bool enable);
extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
#else
static inline void disable_cpuidle(void) { }
-static inline int cpuidle_enabled(struct cpuidle_driver *drv,
- struct cpuidle_device *dev)
-{return -ENODEV; }
static inline int cpuidle_select(struct cpuidle_driver *drv,
struct cpuidle_device *dev)
{return -ENODEV; }
@@ -180,6 +176,7 @@ static inline int cpuidle_enable_device(struct cpuidle_device *dev)
{return -ENODEV; }
static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
static inline int cpuidle_play_dead(void) {return -ENODEV; }
+static inline void cpuidle_use_deepest_state(bool enable) {}
static inline struct cpuidle_driver *cpuidle_get_cpu_driver(
struct cpuidle_device *dev) {return NULL; }
#endif
diff --git a/include/linux/pm.h b/include/linux/pm.h
index d915d0345fa1..72c0fe098a27 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
@@ -546,6 +565,7 @@ struct dev_pm_info {
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;
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 2a5897a4afbc..43fd6716f662 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -101,6 +101,11 @@ static inline bool pm_runtime_status_suspended(struct device *dev)
return dev->power.runtime_status == RPM_SUSPENDED;
}
+static inline bool pm_runtime_suspended_if_enabled(struct device *dev)
+{
+ return pm_runtime_status_suspended(dev) && dev->power.disable_depth == 1;
+}
+
static inline bool pm_runtime_enabled(struct device *dev)
{
return !dev->power.disable_depth;
@@ -150,6 +155,7 @@ static inline void device_set_run_wake(struct device *dev, bool enable) {}
static inline bool pm_runtime_suspended(struct device *dev) { return false; }
static inline bool pm_runtime_active(struct device *dev) { return true; }
static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
+static inline bool pm_runtime_suspended_if_enabled(struct device *dev) { return false; }
static inline bool pm_runtime_enabled(struct device *dev) { return false; }
static inline void pm_runtime_no_callbacks(struct device *dev) {}
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index f73cabf59012..91d66fd8dce1 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -187,6 +187,11 @@ struct platform_suspend_ops {
void (*recover)(void);
};
+struct platform_freeze_ops {
+ int (*begin)(void);
+ void (*end)(void);
+};
+
#ifdef CONFIG_SUSPEND
/**
* suspend_set_ops - set platform dependent suspend operations
@@ -194,6 +199,7 @@ struct platform_suspend_ops {
*/
extern void suspend_set_ops(const struct platform_suspend_ops *ops);
extern int suspend_valid_only_mem(suspend_state_t state);
+extern void freeze_set_ops(const struct platform_freeze_ops *ops);
extern void freeze_wake(void);
/**
@@ -220,6 +226,7 @@ extern int pm_suspend(suspend_state_t state);
static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
+static inline void freeze_set_ops(const struct platform_freeze_ops *ops) {}
static inline void freeze_wake(void) {}
#endif /* !CONFIG_SUSPEND */