diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-03-20 13:20:33 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-03-22 17:19:12 -0400 |
commit | 446d999c1c92cec996e759dc3c03110596e626f5 (patch) | |
tree | 08b831e2ec37158d29fd037f7aaa61001c180425 | |
parent | 6d7d5c3266aa946b2049d9fed02186c1a378621b (diff) |
PM / domains: factor out code to get the generic PM domain from a struct device
The PM domain code contains two methods to get the generic PM domain
for a struct device. One is dev_to_genpd() which is only safe when
we know for certain that the device has a generic PM domain attached.
The other is coded into genpd_dev_pm_detach() which ensures that the
PM domain in the struct device is a generic PM domain (and so is safer).
This commit factors out the safer version, documents it, and hides the
unsafe dev_to_genpd().
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/domain.c | 46 | ||||
-rw-r--r-- | include/linux/pm_domain.h | 6 |
2 files changed, 35 insertions, 17 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 2e2e6af1f3fe..da25c0630789 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -68,7 +68,36 @@ static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name) | |||
68 | return genpd; | 68 | return genpd; |
69 | } | 69 | } |
70 | 70 | ||
71 | struct generic_pm_domain *dev_to_genpd(struct device *dev) | 71 | /* |
72 | * Get the generic PM domain for a particular struct device. | ||
73 | * This validates the struct device pointer, the PM domain pointer, | ||
74 | * and checks that the PM domain pointer is a real generic PM domain. | ||
75 | * Any failure results in NULL being returned. | ||
76 | */ | ||
77 | struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev) | ||
78 | { | ||
79 | struct generic_pm_domain *genpd = NULL, *gpd; | ||
80 | |||
81 | if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain)) | ||
82 | return NULL; | ||
83 | |||
84 | mutex_lock(&gpd_list_lock); | ||
85 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | ||
86 | if (&gpd->domain == dev->pm_domain) { | ||
87 | genpd = gpd; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | mutex_unlock(&gpd_list_lock); | ||
92 | |||
93 | return genpd; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * This should only be used where we are certain that the pm_domain | ||
98 | * attached to the device is a genpd domain. | ||
99 | */ | ||
100 | static struct generic_pm_domain *dev_to_genpd(struct device *dev) | ||
72 | { | 101 | { |
73 | if (IS_ERR_OR_NULL(dev->pm_domain)) | 102 | if (IS_ERR_OR_NULL(dev->pm_domain)) |
74 | return ERR_PTR(-EINVAL); | 103 | return ERR_PTR(-EINVAL); |
@@ -2093,21 +2122,10 @@ EXPORT_SYMBOL_GPL(of_genpd_get_from_provider); | |||
2093 | */ | 2122 | */ |
2094 | static void genpd_dev_pm_detach(struct device *dev, bool power_off) | 2123 | static void genpd_dev_pm_detach(struct device *dev, bool power_off) |
2095 | { | 2124 | { |
2096 | struct generic_pm_domain *pd = NULL, *gpd; | 2125 | struct generic_pm_domain *pd; |
2097 | int ret = 0; | 2126 | int ret = 0; |
2098 | 2127 | ||
2099 | if (!dev->pm_domain) | 2128 | pd = pm_genpd_lookup_dev(dev); |
2100 | return; | ||
2101 | |||
2102 | mutex_lock(&gpd_list_lock); | ||
2103 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | ||
2104 | if (&gpd->domain == dev->pm_domain) { | ||
2105 | pd = gpd; | ||
2106 | break; | ||
2107 | } | ||
2108 | } | ||
2109 | mutex_unlock(&gpd_list_lock); | ||
2110 | |||
2111 | if (!pd) | 2129 | if (!pd) |
2112 | return; | 2130 | return; |
2113 | 2131 | ||
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 080e778118ba..681ccb053f72 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h | |||
@@ -127,7 +127,7 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) | |||
127 | return to_gpd_data(dev->power.subsys_data->domain_data); | 127 | return to_gpd_data(dev->power.subsys_data->domain_data); |
128 | } | 128 | } |
129 | 129 | ||
130 | extern struct generic_pm_domain *dev_to_genpd(struct device *dev); | 130 | extern struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev); |
131 | extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, | 131 | extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, |
132 | struct device *dev, | 132 | struct device *dev, |
133 | struct gpd_timing_data *td); | 133 | struct gpd_timing_data *td); |
@@ -163,9 +163,9 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) | |||
163 | { | 163 | { |
164 | return ERR_PTR(-ENOSYS); | 164 | return ERR_PTR(-ENOSYS); |
165 | } | 165 | } |
166 | static inline struct generic_pm_domain *dev_to_genpd(struct device *dev) | 166 | static inline struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev) |
167 | { | 167 | { |
168 | return ERR_PTR(-ENOSYS); | 168 | return NULL; |
169 | } | 169 | } |
170 | static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, | 170 | static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, |
171 | struct device *dev, | 171 | struct device *dev, |