From 068765ba7987e73d4381edfe47b70aa121c7155c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 1 Sep 2014 13:47:49 +0200 Subject: PM / sleep: Mechanism for aborting system suspends unconditionally It sometimes may be necessary to abort a system suspend in progress or wake up the system from suspend-to-idle even if the pm_wakeup_event()/pm_stay_awake() mechanism is not enabled. For this purpose, introduce a new global variable pm_abort_suspend and make pm_wakeup_pending() check its value. Also add routines for manipulating that variable. Signed-off-by: Rafael J. Wysocki --- include/linux/suspend.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 519064e0c943..06a9910827c2 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -371,6 +371,8 @@ extern int unregister_pm_notifier(struct notifier_block *nb); extern bool events_check_enabled; extern bool pm_wakeup_pending(void); +extern void pm_system_wakeup(void); +extern void pm_wakeup_clear(void); extern bool pm_get_wakeup_count(unsigned int *count, bool block); extern bool pm_save_wakeup_count(unsigned int count); extern void pm_wakep_autosleep_enabled(bool set); @@ -418,6 +420,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) #define pm_notifier(fn, pri) do { (void)(fn); } while (0) static inline bool pm_wakeup_pending(void) { return false; } +static inline void pm_system_wakeup(void) {} +static inline void pm_wakeup_clear(void) {} static inline void lock_system_sleep(void) {} static inline void unlock_system_sleep(void) {} -- cgit v1.2.3 From cab303be91dc47942bc25de33dc1140123540800 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 28 Aug 2014 11:44:31 +0200 Subject: genirq: Add sanity checks for PM options on shared interrupt lines Account the IRQF_NO_SUSPEND and IRQF_RESUME_EARLY actions on shared interrupt lines and yell loudly if there is a mismatch. Signed-off-by: Thomas Gleixner Signed-off-by: Rafael J. Wysocki --- include/linux/irqdesc.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 472c021a2d4f..cb1a31e448ae 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -36,6 +36,11 @@ struct irq_desc; * @threads_oneshot: bitfield to handle shared oneshot threads * @threads_active: number of irqaction threads currently running * @wait_for_threads: wait queue for sync_irq to wait for threaded handlers + * @nr_actions: number of installed actions on this descriptor + * @no_suspend_depth: number of irqactions on a irq descriptor with + * IRQF_NO_SUSPEND set + * @force_resume_depth: number of irqactions on a irq descriptor with + * IRQF_FORCE_RESUME set * @dir: /proc/irq/ procfs entry * @name: flow handler name for /proc/interrupts output */ @@ -68,6 +73,11 @@ struct irq_desc { unsigned long threads_oneshot; atomic_t threads_active; wait_queue_head_t wait_for_threads; +#ifdef CONFIG_PM_SLEEP + unsigned int nr_actions; + unsigned int no_suspend_depth; + unsigned int force_resume_depth; +#endif #ifdef CONFIG_PROC_FS struct proc_dir_entry *dir; #endif -- cgit v1.2.3 From b76f16748fa61801b1a1fd3ffb6f25ee228a35e0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 29 Aug 2014 13:54:09 +0200 Subject: genirq: Mark wakeup sources as armed on suspend This allows us to utilize this information in the irq_may_run() check without adding another conditional to the fast path. Signed-off-by: Thomas Gleixner Signed-off-by: Rafael J. Wysocki --- include/linux/irq.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 62af59242ddc..03f48d936f66 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -173,6 +173,7 @@ struct irq_data { * IRQD_IRQ_DISABLED - Disabled state of the interrupt * IRQD_IRQ_MASKED - Masked state of the interrupt * IRQD_IRQ_INPROGRESS - In progress state of the interrupt + * IRQD_WAKEUP_ARMED - Wakeup mode armed */ enum { IRQD_TRIGGER_MASK = 0xf, @@ -186,6 +187,7 @@ enum { IRQD_IRQ_DISABLED = (1 << 16), IRQD_IRQ_MASKED = (1 << 17), IRQD_IRQ_INPROGRESS = (1 << 18), + IRQD_WAKEUP_ARMED = (1 << 19), }; static inline bool irqd_is_setaffinity_pending(struct irq_data *d) @@ -257,6 +259,12 @@ static inline bool irqd_irq_inprogress(struct irq_data *d) return d->state_use_accessors & IRQD_IRQ_INPROGRESS; } +static inline bool irqd_is_wakeup_armed(struct irq_data *d) +{ + return d->state_use_accessors & IRQD_WAKEUP_ARMED; +} + + /* * Functions for chained handlers which can be enabled/disabled by the * standard disable_irq/enable_irq calls. Must be called with -- cgit v1.2.3 From 9ce7a25849e80cfb264f4995f832b932c1987e1a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 29 Aug 2014 14:00:16 +0200 Subject: genirq: Simplify wakeup mechanism Currently we suspend wakeup interrupts by lazy disabling them and check later whether the interrupt has fired, but that's not sufficient for suspend to idle as there is no way to check that once we transitioned into the CPU idle state. So we change the mechanism in the following way: 1) Leave the wakeup interrupts enabled across suspend 2) Add a check to irq_may_run() which is called at the beginning of each flow handler whether the interrupt is an armed wakeup source. This check is basically free as it just extends the existing check for IRQD_IRQ_INPROGRESS. So no new conditional in the hot path. If the IRQD_WAKEUP_ARMED flag is set, then the interrupt is disabled, marked as pending/suspended and the pm core is notified about the wakeup event. Signed-off-by: Thomas Gleixner [ rjw: syscore.c and put irq_pm_check_wakeup() into pm.c ] Signed-off-by: Rafael J. Wysocki --- include/linux/interrupt.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 698ad053d064..69517a24bc50 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -193,11 +193,6 @@ extern void irq_wake_thread(unsigned int irq, void *dev_id); /* The following three functions are for the core kernel use only. */ extern void suspend_device_irqs(void); extern void resume_device_irqs(void); -#ifdef CONFIG_PM_SLEEP -extern int check_wakeup_irqs(void); -#else -static inline int check_wakeup_irqs(void) { return 0; } -#endif /** * struct irq_affinity_notify - context for notification of IRQ affinity changes -- cgit v1.2.3 From 55e15c949fd05d247a889df0ed0177a676fec665 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:17 +0200 Subject: PM / domains: Remove the pm_genpd_add|remove_callbacks APIs There are no users of these APIs. To simplify the generic power domain let's remove them. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index ebc4c76ffb73..9ae2b9e88d61 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -151,10 +151,6 @@ extern int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name); extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); -extern int pm_genpd_add_callbacks(struct device *dev, - struct gpd_dev_ops *ops, - struct gpd_timing_data *td); -extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td); extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); extern int pm_genpd_name_attach_cpuidle(const char *name, int state); extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd); @@ -217,16 +213,6 @@ static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, { return -ENOSYS; } -static inline int pm_genpd_add_callbacks(struct device *dev, - struct gpd_dev_ops *ops, - struct gpd_timing_data *td) -{ - return -ENOSYS; -} -static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) -{ - return -ENOSYS; -} static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st) { return -ENOSYS; @@ -281,11 +267,6 @@ static inline int pm_genpd_name_add_device(const char *domain_name, return __pm_genpd_name_add_device(domain_name, dev, NULL); } -static inline int pm_genpd_remove_callbacks(struct device *dev) -{ - return __pm_genpd_remove_callbacks(dev, true); -} - #ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd); extern void pm_genpd_poweroff_unused(void); -- cgit v1.2.3 From 67da6d4bf43c4208433ef8f3ee487401b4dc9c74 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:18 +0200 Subject: PM / domains: Ignore callbacks for subsys generic_pm_domain_data In a step of simplifying the generic power domain let's move away from using these callbacks. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 9ae2b9e88d61..436ea149d40c 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -108,7 +108,6 @@ struct gpd_timing_data { struct generic_pm_domain_data { struct pm_domain_data base; - struct gpd_dev_ops ops; struct gpd_timing_data td; struct notifier_block nb; struct mutex lock; -- cgit v1.2.3 From 1e0407ca54d28db8e5f02e437ff21cc6416c0be8 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:19 +0200 Subject: PM / domains: Remove system PM callbacks from gpd_dev_ops There no users of these callbacks, let's simplify the generic power domain by removing them. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 436ea149d40c..b6343d4b9b04 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -35,14 +35,6 @@ struct gpd_dev_ops { int (*stop)(struct device *dev); int (*save_state)(struct device *dev); int (*restore_state)(struct device *dev); - int (*suspend)(struct device *dev); - int (*suspend_late)(struct device *dev); - int (*resume_early)(struct device *dev); - int (*resume)(struct device *dev); - int (*freeze)(struct device *dev); - int (*freeze_late)(struct device *dev); - int (*thaw_early)(struct device *dev); - int (*thaw)(struct device *dev); bool (*active_wakeup)(struct device *dev); }; -- cgit v1.2.3 From c5d79ec2a5715489cff16a0d1cf4fa9108a5509e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:22 +0200 Subject: PM / domains: Remove dev_irq_safe from genpd config The genpd dev_irq_safe configuration somewhat overlaps with the runtime PM pm_runtime_irq_safe() option. Also, currently genpd don't have a good way to deal with these device. So, until we figured out if and how to support this in genpd, let's remove the option to configure it. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index b6343d4b9b04..360c94ceeebb 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -63,7 +63,6 @@ struct generic_pm_domain { unsigned int suspended_count; /* System suspend device counter */ unsigned int prepared_count; /* Suspend counter of prepared devices */ bool suspend_power_off; /* Power status before system suspend */ - bool dev_irq_safe; /* Device callbacks are IRQ-safe */ int (*power_off)(struct generic_pm_domain *domain); s64 power_off_latency_ns; int (*power_on)(struct generic_pm_domain *domain); -- cgit v1.2.3 From d47e6464ae6c96735d4706f5cb0537fe717b6b00 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:24 +0200 Subject: PM / domains: Remove pm_genpd_syscore_switch() API The pm_genpd_syscore_poweroff() API and pm_genpd_syscore_poweron() API makes the pm_genpd_syscore_switch() API redundant. Moreover, since there are no active users, let's just remove it. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 360c94ceeebb..3997af691600 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -266,19 +266,11 @@ static inline void pm_genpd_poweroff_unused(void) {} #endif #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP -extern void pm_genpd_syscore_switch(struct device *dev, bool suspend); +extern void pm_genpd_syscore_poweroff(struct device *dev); +extern void pm_genpd_syscore_poweron(struct device *dev); #else -static inline void pm_genpd_syscore_switch(struct device *dev, bool suspend) {} +static inline void pm_genpd_syscore_poweroff(struct device *dev) {} +static inline void pm_genpd_syscore_poweron(struct device *dev) {} #endif -static inline void pm_genpd_syscore_poweroff(struct device *dev) -{ - pm_genpd_syscore_switch(dev, true); -} - -static inline void pm_genpd_syscore_poweron(struct device *dev) -{ - pm_genpd_syscore_switch(dev, false); -} - #endif /* _LINUX_PM_DOMAIN_H */ -- cgit v1.2.3 From d971f0b0eaaf3f2086bf21bbd64f7ea7e2f28459 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:25 +0200 Subject: PM / domains: Remove genpd_queue_power_off_work() API There are no active users of this API. Let's remove it and if future needs shows up we could consider to have a get/put API instead. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 3997af691600..c19c90b839b8 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -258,10 +258,8 @@ static inline int pm_genpd_name_add_device(const char *domain_name, } #ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME -extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd); extern void pm_genpd_poweroff_unused(void); #else -static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {} static inline void pm_genpd_poweroff_unused(void) {} #endif -- cgit v1.2.3 From 0f574d4c3a7a325cbbef28ee738dedca9851e957 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:30 +0200 Subject: PM / domains: Remove default_stop_ok() API There are currently no need to export default_stop_ok() as an API, instead let's keep it local to the PM domain governor. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index c19c90b839b8..3b59f296e6ec 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -151,8 +151,6 @@ extern void pm_genpd_init(struct generic_pm_domain *genpd, extern int pm_genpd_poweron(struct generic_pm_domain *genpd); extern int pm_genpd_name_poweron(const char *domain_name); -extern bool default_stop_ok(struct device *dev); - extern struct dev_power_governor pm_domain_always_on_gov; #else @@ -231,10 +229,6 @@ static inline int pm_genpd_name_poweron(const char *domain_name) { return -ENOSYS; } -static inline bool default_stop_ok(struct device *dev) -{ - return false; -} #define simple_qos_governor NULL #define pm_domain_always_on_gov NULL #endif -- cgit v1.2.3 From ae3c511c2d72161b11e93866203b59a3a37dfac7 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 3 Sep 2014 12:52:31 +0200 Subject: PM / domains: Keep declaration of dev_power_governors together This is a pure code cleanup in the header file for the PM domain. No functional change. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 3b59f296e6ec..aa03586c94a2 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -117,8 +117,6 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) return to_gpd_data(dev->power.subsys_data->domain_data); } -extern struct dev_power_governor simple_qos_governor; - extern struct generic_pm_domain *dev_to_genpd(struct device *dev); extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, @@ -151,6 +149,7 @@ extern void pm_genpd_init(struct generic_pm_domain *genpd, extern int pm_genpd_poweron(struct generic_pm_domain *genpd); extern int pm_genpd_name_poweron(const char *domain_name); +extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; #else -- cgit v1.2.3 From 413fffc3a1db7f270afdf1ecb35c1edc013acc68 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 28 Aug 2014 11:22:23 +0530 Subject: cpufreq: Add support for per-policy driver data Drivers supporting multiple clusters or multiple 'struct cpufreq_policy' instances may need to keep per-policy data. If the core doesn't provide support for that, they might do it in the most unoptimized way: 'per-cpu' data. This patch adds another field in struct cpufreq_policy: 'driver_data'. It isn't accessed by core and is for driver's internal use only. Tested-by: Stephen Boyd Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 7d1955afa62c..138336b6bb04 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -112,6 +112,9 @@ struct cpufreq_policy { spinlock_t transition_lock; wait_queue_head_t transition_wait; struct task_struct *transition_task; /* Task which is doing the transition */ + + /* For cpufreq driver's internal use */ + void *driver_data; }; /* Only for ACPI */ -- cgit v1.2.3 From c3099a5294f2c7266234e8ea35cbffc20a41aa9a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 19 Sep 2014 20:27:34 +0200 Subject: PM / Domains: Add a detach callback to the struct dev_pm_domain The intent of this callback is to simplify detachment of devices from their PM domains. Further patches will show the benefit. Signed-off-by: Ulf Hansson Reviewed-by: Dmitry Torokhov Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pm.h b/include/linux/pm.h index 72c0fe098a27..1022ba1eb4de 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -619,6 +619,7 @@ extern int dev_pm_put_subsys_data(struct device *dev); */ struct dev_pm_domain { struct dev_pm_ops ops; + void (*detach)(struct device *dev, bool power_off); }; /* -- cgit v1.2.3 From aa42240ab2544a8bcb2efb400193826f57f3175e Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Fri, 19 Sep 2014 20:27:36 +0200 Subject: PM / Domains: Add generic OF-based PM domain look-up This patch introduces generic code to perform PM domain look-up using device tree and automatically bind devices to their PM domains. Generic device tree bindings are introduced to specify PM domains of devices in their device tree nodes. Backwards compatibility with legacy Samsung-specific PM domain bindings is provided, but for now the new code is not compiled when CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This will change as soon as the Exynos PM domain code gets converted to use the generic framework in further patch. This patch was originally submitted by Tomasz Figa when he was employed by Samsung. Link: http://marc.info/?l=linux-pm&m=139955349702152&w=2 Signed-off-by: Ulf Hansson Acked-by: Rob Herring Tested-by: Philipp Zabel Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index aa03586c94a2..292079d8da6b 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -264,4 +264,56 @@ static inline void pm_genpd_syscore_poweroff(struct device *dev) {} static inline void pm_genpd_syscore_poweron(struct device *dev) {} #endif +/* OF PM domain providers */ +struct of_device_id; + +struct genpd_onecell_data { + struct generic_pm_domain **domains; + unsigned int num_domains; +}; + +typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args, + void *data); + +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate, + void *data); +void of_genpd_del_provider(struct device_node *np); + +struct generic_pm_domain *__of_genpd_xlate_simple( + struct of_phandle_args *genpdspec, + void *data); +struct generic_pm_domain *__of_genpd_xlate_onecell( + struct of_phandle_args *genpdspec, + void *data); + +int genpd_dev_pm_attach(struct device *dev); +#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */ +static inline int __of_genpd_add_provider(struct device_node *np, + genpd_xlate_t xlate, void *data) +{ + return 0; +} +static inline void of_genpd_del_provider(struct device_node *np) {} + +#define __of_genpd_xlate_simple NULL +#define __of_genpd_xlate_onecell NULL + +static inline int genpd_dev_pm_attach(struct device *dev) +{ + return -ENODEV; +} +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */ + +static inline int of_genpd_add_provider_simple(struct device_node *np, + struct generic_pm_domain *genpd) +{ + return __of_genpd_add_provider(np, __of_genpd_xlate_simple, genpd); +} +static inline int of_genpd_add_provider_onecell(struct device_node *np, + struct genpd_onecell_data *data) +{ + return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data); +} + #endif /* _LINUX_PM_DOMAIN_H */ -- cgit v1.2.3 From 46420dd73b800f87a19af13af5883855cf38cb08 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 19 Sep 2014 20:27:37 +0200 Subject: PM / Domains: Add APIs to attach/detach a PM domain for a device To maintain scalability let's add common methods to attach and detach a PM domain for a device, dev_pm_domain_attach|detach(). Typically dev_pm_domain_attach() shall be invoked from subsystem level code at the probe phase to try to attach a device to its PM domain. The reversed actions may be done a the remove phase and then by invoking dev_pm_domain_detach(). When attachment succeeds, the attach function should assign its corresponding detach function to a new ->detach() callback added in the struct dev_pm_domain. Signed-off-by: Ulf Hansson Tested-by: Philipp Zabel Reviewed-by: Kevin Hilman Reviewed-by: Dmitry Torokhov Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pm.h b/include/linux/pm.h index 1022ba1eb4de..c4cbf485a5d6 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -622,6 +622,17 @@ struct dev_pm_domain { void (*detach)(struct device *dev, bool power_off); }; +#ifdef CONFIG_PM +extern int dev_pm_domain_attach(struct device *dev, bool power_on); +extern void dev_pm_domain_detach(struct device *dev, bool power_off); +#else +static inline int dev_pm_domain_attach(struct device *dev, bool power_on) +{ + return -ENODEV; +} +static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {} +#endif + /* * The PM_EVENT_ messages are also used by drivers implementing the legacy * suspend framework, based on the ->suspend() and ->resume() callbacks common -- cgit v1.2.3 From 91d66cd27f5fd8a3bca4621a3505c9067925478d Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 19 Sep 2014 20:27:44 +0200 Subject: ACPI / PM: Convert acpi_dev_pm_detach() into a static function The ->detach() callback for the PM domain has now been fully adopted, thus there no users left of the acpi_dev_pm_detach() API. This allow us to convert it into a static function. Signed-off-by: Ulf Hansson Reviewed-by: Dmitry Torokhov Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 807cbc46d73e..b7926bb9b444 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -587,7 +587,6 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; } #if defined(CONFIG_ACPI) && defined(CONFIG_PM) struct acpi_device *acpi_dev_pm_get_node(struct device *dev); int acpi_dev_pm_attach(struct device *dev, bool power_on); -void acpi_dev_pm_detach(struct device *dev, bool power_off); #else static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev) { @@ -597,7 +596,6 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) { return -ENODEV; } -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {} #endif #ifdef CONFIG_ACPI -- cgit v1.2.3 From d79b6fe17aa279c7015a9c4ee88809dad4be9959 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 25 Sep 2014 18:28:28 +0200 Subject: PM / Domains: Add genpd attach/detach callbacks While a PM domain can enable PM runtime management of its devices' module clocks by setting genpd->dev_ops.stop = pm_clk_suspend; genpd->dev_ops.start = pm_clk_resume; this also requires registering the clocks with the pm_clk subsystem. In the legacy case, this is handled by the platform code, after attaching the device to its PM domain. When the devices are instantiated from DT, devices are attached to their PM domains by generic code, leaving no method for the platform-specific PM domain code to register their clocks. Add two callbacks, allowing a PM domain to perform platform-specific tasks when a device is attached to or detached from a PM domain. Signed-off-by: Geert Uytterhoeven Reviewed-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 292079d8da6b..9a93e622bdea 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -73,6 +73,8 @@ struct generic_pm_domain { bool cached_power_down_ok; struct device_node *of_node; /* Node in device tree */ struct gpd_cpu_data *cpu_data; + void (*attach_dev)(struct device *dev); + void (*detach_dev)(struct device *dev); }; static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) -- cgit v1.2.3 From 263c589bae9eb404df2c1e8d49ec775bb7b288d4 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 25 Sep 2014 17:49:59 +0200 Subject: PM / Domains: Remove legacy API for adding devices through DT There are no active clients of the legacy API and we now also have a better way to handle genpd DT support. So let's remove the legacy API. Signed-off-by: Ulf Hansson Acked-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 9a93e622bdea..ed4f4a79c528 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -71,7 +71,6 @@ struct generic_pm_domain { s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; bool cached_power_down_ok; - struct device_node *of_node; /* Node in device tree */ struct gpd_cpu_data *cpu_data; void (*attach_dev)(struct device *dev); void (*detach_dev)(struct device *dev); @@ -124,10 +123,6 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); -extern int __pm_genpd_of_add_device(struct device_node *genpd_node, - struct device *dev, - struct gpd_timing_data *td); - extern int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td); @@ -169,12 +164,6 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, { return -ENOSYS; } -static inline int __pm_genpd_of_add_device(struct device_node *genpd_node, - struct device *dev, - struct gpd_timing_data *td) -{ - return -ENOSYS; -} static inline int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td) @@ -240,12 +229,6 @@ static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, return __pm_genpd_add_device(genpd, dev, NULL); } -static inline int pm_genpd_of_add_device(struct device_node *genpd_node, - struct device *dev) -{ - return __pm_genpd_of_add_device(genpd_node, dev, NULL); -} - static inline int pm_genpd_name_add_device(const char *domain_name, struct device *dev) { -- cgit v1.2.3 From f48c767ce8951e30eb716b8ef69142d21aacbd1d Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 29 Sep 2014 13:58:47 +0200 Subject: PM / Domains: Move dev_pm_domain_attach|detach() to pm_domain.h The commit 46420dd73b80 (PM / Domains: Add APIs to attach/detach a PM domain for a device) started using errno values in pm.h header file. It also failed to include the header for these, thus it caused compiler errors. Instead of including the errno header to pm.h, let's move the functions to pm_domain.h, since it's a better match. Fixes: 46420dd73b80 (PM / Domains: Add APIs to attach/detach a PM domain for a device) Signed-off-by: Ulf Hansson Acked-by: Geert Uytterhoeven Acked-by: Wolfram Sang Acked-by: Mark Brown Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 11 ----------- include/linux/pm_domain.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm.h b/include/linux/pm.h index c4cbf485a5d6..1022ba1eb4de 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -622,17 +622,6 @@ struct dev_pm_domain { void (*detach)(struct device *dev, bool power_off); }; -#ifdef CONFIG_PM -extern int dev_pm_domain_attach(struct device *dev, bool power_on); -extern void dev_pm_domain_detach(struct device *dev, bool power_off); -#else -static inline int dev_pm_domain_attach(struct device *dev, bool power_on) -{ - return -ENODEV; -} -static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {} -#endif - /* * The PM_EVENT_ messages are also used by drivers implementing the legacy * suspend framework, based on the ->suspend() and ->resume() callbacks common diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index ed4f4a79c528..900474317afc 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -301,4 +301,15 @@ static inline int of_genpd_add_provider_onecell(struct device_node *np, return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data); } +#ifdef CONFIG_PM +extern int dev_pm_domain_attach(struct device *dev, bool power_on); +extern void dev_pm_domain_detach(struct device *dev, bool power_off); +#else +static inline int dev_pm_domain_attach(struct device *dev, bool power_on) +{ + return -ENODEV; +} +static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {} +#endif + #endif /* _LINUX_PM_DOMAIN_H */ -- cgit v1.2.3 From 2a8a8ce651d3a88fdf83e2ed15633c8d19292108 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Sep 2014 02:21:34 +0200 Subject: PM / sleep: Export dpm_suspend_late/noirq() and dpm_resume_early/noirq() Subsequent change sets will add platform-related operations between dpm_suspend_late() and dpm_suspend_noirq() as well as between dpm_resume_noirq() and dpm_resume_early() in suspend_enter(), so export these functions for suspend_enter() to be able to call them separately and split the invocations of dpm_suspend_end() and dpm_resume_start() in there accordingly. Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pm.h b/include/linux/pm.h index 72c0fe098a27..e1c00b7ee913 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -679,12 +679,16 @@ struct dev_pm_domain { extern void device_pm_lock(void); extern void dpm_resume_start(pm_message_t state); extern void dpm_resume_end(pm_message_t state); +extern void dpm_resume_noirq(pm_message_t state); +extern void dpm_resume_early(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_end(pm_message_t state); extern int dpm_suspend_start(pm_message_t state); +extern int dpm_suspend_noirq(pm_message_t state); +extern int dpm_suspend_late(pm_message_t state); extern int dpm_suspend(pm_message_t state); extern int dpm_prepare(pm_message_t state); -- cgit v1.2.3 From a8d46b9e4e487301affe84fa53de40b890898604 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Sep 2014 02:29:01 +0200 Subject: ACPI / sleep: Rework the handling of ACPI GPE wakeup from suspend-to-idle The ACPI GPE wakeup from suspend-to-idle is currently based on using the IRQF_NO_SUSPEND flag for the ACPI SCI, but that is problematic for a couple of reasons. First, in principle the ACPI SCI may be shared and IRQF_NO_SUSPEND does not really work well with shared interrupts. Second, it may require the ACPI subsystem to special-case the handling of device notifications depending on whether or not they are received during suspend-to-idle in some places which would lead to fragile code. Finally, it's better the handle ACPI wakeup interrupts consistently with wakeup interrupts from other sources. For this reason, remove the IRQF_NO_SUSPEND flag from the ACPI SCI and use enable_irq_wake()/disable_irq_wake() with it instead, which requires two additional platform hooks to be added to struct platform_freeze_ops. Signed-off-by: Rafael J. Wysocki --- include/linux/suspend.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 06a9910827c2..3388c1b6f7d8 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -189,6 +189,8 @@ struct platform_suspend_ops { struct platform_freeze_ops { int (*begin)(void); + int (*prepare)(void); + void (*restore)(void); void (*end)(void); }; -- cgit v1.2.3 From f39cb1797ec1094b196d3dab44a7ca6060813d38 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 2 Oct 2014 21:12:34 +0200 Subject: PM / Domains: Rename cpu_data to cpuidle_data The "cpu_data" are defined for some archs and thus conflicting with the "cpu_data" member in the struct gpd_cpu_data. This causes a compiler error for those archs. Let's fix it by rename the member to cpuidle_data. In this context it also seems appropriate to rename the struct to gpd_cpuidle_data to better reflect its use. Fixes: f48c767ce895 (PM / Domains: Move dev_pm_domain_attach|detach() to pm_domain.h) Signed-off-by: Ulf Hansson Acked-by: Geert Uytterhoeven Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- include/linux/pm_domain.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 900474317afc..73e938b7e937 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -38,7 +38,7 @@ struct gpd_dev_ops { bool (*active_wakeup)(struct device *dev); }; -struct gpd_cpu_data { +struct gpd_cpuidle_data { unsigned int saved_exit_latency; struct cpuidle_state *idle_state; }; @@ -71,7 +71,7 @@ struct generic_pm_domain { s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; bool cached_power_down_ok; - struct gpd_cpu_data *cpu_data; + struct gpd_cpuidle_data *cpuidle_data; void (*attach_dev)(struct device *dev); void (*detach_dev)(struct device *dev); }; -- cgit v1.2.3