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/linux | |
| parent | d727b60659a1173eb4142a5fc521ce67c28b34e1 (diff) | |
| parent | cd0ea672f58d5cfdea271c45cec0c897f2b792aa (diff) | |
| download | olio-linux-3.10-c28b56b1d46b1bbb1be33c8f2632a88b0de1ef68.tar.xz olio-linux-3.10-c28b56b1d46b1bbb1be33c8f2632a88b0de1ef68.zip  | |
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/linux')
| -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  |