aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/main.c14
-rw-r--r--drivers/base/power/power.h4
-rw-r--r--drivers/base/power/resume.c12
-rw-r--r--drivers/base/power/runtime.c12
-rw-r--r--drivers/base/power/suspend.c14
5 files changed, 29 insertions, 27 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 05dc8764e765..7b3cc3c15b9d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -20,14 +20,16 @@
20 */ 20 */
21 21
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/mutex.h>
24
23#include "power.h" 25#include "power.h"
24 26
25LIST_HEAD(dpm_active); 27LIST_HEAD(dpm_active);
26LIST_HEAD(dpm_off); 28LIST_HEAD(dpm_off);
27LIST_HEAD(dpm_off_irq); 29LIST_HEAD(dpm_off_irq);
28 30
29DECLARE_MUTEX(dpm_sem); 31DEFINE_MUTEX(dpm_mtx);
30DECLARE_MUTEX(dpm_list_sem); 32DEFINE_MUTEX(dpm_list_mtx);
31 33
32int (*platform_enable_wakeup)(struct device *dev, int is_on); 34int (*platform_enable_wakeup)(struct device *dev, int is_on);
33 35
@@ -59,12 +61,12 @@ int device_pm_add(struct device * dev)
59 pr_debug("PM: Adding info for %s:%s\n", 61 pr_debug("PM: Adding info for %s:%s\n",
60 dev->bus ? dev->bus->name : "No Bus", 62 dev->bus ? dev->bus->name : "No Bus",
61 kobject_name(&dev->kobj)); 63 kobject_name(&dev->kobj));
62 down(&dpm_list_sem); 64 mutex_lock(&dpm_list_mtx);
63 list_add_tail(&dev->power.entry, &dpm_active); 65 list_add_tail(&dev->power.entry, &dpm_active);
64 device_pm_set_parent(dev, dev->parent); 66 device_pm_set_parent(dev, dev->parent);
65 if ((error = dpm_sysfs_add(dev))) 67 if ((error = dpm_sysfs_add(dev)))
66 list_del(&dev->power.entry); 68 list_del(&dev->power.entry);
67 up(&dpm_list_sem); 69 mutex_unlock(&dpm_list_mtx);
68 return error; 70 return error;
69} 71}
70 72
@@ -73,11 +75,11 @@ void device_pm_remove(struct device * dev)
73 pr_debug("PM: Removing info for %s:%s\n", 75 pr_debug("PM: Removing info for %s:%s\n",
74 dev->bus ? dev->bus->name : "No Bus", 76 dev->bus ? dev->bus->name : "No Bus",
75 kobject_name(&dev->kobj)); 77 kobject_name(&dev->kobj));
76 down(&dpm_list_sem); 78 mutex_lock(&dpm_list_mtx);
77 dpm_sysfs_remove(dev); 79 dpm_sysfs_remove(dev);
78 put_device(dev->power.pm_parent); 80 put_device(dev->power.pm_parent);
79 list_del_init(&dev->power.entry); 81 list_del_init(&dev->power.entry);
80 up(&dpm_list_sem); 82 mutex_unlock(&dpm_list_mtx);
81} 83}
82 84
83 85
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index fb3d35a9e101..2760f25b3ac5 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -14,12 +14,12 @@ extern void device_shutdown(void);
14/* 14/*
15 * Used to synchronize global power management operations. 15 * Used to synchronize global power management operations.
16 */ 16 */
17extern struct semaphore dpm_sem; 17extern struct mutex dpm_mtx;
18 18
19/* 19/*
20 * Used to serialize changes to the dpm_* lists. 20 * Used to serialize changes to the dpm_* lists.
21 */ 21 */
22extern struct semaphore dpm_list_sem; 22extern struct mutex dpm_list_mtx;
23 23
24/* 24/*
25 * The PM lists. 25 * The PM lists.
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index a2c64188d713..f6cfea496ea0 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -80,7 +80,7 @@ static int resume_device_early(struct device * dev)
80 */ 80 */
81void dpm_resume(void) 81void dpm_resume(void)
82{ 82{
83 down(&dpm_list_sem); 83 mutex_lock(&dpm_list_mtx);
84 while(!list_empty(&dpm_off)) { 84 while(!list_empty(&dpm_off)) {
85 struct list_head * entry = dpm_off.next; 85 struct list_head * entry = dpm_off.next;
86 struct device * dev = to_device(entry); 86 struct device * dev = to_device(entry);
@@ -88,13 +88,13 @@ void dpm_resume(void)
88 get_device(dev); 88 get_device(dev);
89 list_move_tail(entry, &dpm_active); 89 list_move_tail(entry, &dpm_active);
90 90
91 up(&dpm_list_sem); 91 mutex_unlock(&dpm_list_mtx);
92 if (!dev->power.prev_state.event) 92 if (!dev->power.prev_state.event)
93 resume_device(dev); 93 resume_device(dev);
94 down(&dpm_list_sem); 94 mutex_lock(&dpm_list_mtx);
95 put_device(dev); 95 put_device(dev);
96 } 96 }
97 up(&dpm_list_sem); 97 mutex_unlock(&dpm_list_mtx);
98} 98}
99 99
100 100
@@ -108,9 +108,9 @@ void dpm_resume(void)
108void device_resume(void) 108void device_resume(void)
109{ 109{
110 might_sleep(); 110 might_sleep();
111 down(&dpm_sem); 111 mutex_lock(&dpm_mtx);
112 dpm_resume(); 112 dpm_resume();
113 up(&dpm_sem); 113 mutex_unlock(&dpm_mtx);
114} 114}
115 115
116EXPORT_SYMBOL_GPL(device_resume); 116EXPORT_SYMBOL_GPL(device_resume);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 96370ec1d673..df6174d85866 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -32,9 +32,9 @@ static void runtime_resume(struct device * dev)
32 32
33void dpm_runtime_resume(struct device * dev) 33void dpm_runtime_resume(struct device * dev)
34{ 34{
35 down(&dpm_sem); 35 mutex_lock(&dpm_mtx);
36 runtime_resume(dev); 36 runtime_resume(dev);
37 up(&dpm_sem); 37 mutex_unlock(&dpm_mtx);
38} 38}
39EXPORT_SYMBOL(dpm_runtime_resume); 39EXPORT_SYMBOL(dpm_runtime_resume);
40 40
@@ -49,7 +49,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
49{ 49{
50 int error = 0; 50 int error = 0;
51 51
52 down(&dpm_sem); 52 mutex_lock(&dpm_mtx);
53 if (dev->power.power_state.event == state.event) 53 if (dev->power.power_state.event == state.event)
54 goto Done; 54 goto Done;
55 55
@@ -59,7 +59,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
59 if (!(error = suspend_device(dev, state))) 59 if (!(error = suspend_device(dev, state)))
60 dev->power.power_state = state; 60 dev->power.power_state = state;
61 Done: 61 Done:
62 up(&dpm_sem); 62 mutex_unlock(&dpm_mtx);
63 return error; 63 return error;
64} 64}
65EXPORT_SYMBOL(dpm_runtime_suspend); 65EXPORT_SYMBOL(dpm_runtime_suspend);
@@ -78,8 +78,8 @@ EXPORT_SYMBOL(dpm_runtime_suspend);
78 */ 78 */
79void dpm_set_power_state(struct device * dev, pm_message_t state) 79void dpm_set_power_state(struct device * dev, pm_message_t state)
80{ 80{
81 down(&dpm_sem); 81 mutex_lock(&dpm_mtx);
82 dev->power.power_state = state; 82 dev->power.power_state = state;
83 up(&dpm_sem); 83 mutex_unlock(&dpm_mtx);
84} 84}
85#endif /* 0 */ 85#endif /* 0 */
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 42d2b86ba765..9d6701cd7f10 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -108,7 +108,7 @@ int suspend_device(struct device * dev, pm_message_t state)
108 108
109/* 109/*
110 * This is called with interrupts off, only a single CPU 110 * This is called with interrupts off, only a single CPU
111 * running. We can't do down() on a semaphore (and we don't 111 * running. We can't acquire a mutex or semaphore (and we don't
112 * need the protection) 112 * need the protection)
113 */ 113 */
114static int suspend_device_late(struct device *dev, pm_message_t state) 114static int suspend_device_late(struct device *dev, pm_message_t state)
@@ -153,18 +153,18 @@ int device_suspend(pm_message_t state)
153 int error = 0; 153 int error = 0;
154 154
155 might_sleep(); 155 might_sleep();
156 down(&dpm_sem); 156 mutex_lock(&dpm_mtx);
157 down(&dpm_list_sem); 157 mutex_lock(&dpm_list_mtx);
158 while (!list_empty(&dpm_active) && error == 0) { 158 while (!list_empty(&dpm_active) && error == 0) {
159 struct list_head * entry = dpm_active.prev; 159 struct list_head * entry = dpm_active.prev;
160 struct device * dev = to_device(entry); 160 struct device * dev = to_device(entry);
161 161
162 get_device(dev); 162 get_device(dev);
163 up(&dpm_list_sem); 163 mutex_unlock(&dpm_list_mtx);
164 164
165 error = suspend_device(dev, state); 165 error = suspend_device(dev, state);
166 166
167 down(&dpm_list_sem); 167 mutex_lock(&dpm_list_mtx);
168 168
169 /* Check if the device got removed */ 169 /* Check if the device got removed */
170 if (!list_empty(&dev->power.entry)) { 170 if (!list_empty(&dev->power.entry)) {
@@ -179,11 +179,11 @@ int device_suspend(pm_message_t state)
179 error == -EAGAIN ? " (please convert to suspend_late)" : ""); 179 error == -EAGAIN ? " (please convert to suspend_late)" : "");
180 put_device(dev); 180 put_device(dev);
181 } 181 }
182 up(&dpm_list_sem); 182 mutex_unlock(&dpm_list_mtx);
183 if (error) 183 if (error)
184 dpm_resume(); 184 dpm_resume();
185 185
186 up(&dpm_sem); 186 mutex_unlock(&dpm_mtx);
187 return error; 187 return error;
188} 188}
189 189