diff options
-rw-r--r-- | drivers/base/power/domain.c | 28 | ||||
-rw-r--r-- | include/linux/pm.h | 3 | ||||
-rw-r--r-- | include/linux/pm_domain.h | 10 |
3 files changed, 30 insertions, 11 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index c2468a7e5b21..22fe029ca212 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -188,11 +188,12 @@ static int __pm_genpd_save_device(struct pm_domain_data *pdd, | |||
188 | struct generic_pm_domain *genpd) | 188 | struct generic_pm_domain *genpd) |
189 | __releases(&genpd->lock) __acquires(&genpd->lock) | 189 | __releases(&genpd->lock) __acquires(&genpd->lock) |
190 | { | 190 | { |
191 | struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); | ||
191 | struct device *dev = pdd->dev; | 192 | struct device *dev = pdd->dev; |
192 | struct device_driver *drv = dev->driver; | 193 | struct device_driver *drv = dev->driver; |
193 | int ret = 0; | 194 | int ret = 0; |
194 | 195 | ||
195 | if (pdd->need_restore) | 196 | if (gpd_data->need_restore) |
196 | return 0; | 197 | return 0; |
197 | 198 | ||
198 | mutex_unlock(&genpd->lock); | 199 | mutex_unlock(&genpd->lock); |
@@ -210,7 +211,7 @@ static int __pm_genpd_save_device(struct pm_domain_data *pdd, | |||
210 | mutex_lock(&genpd->lock); | 211 | mutex_lock(&genpd->lock); |
211 | 212 | ||
212 | if (!ret) | 213 | if (!ret) |
213 | pdd->need_restore = true; | 214 | gpd_data->need_restore = true; |
214 | 215 | ||
215 | return ret; | 216 | return ret; |
216 | } | 217 | } |
@@ -224,10 +225,11 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd, | |||
224 | struct generic_pm_domain *genpd) | 225 | struct generic_pm_domain *genpd) |
225 | __releases(&genpd->lock) __acquires(&genpd->lock) | 226 | __releases(&genpd->lock) __acquires(&genpd->lock) |
226 | { | 227 | { |
228 | struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); | ||
227 | struct device *dev = pdd->dev; | 229 | struct device *dev = pdd->dev; |
228 | struct device_driver *drv = dev->driver; | 230 | struct device_driver *drv = dev->driver; |
229 | 231 | ||
230 | if (!pdd->need_restore) | 232 | if (!gpd_data->need_restore) |
231 | return; | 233 | return; |
232 | 234 | ||
233 | mutex_unlock(&genpd->lock); | 235 | mutex_unlock(&genpd->lock); |
@@ -244,7 +246,7 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd, | |||
244 | 246 | ||
245 | mutex_lock(&genpd->lock); | 247 | mutex_lock(&genpd->lock); |
246 | 248 | ||
247 | pdd->need_restore = false; | 249 | gpd_data->need_restore = false; |
248 | } | 250 | } |
249 | 251 | ||
250 | /** | 252 | /** |
@@ -493,7 +495,7 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
493 | mutex_lock(&genpd->lock); | 495 | mutex_lock(&genpd->lock); |
494 | } | 496 | } |
495 | finish_wait(&genpd->status_wait_queue, &wait); | 497 | finish_wait(&genpd->status_wait_queue, &wait); |
496 | __pm_genpd_restore_device(&dev->power.subsys_data->domain_data, genpd); | 498 | __pm_genpd_restore_device(dev->power.subsys_data->domain_data, genpd); |
497 | genpd->resume_count--; | 499 | genpd->resume_count--; |
498 | genpd_set_active(genpd); | 500 | genpd_set_active(genpd); |
499 | wake_up_all(&genpd->status_wait_queue); | 501 | wake_up_all(&genpd->status_wait_queue); |
@@ -1080,6 +1082,7 @@ static void pm_genpd_complete(struct device *dev) | |||
1080 | */ | 1082 | */ |
1081 | int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) | 1083 | int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) |
1082 | { | 1084 | { |
1085 | struct generic_pm_domain_data *gpd_data; | ||
1083 | struct pm_domain_data *pdd; | 1086 | struct pm_domain_data *pdd; |
1084 | int ret = 0; | 1087 | int ret = 0; |
1085 | 1088 | ||
@@ -1106,14 +1109,20 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) | |||
1106 | goto out; | 1109 | goto out; |
1107 | } | 1110 | } |
1108 | 1111 | ||
1112 | gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); | ||
1113 | if (!gpd_data) { | ||
1114 | ret = -ENOMEM; | ||
1115 | goto out; | ||
1116 | } | ||
1117 | |||
1109 | genpd->device_count++; | 1118 | genpd->device_count++; |
1110 | 1119 | ||
1111 | dev->pm_domain = &genpd->domain; | 1120 | dev->pm_domain = &genpd->domain; |
1112 | dev_pm_get_subsys_data(dev); | 1121 | dev_pm_get_subsys_data(dev); |
1113 | pdd = &dev->power.subsys_data->domain_data; | 1122 | dev->power.subsys_data->domain_data = &gpd_data->base; |
1114 | pdd->dev = dev; | 1123 | gpd_data->base.dev = dev; |
1115 | pdd->need_restore = false; | 1124 | gpd_data->need_restore = false; |
1116 | list_add_tail(&pdd->list_node, &genpd->dev_list); | 1125 | list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); |
1117 | 1126 | ||
1118 | out: | 1127 | out: |
1119 | genpd_release_lock(genpd); | 1128 | genpd_release_lock(genpd); |
@@ -1152,6 +1161,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
1152 | pdd->dev = NULL; | 1161 | pdd->dev = NULL; |
1153 | dev_pm_put_subsys_data(dev); | 1162 | dev_pm_put_subsys_data(dev); |
1154 | dev->pm_domain = NULL; | 1163 | dev->pm_domain = NULL; |
1164 | kfree(to_gpd_data(pdd)); | ||
1155 | 1165 | ||
1156 | genpd->device_count--; | 1166 | genpd->device_count--; |
1157 | 1167 | ||
diff --git a/include/linux/pm.h b/include/linux/pm.h index ed10f24d5259..f25682477f08 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -424,7 +424,6 @@ struct wakeup_source; | |||
424 | struct pm_domain_data { | 424 | struct pm_domain_data { |
425 | struct list_head list_node; | 425 | struct list_head list_node; |
426 | struct device *dev; | 426 | struct device *dev; |
427 | bool need_restore; | ||
428 | }; | 427 | }; |
429 | 428 | ||
430 | struct pm_subsys_data { | 429 | struct pm_subsys_data { |
@@ -434,7 +433,7 @@ struct pm_subsys_data { | |||
434 | struct list_head clock_list; | 433 | struct list_head clock_list; |
435 | #endif | 434 | #endif |
436 | #ifdef CONFIG_PM_GENERIC_DOMAINS | 435 | #ifdef CONFIG_PM_GENERIC_DOMAINS |
437 | struct pm_domain_data domain_data; | 436 | struct pm_domain_data *domain_data; |
438 | #endif | 437 | #endif |
439 | }; | 438 | }; |
440 | 439 | ||
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 2538d906bcd1..65633e5a2bc0 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h | |||
@@ -62,6 +62,16 @@ struct gpd_link { | |||
62 | struct list_head slave_node; | 62 | struct list_head slave_node; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | struct generic_pm_domain_data { | ||
66 | struct pm_domain_data base; | ||
67 | bool need_restore; | ||
68 | }; | ||
69 | |||
70 | static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd) | ||
71 | { | ||
72 | return container_of(pdd, struct generic_pm_domain_data, base); | ||
73 | } | ||
74 | |||
65 | #ifdef CONFIG_PM_GENERIC_DOMAINS | 75 | #ifdef CONFIG_PM_GENERIC_DOMAINS |
66 | extern int pm_genpd_add_device(struct generic_pm_domain *genpd, | 76 | extern int pm_genpd_add_device(struct generic_pm_domain *genpd, |
67 | struct device *dev); | 77 | struct device *dev); |