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
This commit is contained in:
@@ -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;
|
||||
|
@@ -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,
|
||||
|
71
include/linux/pm_clock.h
Normal file
71
include/linux/pm_clock.h
Normal file
@@ -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
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user