diff options
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r-- | drivers/base/power/main.c | 44 |
1 files changed, 12 insertions, 32 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 05dc8764e765..eb9f38d0aa58 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -20,64 +20,44 @@ | |||
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 | ||
25 | LIST_HEAD(dpm_active); | 27 | LIST_HEAD(dpm_active); |
26 | LIST_HEAD(dpm_off); | 28 | LIST_HEAD(dpm_off); |
27 | LIST_HEAD(dpm_off_irq); | 29 | LIST_HEAD(dpm_off_irq); |
28 | 30 | ||
29 | DECLARE_MUTEX(dpm_sem); | 31 | DEFINE_MUTEX(dpm_mtx); |
30 | DECLARE_MUTEX(dpm_list_sem); | 32 | DEFINE_MUTEX(dpm_list_mtx); |
31 | 33 | ||
32 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | 34 | int (*platform_enable_wakeup)(struct device *dev, int is_on); |
33 | 35 | ||
34 | 36 | int device_pm_add(struct device *dev) | |
35 | /** | ||
36 | * device_pm_set_parent - Specify power dependency. | ||
37 | * @dev: Device who needs power. | ||
38 | * @parent: Device that supplies power. | ||
39 | * | ||
40 | * This function is used to manually describe a power-dependency | ||
41 | * relationship. It may be used to specify a transversal relationship | ||
42 | * (where the power supplier is not the physical (or electrical) | ||
43 | * ancestor of a specific device. | ||
44 | * The effect of this is that the supplier will not be powered down | ||
45 | * before the power dependent. | ||
46 | */ | ||
47 | |||
48 | void device_pm_set_parent(struct device * dev, struct device * parent) | ||
49 | { | ||
50 | put_device(dev->power.pm_parent); | ||
51 | dev->power.pm_parent = get_device(parent); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(device_pm_set_parent); | ||
54 | |||
55 | int device_pm_add(struct device * dev) | ||
56 | { | 37 | { |
57 | int error; | 38 | int error; |
58 | 39 | ||
59 | pr_debug("PM: Adding info for %s:%s\n", | 40 | pr_debug("PM: Adding info for %s:%s\n", |
60 | dev->bus ? dev->bus->name : "No Bus", | 41 | dev->bus ? dev->bus->name : "No Bus", |
61 | kobject_name(&dev->kobj)); | 42 | kobject_name(&dev->kobj)); |
62 | down(&dpm_list_sem); | 43 | mutex_lock(&dpm_list_mtx); |
63 | list_add_tail(&dev->power.entry, &dpm_active); | 44 | list_add_tail(&dev->power.entry, &dpm_active); |
64 | device_pm_set_parent(dev, dev->parent); | 45 | error = dpm_sysfs_add(dev); |
65 | if ((error = dpm_sysfs_add(dev))) | 46 | if (error) |
66 | list_del(&dev->power.entry); | 47 | list_del(&dev->power.entry); |
67 | up(&dpm_list_sem); | 48 | mutex_unlock(&dpm_list_mtx); |
68 | return error; | 49 | return error; |
69 | } | 50 | } |
70 | 51 | ||
71 | void device_pm_remove(struct device * dev) | 52 | void device_pm_remove(struct device *dev) |
72 | { | 53 | { |
73 | pr_debug("PM: Removing info for %s:%s\n", | 54 | pr_debug("PM: Removing info for %s:%s\n", |
74 | dev->bus ? dev->bus->name : "No Bus", | 55 | dev->bus ? dev->bus->name : "No Bus", |
75 | kobject_name(&dev->kobj)); | 56 | kobject_name(&dev->kobj)); |
76 | down(&dpm_list_sem); | 57 | mutex_lock(&dpm_list_mtx); |
77 | dpm_sysfs_remove(dev); | 58 | dpm_sysfs_remove(dev); |
78 | put_device(dev->power.pm_parent); | ||
79 | list_del_init(&dev->power.entry); | 59 | list_del_init(&dev->power.entry); |
80 | up(&dpm_list_sem); | 60 | mutex_unlock(&dpm_list_mtx); |
81 | } | 61 | } |
82 | 62 | ||
83 | 63 | ||