aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-08-13 08:00:25 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-09-03 19:36:05 -0400
commitfeb70af0e3ac6817327be70b47731039ea135dbc (patch)
tree7df6ab174688d8bcc637af0d7a8fc7beb6a1e2aa
parent3cb6f10a4d925ec21f414bc30a8aded2830963e5 (diff)
PM: Do not use the syscore flag for runtime PM
The syscore device PM flag used to mark the devices (belonging to PM domains) that should never be turned off, except for the system core (syscore) suspend/hibernation and resume stages, need not be accessed by the runtime PM core functions, because all of the devices it is set for need to be marked as "irq safe" anyway and are protected from being turned off by runtime PM by ensuring that their usage counters are always set. For this reason, make the syscore flag system-wide PM-specific and simplify the code used for manipulating it, because it need not acquire the device's power.lock any more. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r--drivers/base/power/common.c15
-rw-r--r--drivers/base/power/domain.c2
-rw-r--r--drivers/base/power/runtime.c2
-rw-r--r--include/linux/device.h7
-rw-r--r--include/linux/pm.h6
5 files changed, 10 insertions, 22 deletions
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index cf7a85134730..39c32529b833 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -83,18 +83,3 @@ int dev_pm_put_subsys_data(struct device *dev)
83 return ret; 83 return ret;
84} 84}
85EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data); 85EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
86
87/**
88 * dev_pm_syscore_device - Set/unset the given device's power.syscore flag.
89 * @dev: Device whose flag is to be modified.
90 * @val: New value of the flag.
91 */
92void dev_pm_syscore_device(struct device *dev, bool val)
93{
94 unsigned long flags;
95
96 spin_lock_irqsave(&dev->power.lock, flags);
97 dev->power.syscore = val;
98 spin_unlock_irqrestore(&dev->power.lock, flags);
99}
100EXPORT_SYMBOL_GPL(dev_pm_syscore_device);
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index d7e71b5b080e..5f4606f13be6 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -442,7 +442,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
442 not_suspended = 0; 442 not_suspended = 0;
443 list_for_each_entry(pdd, &genpd->dev_list, list_node) 443 list_for_each_entry(pdd, &genpd->dev_list, list_node)
444 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev) 444 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
445 || pdd->dev->power.irq_safe || pdd->dev->power.syscore)) 445 || pdd->dev->power.irq_safe))
446 not_suspended++; 446 not_suspended++;
447 447
448 if (not_suspended > genpd->in_progress) 448 if (not_suspended > genpd->in_progress)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index bd1de3980919..7d9c1cb1c39a 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -134,7 +134,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
134 134
135 if (dev->power.runtime_error) 135 if (dev->power.runtime_error)
136 retval = -EINVAL; 136 retval = -EINVAL;
137 else if (dev->power.disable_depth > 0 || dev->power.syscore) 137 else if (dev->power.disable_depth > 0)
138 retval = -EACCES; 138 retval = -EACCES;
139 else if (atomic_read(&dev->power.usage_count) > 0) 139 else if (atomic_read(&dev->power.usage_count) > 0)
140 retval = -EAGAIN; 140 retval = -EAGAIN;
diff --git a/include/linux/device.h b/include/linux/device.h
index 52a5f15a2223..86529e642d6c 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -772,6 +772,13 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
772 dev->power.ignore_children = enable; 772 dev->power.ignore_children = enable;
773} 773}
774 774
775static inline void dev_pm_syscore_device(struct device *dev, bool val)
776{
777#ifdef CONFIG_PM_SLEEP
778 dev->power.syscore = val;
779#endif
780}
781
775static inline void device_lock(struct device *dev) 782static inline void device_lock(struct device *dev)
776{ 783{
777 mutex_lock(&dev->mutex); 784 mutex_lock(&dev->mutex);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index b79a0dd3bc6d..44d1f2307dbc 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -43,12 +43,8 @@ struct device;
43 43
44#ifdef CONFIG_PM 44#ifdef CONFIG_PM
45extern const char power_group_name[]; /* = "power" */ 45extern const char power_group_name[]; /* = "power" */
46
47extern void dev_pm_syscore_device(struct device *dev, bool val);
48#else 46#else
49#define power_group_name NULL 47#define power_group_name NULL
50
51static inline void dev_pm_syscore_device(struct device *dev, bool val) {}
52#endif 48#endif
53 49
54typedef struct pm_message { 50typedef struct pm_message {
@@ -515,13 +511,13 @@ struct dev_pm_info {
515 bool is_suspended:1; /* Ditto */ 511 bool is_suspended:1; /* Ditto */
516 bool ignore_children:1; 512 bool ignore_children:1;
517 bool early_init:1; /* Owned by the PM core */ 513 bool early_init:1; /* Owned by the PM core */
518 bool syscore:1;
519 spinlock_t lock; 514 spinlock_t lock;
520#ifdef CONFIG_PM_SLEEP 515#ifdef CONFIG_PM_SLEEP
521 struct list_head entry; 516 struct list_head entry;
522 struct completion completion; 517 struct completion completion;
523 struct wakeup_source *wakeup; 518 struct wakeup_source *wakeup;
524 bool wakeup_path:1; 519 bool wakeup_path:1;
520 bool syscore:1;
525#else 521#else
526 unsigned int should_wakeup:1; 522 unsigned int should_wakeup:1;
527#endif 523#endif