diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-10-07 23:17:02 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-10-07 23:17:02 +0200 |
commit | c28b56b1d46b1bbb1be33c8f2632a88b0de1ef68 (patch) | |
tree | a7caddb9f58c968f6e77f36d2d398ec06983509e /include | |
parent | d727b60659a1173eb4142a5fc521ce67c28b34e1 (diff) | |
parent | cd0ea672f58d5cfdea271c45cec0c897f2b792aa (diff) |
Merge branch 'pm-domains' into pm-for-linus
* pm-domains:
PM / Domains: Split device PM domain data into base and need_restore
ARM: mach-shmobile: sh7372 sleep warning fixes
ARM: mach-shmobile: sh7372 A3SM support
ARM: mach-shmobile: sh7372 generic suspend/resume support
PM / Domains: Preliminary support for devices with power.irq_safe set
PM: Move clock-related definitions and headers to separate file
PM / Domains: Use power.sybsys_data to reduce overhead
PM: Reference counting of power.subsys_data
PM: Introduce struct pm_subsys_data
ARM / shmobile: Make A3RV be a subdomain of A4LC on SH7372
PM / Domains: Rename argument of pm_genpd_add_subdomain()
PM / Domains: Rename GPD_STATE_WAIT_PARENT to GPD_STATE_WAIT_MASTER
PM / Domains: Allow generic PM domains to have multiple masters
PM / Domains: Add "wait for parent" status for generic PM domains
PM / Domains: Make pm_genpd_poweron() always survive parent removal
PM / Domains: Do not take parent locks to modify subdomain counters
PM / Domains: Implement subdomain counters as atomic fields
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/device.h | 5 | ||||
-rw-r--r-- | include/linux/pm.h | 20 | ||||
-rw-r--r-- | include/linux/pm_clock.h | 71 | ||||
-rw-r--r-- | include/linux/pm_domain.h | 26 | ||||
-rw-r--r-- | include/linux/pm_runtime.h | 42 |
5 files changed, 114 insertions, 50 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index c20dfbfc49b..5d200ed0071 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -636,6 +636,11 @@ static inline void set_dev_node(struct device *dev, int node) } #endif +static inline struct pm_subsys_data *dev_to_psd(struct device *dev) +{ + return dev ? dev->power.subsys_data : NULL; +} + static inline unsigned int dev_get_uevent_suppress(const struct device *dev) { return dev->kobj.uevent_suppress; diff --git a/include/linux/pm.h b/include/linux/pm.h index 18de9f89349..f497ed06ee1 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -423,6 +423,22 @@ enum rpm_request { struct wakeup_source; +struct pm_domain_data { + struct list_head list_node; + struct device *dev; +}; + +struct pm_subsys_data { + spinlock_t lock; + unsigned int refcount; +#ifdef CONFIG_PM_CLK + struct list_head clock_list; +#endif +#ifdef CONFIG_PM_GENERIC_DOMAINS + struct pm_domain_data *domain_data; +#endif +}; + struct dev_pm_info { pm_message_t power_state; unsigned int can_wakeup:1; @@ -464,10 +480,12 @@ struct dev_pm_info { unsigned long suspended_jiffies; unsigned long accounting_timestamp; #endif - void *subsys_data; /* Owned by the subsystem. */ + struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ }; extern void update_pm_runtime_accounting(struct device *dev); +extern int dev_pm_get_subsys_data(struct device *dev); +extern int dev_pm_put_subsys_data(struct device *dev); /* * Power domains provide callbacks that are executed during system suspend, diff --git a/include/linux/pm_clock.h b/include/linux/pm_clock.h new file mode 100644 index 00000000000..8348866e7b0 --- /dev/null +++ b/include/linux/pm_clock.h @@ -0,0 +1,71 @@ +/* + * pm_clock.h - Definitions and headers related to device clocks. + * + * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp. + * + * This file is released under the GPLv2. + */ + +#ifndef _LINUX_PM_CLOCK_H +#define _LINUX_PM_CLOCK_H + +#include <linux/device.h> +#include <linux/notifier.h> + +struct pm_clk_notifier_block { + struct notifier_block nb; + struct dev_pm_domain *pm_domain; + char *con_ids[]; +}; + +#ifdef CONFIG_PM_CLK +static inline bool pm_clk_no_clocks(struct device *dev) +{ + return dev && dev->power.subsys_data + && list_empty(&dev->power.subsys_data->clock_list); +} + +extern void pm_clk_init(struct device *dev); +extern int pm_clk_create(struct device *dev); +extern void pm_clk_destroy(struct device *dev); +extern int pm_clk_add(struct device *dev, const char *con_id); +extern void pm_clk_remove(struct device *dev, const char *con_id); +extern int pm_clk_suspend(struct device *dev); +extern int pm_clk_resume(struct device *dev); +#else +static inline bool pm_clk_no_clocks(struct device *dev) +{ + return true; +} +static inline void pm_clk_init(struct device *dev) +{ +} +static inline int pm_clk_create(struct device *dev) +{ + return -EINVAL; +} +static inline void pm_clk_destroy(struct device *dev) +{ +} +static inline int pm_clk_add(struct device *dev, const char *con_id) +{ + return -EINVAL; +} +static inline void pm_clk_remove(struct device *dev, const char *con_id) +{ +} +#define pm_clk_suspend NULL +#define pm_clk_resume NULL +#endif + +#ifdef CONFIG_HAVE_CLK +extern void pm_clk_add_notifier(struct bus_type *bus, + struct pm_clk_notifier_block *clknb); +#else +static inline void pm_clk_add_notifier(struct bus_type *bus, + struct pm_clk_notifier_block *clknb) +{ +} +#endif + +#endif diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index f9ec1736a11..65633e5a2bc 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -13,6 +13,7 @@ enum gpd_status { GPD_STATE_ACTIVE = 0, /* PM domain is active */ + GPD_STATE_WAIT_MASTER, /* PM domain's master is being waited for */ GPD_STATE_BUSY, /* Something is happening to the PM domain */ GPD_STATE_REPEAT, /* Power off in progress, to be repeated */ GPD_STATE_POWER_OFF, /* PM domain is off */ @@ -25,15 +26,14 @@ struct dev_power_governor { struct generic_pm_domain { struct dev_pm_domain domain; /* PM domain operations */ struct list_head gpd_list_node; /* Node in the global PM domains list */ - struct list_head sd_node; /* Node in the parent's subdomain list */ - struct generic_pm_domain *parent; /* Parent PM domain */ - struct list_head sd_list; /* List of dubdomains */ + struct list_head master_links; /* Links with PM domain as a master */ + struct list_head slave_links; /* Links with PM domain as a slave */ struct list_head dev_list; /* List of devices */ struct mutex lock; struct dev_power_governor *gov; struct work_struct power_off_work; unsigned int in_progress; /* Number of devices being suspended now */ - unsigned int sd_count; /* Number of subdomains with power "on" */ + atomic_t sd_count; /* Number of subdomains with power "on" */ enum gpd_status status; /* Current state of the domain */ wait_queue_head_t status_wait_queue; struct task_struct *poweroff_task; /* Powering off task */ @@ -42,6 +42,7 @@ 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); int (*power_on)(struct generic_pm_domain *domain); int (*start_device)(struct device *dev); @@ -54,12 +55,23 @@ static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) return container_of(pd, struct generic_pm_domain, domain); } -struct dev_list_entry { - struct list_head node; - struct device *dev; +struct gpd_link { + struct generic_pm_domain *master; + struct list_head master_node; + struct generic_pm_domain *slave; + struct list_head slave_node; +}; + +struct generic_pm_domain_data { + struct pm_domain_data base; bool need_restore; }; +static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd) +{ + return container_of(pdd, struct generic_pm_domain_data, base); +} + #ifdef CONFIG_PM_GENERIC_DOMAINS extern int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev); diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index daac05d751b..70b284024d9 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -251,46 +251,4 @@ static inline void pm_runtime_dont_use_autosuspend(struct device *dev) __pm_runtime_use_autosuspend(dev, false); } -struct pm_clk_notifier_block { - struct notifier_block nb; - struct dev_pm_domain *pm_domain; - char *con_ids[]; -}; - -#ifdef CONFIG_PM_CLK -extern int pm_clk_init(struct device *dev); -extern void pm_clk_destroy(struct device *dev); -extern int pm_clk_add(struct device *dev, const char *con_id); -extern void pm_clk_remove(struct device *dev, const char *con_id); -extern int pm_clk_suspend(struct device *dev); -extern int pm_clk_resume(struct device *dev); -#else -static inline int pm_clk_init(struct device *dev) -{ - return -EINVAL; -} -static inline void pm_clk_destroy(struct device *dev) -{ -} -static inline int pm_clk_add(struct device *dev, const char *con_id) -{ - return -EINVAL; -} -static inline void pm_clk_remove(struct device *dev, const char *con_id) -{ -} -#define pm_clk_suspend NULL -#define pm_clk_resume NULL -#endif - -#ifdef CONFIG_HAVE_CLK -extern void pm_clk_add_notifier(struct bus_type *bus, - struct pm_clk_notifier_block *clknb); -#else -static inline void pm_clk_add_notifier(struct bus_type *bus, - struct pm_clk_notifier_block *clknb) -{ -} -#endif - #endif |