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, |
