aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/domain.c28
-rw-r--r--include/linux/pm.h3
-rw-r--r--include/linux/pm_domain.h10
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 */
1081int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) 1083int 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;
424struct pm_domain_data { 424struct 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
430struct pm_subsys_data { 429struct 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
65struct generic_pm_domain_data {
66 struct pm_domain_data base;
67 bool need_restore;
68};
69
70static 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
66extern int pm_genpd_add_device(struct generic_pm_domain *genpd, 76extern int pm_genpd_add_device(struct generic_pm_domain *genpd,
67 struct device *dev); 77 struct device *dev);