aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-07-18 18:03:17 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-07-18 18:03:17 -0400
commit7791bd230c6fe65348456564743f99fa066f00e7 (patch)
treee9ed6b3e1baea455a65274aa054ebd29d2623b92 /drivers/base
parent3db0bc97678d7de32f25514b290a0ca028dd4512 (diff)
parent8e9afafdad59f5973a5e72e05db9802f82091398 (diff)
Merge branch 'pm-domains'
* pm-domains: PM / Domains: Fix build warning for CONFIG_PM_RUNTIME unset PM / Domains: Replace plain integer with NULL pointer in domain.c file PM / Domains: Add missing static storage class specifier in domain.c file PM / Domains: Allow device callbacks to be added at any time PM / Domains: Add device domain data reference counter PM / Domains: Add preliminary support for cpuidle, v2 PM / Domains: Do not stop devices after restoring their states PM / Domains: Use subsystem runtime suspend/resume callbacks by default
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/domain.c342
1 files changed, 268 insertions, 74 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 83aa694a8efe..ba3487c9835b 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -75,19 +75,6 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
75 start_latency_ns, "start"); 75 start_latency_ns, "start");
76} 76}
77 77
78static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
79{
80 return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
81 save_state_latency_ns, "state save");
82}
83
84static int genpd_restore_dev(struct generic_pm_domain *genpd, struct device *dev)
85{
86 return GENPD_DEV_TIMED_CALLBACK(genpd, int, restore_state, dev,
87 restore_state_latency_ns,
88 "state restore");
89}
90
91static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) 78static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
92{ 79{
93 bool ret = false; 80 bool ret = false;
@@ -139,6 +126,19 @@ static void genpd_set_active(struct generic_pm_domain *genpd)
139 genpd->status = GPD_STATE_ACTIVE; 126 genpd->status = GPD_STATE_ACTIVE;
140} 127}
141 128
129static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
130{
131 s64 usecs64;
132
133 if (!genpd->cpu_data)
134 return;
135
136 usecs64 = genpd->power_on_latency_ns;
137 do_div(usecs64, NSEC_PER_USEC);
138 usecs64 += genpd->cpu_data->saved_exit_latency;
139 genpd->cpu_data->idle_state->exit_latency = usecs64;
140}
141
142/** 142/**
143 * __pm_genpd_poweron - Restore power to a given PM domain and its masters. 143 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
144 * @genpd: PM domain to power up. 144 * @genpd: PM domain to power up.
@@ -146,7 +146,7 @@ static void genpd_set_active(struct generic_pm_domain *genpd)
146 * Restore power to @genpd and all of its masters so that it is possible to 146 * Restore power to @genpd and all of its masters so that it is possible to
147 * resume a device belonging to it. 147 * resume a device belonging to it.
148 */ 148 */
149int __pm_genpd_poweron(struct generic_pm_domain *genpd) 149static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
150 __releases(&genpd->lock) __acquires(&genpd->lock) 150 __releases(&genpd->lock) __acquires(&genpd->lock)
151{ 151{
152 struct gpd_link *link; 152 struct gpd_link *link;
@@ -176,6 +176,13 @@ int __pm_genpd_poweron(struct generic_pm_domain *genpd)
176 return 0; 176 return 0;
177 } 177 }
178 178
179 if (genpd->cpu_data) {
180 cpuidle_pause_and_lock();
181 genpd->cpu_data->idle_state->disabled = true;
182 cpuidle_resume_and_unlock();
183 goto out;
184 }
185
179 /* 186 /*
180 * The list is guaranteed not to change while the loop below is being 187 * The list is guaranteed not to change while the loop below is being
181 * executed, unless one of the masters' .power_on() callbacks fiddles 188 * executed, unless one of the masters' .power_on() callbacks fiddles
@@ -215,6 +222,7 @@ int __pm_genpd_poweron(struct generic_pm_domain *genpd)
215 if (elapsed_ns > genpd->power_on_latency_ns) { 222 if (elapsed_ns > genpd->power_on_latency_ns) {
216 genpd->power_on_latency_ns = elapsed_ns; 223 genpd->power_on_latency_ns = elapsed_ns;
217 genpd->max_off_time_changed = true; 224 genpd->max_off_time_changed = true;
225 genpd_recalc_cpu_exit_latency(genpd);
218 if (genpd->name) 226 if (genpd->name)
219 pr_warning("%s: Power-on latency exceeded, " 227 pr_warning("%s: Power-on latency exceeded, "
220 "new value %lld ns\n", genpd->name, 228 "new value %lld ns\n", genpd->name,
@@ -222,6 +230,7 @@ int __pm_genpd_poweron(struct generic_pm_domain *genpd)
222 } 230 }
223 } 231 }
224 232
233 out:
225 genpd_set_active(genpd); 234 genpd_set_active(genpd);
226 235
227 return 0; 236 return 0;
@@ -251,6 +260,19 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
251 260
252#ifdef CONFIG_PM_RUNTIME 261#ifdef CONFIG_PM_RUNTIME
253 262
263static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
264{
265 return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
266 save_state_latency_ns, "state save");
267}
268
269static int genpd_restore_dev(struct generic_pm_domain *genpd, struct device *dev)
270{
271 return GENPD_DEV_TIMED_CALLBACK(genpd, int, restore_state, dev,
272 restore_state_latency_ns,
273 "state restore");
274}
275
254static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, 276static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
255 unsigned long val, void *ptr) 277 unsigned long val, void *ptr)
256{ 278{
@@ -275,7 +297,7 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
275 297
276 pdd = dev->power.subsys_data ? 298 pdd = dev->power.subsys_data ?
277 dev->power.subsys_data->domain_data : NULL; 299 dev->power.subsys_data->domain_data : NULL;
278 if (pdd) { 300 if (pdd && pdd->dev) {
279 to_gpd_data(pdd)->td.constraint_changed = true; 301 to_gpd_data(pdd)->td.constraint_changed = true;
280 genpd = dev_to_genpd(dev); 302 genpd = dev_to_genpd(dev);
281 } else { 303 } else {
@@ -339,19 +361,16 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd,
339{ 361{
340 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); 362 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
341 struct device *dev = pdd->dev; 363 struct device *dev = pdd->dev;
364 bool need_restore = gpd_data->need_restore;
342 365
343 if (!gpd_data->need_restore) 366 gpd_data->need_restore = false;
344 return;
345
346 mutex_unlock(&genpd->lock); 367 mutex_unlock(&genpd->lock);
347 368
348 genpd_start_dev(genpd, dev); 369 genpd_start_dev(genpd, dev);
349 genpd_restore_dev(genpd, dev); 370 if (need_restore)
350 genpd_stop_dev(genpd, dev); 371 genpd_restore_dev(genpd, dev);
351 372
352 mutex_lock(&genpd->lock); 373 mutex_lock(&genpd->lock);
353
354 gpd_data->need_restore = false;
355} 374}
356 375
357/** 376/**
@@ -458,6 +477,21 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
458 } 477 }
459 } 478 }
460 479
480 if (genpd->cpu_data) {
481 /*
482 * If cpu_data is set, cpuidle should turn the domain off when
483 * the CPU in it is idle. In that case we don't decrement the
484 * subdomain counts of the master domains, so that power is not
485 * removed from the current domain prematurely as a result of
486 * cutting off the masters' power.
487 */
488 genpd->status = GPD_STATE_POWER_OFF;
489 cpuidle_pause_and_lock();
490 genpd->cpu_data->idle_state->disabled = false;
491 cpuidle_resume_and_unlock();
492 goto out;
493 }
494
461 if (genpd->power_off) { 495 if (genpd->power_off) {
462 ktime_t time_start; 496 ktime_t time_start;
463 s64 elapsed_ns; 497 s64 elapsed_ns;
@@ -595,7 +629,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
595 629
596 /* If power.irq_safe, the PM domain is never powered off. */ 630 /* If power.irq_safe, the PM domain is never powered off. */
597 if (dev->power.irq_safe) 631 if (dev->power.irq_safe)
598 goto out; 632 return genpd_start_dev(genpd, dev);
599 633
600 mutex_lock(&genpd->lock); 634 mutex_lock(&genpd->lock);
601 ret = __pm_genpd_poweron(genpd); 635 ret = __pm_genpd_poweron(genpd);
@@ -628,9 +662,6 @@ static int pm_genpd_runtime_resume(struct device *dev)
628 wake_up_all(&genpd->status_wait_queue); 662 wake_up_all(&genpd->status_wait_queue);
629 mutex_unlock(&genpd->lock); 663 mutex_unlock(&genpd->lock);
630 664
631 out:
632 genpd_start_dev(genpd, dev);
633
634 return 0; 665 return 0;
635} 666}
636 667
@@ -1235,6 +1266,27 @@ static void pm_genpd_complete(struct device *dev)
1235 1266
1236#endif /* CONFIG_PM_SLEEP */ 1267#endif /* CONFIG_PM_SLEEP */
1237 1268
1269static struct generic_pm_domain_data *__pm_genpd_alloc_dev_data(struct device *dev)
1270{
1271 struct generic_pm_domain_data *gpd_data;
1272
1273 gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL);
1274 if (!gpd_data)
1275 return NULL;
1276
1277 mutex_init(&gpd_data->lock);
1278 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
1279 dev_pm_qos_add_notifier(dev, &gpd_data->nb);
1280 return gpd_data;
1281}
1282
1283static void __pm_genpd_free_dev_data(struct device *dev,
1284 struct generic_pm_domain_data *gpd_data)
1285{
1286 dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
1287 kfree(gpd_data);
1288}
1289
1238/** 1290/**
1239 * __pm_genpd_add_device - Add a device to an I/O PM domain. 1291 * __pm_genpd_add_device - Add a device to an I/O PM domain.
1240 * @genpd: PM domain to add the device to. 1292 * @genpd: PM domain to add the device to.
@@ -1244,7 +1296,7 @@ static void pm_genpd_complete(struct device *dev)
1244int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, 1296int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1245 struct gpd_timing_data *td) 1297 struct gpd_timing_data *td)
1246{ 1298{
1247 struct generic_pm_domain_data *gpd_data; 1299 struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL;
1248 struct pm_domain_data *pdd; 1300 struct pm_domain_data *pdd;
1249 int ret = 0; 1301 int ret = 0;
1250 1302
@@ -1253,14 +1305,10 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1253 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) 1305 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1254 return -EINVAL; 1306 return -EINVAL;
1255 1307
1256 gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); 1308 gpd_data_new = __pm_genpd_alloc_dev_data(dev);
1257 if (!gpd_data) 1309 if (!gpd_data_new)
1258 return -ENOMEM; 1310 return -ENOMEM;
1259 1311
1260 mutex_init(&gpd_data->lock);
1261 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
1262 dev_pm_qos_add_notifier(dev, &gpd_data->nb);
1263
1264 genpd_acquire_lock(genpd); 1312 genpd_acquire_lock(genpd);
1265 1313
1266 if (genpd->prepared_count > 0) { 1314 if (genpd->prepared_count > 0) {
@@ -1274,35 +1322,42 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1274 goto out; 1322 goto out;
1275 } 1323 }
1276 1324
1325 ret = dev_pm_get_subsys_data(dev);
1326 if (ret)
1327 goto out;
1328
1277 genpd->device_count++; 1329 genpd->device_count++;
1278 genpd->max_off_time_changed = true; 1330 genpd->max_off_time_changed = true;
1279 1331
1280 dev_pm_get_subsys_data(dev);
1281
1282 mutex_lock(&gpd_data->lock);
1283 spin_lock_irq(&dev->power.lock); 1332 spin_lock_irq(&dev->power.lock);
1333
1284 dev->pm_domain = &genpd->domain; 1334 dev->pm_domain = &genpd->domain;
1285 dev->power.subsys_data->domain_data = &gpd_data->base; 1335 if (dev->power.subsys_data->domain_data) {
1286 gpd_data->base.dev = dev; 1336 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
1287 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); 1337 } else {
1288 gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF; 1338 gpd_data = gpd_data_new;
1339 dev->power.subsys_data->domain_data = &gpd_data->base;
1340 }
1341 gpd_data->refcount++;
1289 if (td) 1342 if (td)
1290 gpd_data->td = *td; 1343 gpd_data->td = *td;
1291 1344
1345 spin_unlock_irq(&dev->power.lock);
1346
1347 mutex_lock(&gpd_data->lock);
1348 gpd_data->base.dev = dev;
1349 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
1350 gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF;
1292 gpd_data->td.constraint_changed = true; 1351 gpd_data->td.constraint_changed = true;
1293 gpd_data->td.effective_constraint_ns = -1; 1352 gpd_data->td.effective_constraint_ns = -1;
1294 spin_unlock_irq(&dev->power.lock);
1295 mutex_unlock(&gpd_data->lock); 1353 mutex_unlock(&gpd_data->lock);
1296 1354
1297 genpd_release_lock(genpd);
1298
1299 return 0;
1300
1301 out: 1355 out:
1302 genpd_release_lock(genpd); 1356 genpd_release_lock(genpd);
1303 1357
1304 dev_pm_qos_remove_notifier(dev, &gpd_data->nb); 1358 if (gpd_data != gpd_data_new)
1305 kfree(gpd_data); 1359 __pm_genpd_free_dev_data(dev, gpd_data_new);
1360
1306 return ret; 1361 return ret;
1307} 1362}
1308 1363
@@ -1348,6 +1403,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1348{ 1403{
1349 struct generic_pm_domain_data *gpd_data; 1404 struct generic_pm_domain_data *gpd_data;
1350 struct pm_domain_data *pdd; 1405 struct pm_domain_data *pdd;
1406 bool remove = false;
1351 int ret = 0; 1407 int ret = 0;
1352 1408
1353 dev_dbg(dev, "%s()\n", __func__); 1409 dev_dbg(dev, "%s()\n", __func__);
@@ -1368,22 +1424,28 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1368 genpd->max_off_time_changed = true; 1424 genpd->max_off_time_changed = true;
1369 1425
1370 spin_lock_irq(&dev->power.lock); 1426 spin_lock_irq(&dev->power.lock);
1427
1371 dev->pm_domain = NULL; 1428 dev->pm_domain = NULL;
1372 pdd = dev->power.subsys_data->domain_data; 1429 pdd = dev->power.subsys_data->domain_data;
1373 list_del_init(&pdd->list_node); 1430 list_del_init(&pdd->list_node);
1374 dev->power.subsys_data->domain_data = NULL; 1431 gpd_data = to_gpd_data(pdd);
1432 if (--gpd_data->refcount == 0) {
1433 dev->power.subsys_data->domain_data = NULL;
1434 remove = true;
1435 }
1436
1375 spin_unlock_irq(&dev->power.lock); 1437 spin_unlock_irq(&dev->power.lock);
1376 1438
1377 gpd_data = to_gpd_data(pdd);
1378 mutex_lock(&gpd_data->lock); 1439 mutex_lock(&gpd_data->lock);
1379 pdd->dev = NULL; 1440 pdd->dev = NULL;
1380 mutex_unlock(&gpd_data->lock); 1441 mutex_unlock(&gpd_data->lock);
1381 1442
1382 genpd_release_lock(genpd); 1443 genpd_release_lock(genpd);
1383 1444
1384 dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
1385 kfree(gpd_data);
1386 dev_pm_put_subsys_data(dev); 1445 dev_pm_put_subsys_data(dev);
1446 if (remove)
1447 __pm_genpd_free_dev_data(dev, gpd_data);
1448
1387 return 0; 1449 return 0;
1388 1450
1389 out: 1451 out:
@@ -1541,33 +1603,52 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
1541 * @dev: Device to add the callbacks to. 1603 * @dev: Device to add the callbacks to.
1542 * @ops: Set of callbacks to add. 1604 * @ops: Set of callbacks to add.
1543 * @td: Timing data to add to the device along with the callbacks (optional). 1605 * @td: Timing data to add to the device along with the callbacks (optional).
1606 *
1607 * Every call to this routine should be balanced with a call to
1608 * __pm_genpd_remove_callbacks() and they must not be nested.
1544 */ 1609 */
1545int pm_genpd_add_callbacks(struct device *dev, struct gpd_dev_ops *ops, 1610int pm_genpd_add_callbacks(struct device *dev, struct gpd_dev_ops *ops,
1546 struct gpd_timing_data *td) 1611 struct gpd_timing_data *td)
1547{ 1612{
1548 struct pm_domain_data *pdd; 1613 struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL;
1549 int ret = 0; 1614 int ret = 0;
1550 1615
1551 if (!(dev && dev->power.subsys_data && ops)) 1616 if (!(dev && ops))
1552 return -EINVAL; 1617 return -EINVAL;
1553 1618
1619 gpd_data_new = __pm_genpd_alloc_dev_data(dev);
1620 if (!gpd_data_new)
1621 return -ENOMEM;
1622
1554 pm_runtime_disable(dev); 1623 pm_runtime_disable(dev);
1555 device_pm_lock(); 1624 device_pm_lock();
1556 1625
1557 pdd = dev->power.subsys_data->domain_data; 1626 ret = dev_pm_get_subsys_data(dev);
1558 if (pdd) { 1627 if (ret)
1559 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); 1628 goto out;
1560 1629
1561 gpd_data->ops = *ops; 1630 spin_lock_irq(&dev->power.lock);
1562 if (td) 1631
1563 gpd_data->td = *td; 1632 if (dev->power.subsys_data->domain_data) {
1633 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
1564 } else { 1634 } else {
1565 ret = -EINVAL; 1635 gpd_data = gpd_data_new;
1636 dev->power.subsys_data->domain_data = &gpd_data->base;
1566 } 1637 }
1638 gpd_data->refcount++;
1639 gpd_data->ops = *ops;
1640 if (td)
1641 gpd_data->td = *td;
1642
1643 spin_unlock_irq(&dev->power.lock);
1567 1644
1645 out:
1568 device_pm_unlock(); 1646 device_pm_unlock();
1569 pm_runtime_enable(dev); 1647 pm_runtime_enable(dev);
1570 1648
1649 if (gpd_data != gpd_data_new)
1650 __pm_genpd_free_dev_data(dev, gpd_data_new);
1651
1571 return ret; 1652 return ret;
1572} 1653}
1573EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks); 1654EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks);
@@ -1576,10 +1657,13 @@ EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks);
1576 * __pm_genpd_remove_callbacks - Remove PM domain callbacks from a given device. 1657 * __pm_genpd_remove_callbacks - Remove PM domain callbacks from a given device.
1577 * @dev: Device to remove the callbacks from. 1658 * @dev: Device to remove the callbacks from.
1578 * @clear_td: If set, clear the device's timing data too. 1659 * @clear_td: If set, clear the device's timing data too.
1660 *
1661 * This routine can only be called after pm_genpd_add_callbacks().
1579 */ 1662 */
1580int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) 1663int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
1581{ 1664{
1582 struct pm_domain_data *pdd; 1665 struct generic_pm_domain_data *gpd_data = NULL;
1666 bool remove = false;
1583 int ret = 0; 1667 int ret = 0;
1584 1668
1585 if (!(dev && dev->power.subsys_data)) 1669 if (!(dev && dev->power.subsys_data))
@@ -1588,24 +1672,118 @@ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
1588 pm_runtime_disable(dev); 1672 pm_runtime_disable(dev);
1589 device_pm_lock(); 1673 device_pm_lock();
1590 1674
1591 pdd = dev->power.subsys_data->domain_data; 1675 spin_lock_irq(&dev->power.lock);
1592 if (pdd) {
1593 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
1594 1676
1595 gpd_data->ops = (struct gpd_dev_ops){ 0 }; 1677 if (dev->power.subsys_data->domain_data) {
1678 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
1679 gpd_data->ops = (struct gpd_dev_ops){ NULL };
1596 if (clear_td) 1680 if (clear_td)
1597 gpd_data->td = (struct gpd_timing_data){ 0 }; 1681 gpd_data->td = (struct gpd_timing_data){ 0 };
1682
1683 if (--gpd_data->refcount == 0) {
1684 dev->power.subsys_data->domain_data = NULL;
1685 remove = true;
1686 }
1598 } else { 1687 } else {
1599 ret = -EINVAL; 1688 ret = -EINVAL;
1600 } 1689 }
1601 1690
1691 spin_unlock_irq(&dev->power.lock);
1692
1602 device_pm_unlock(); 1693 device_pm_unlock();
1603 pm_runtime_enable(dev); 1694 pm_runtime_enable(dev);
1604 1695
1605 return ret; 1696 if (ret)
1697 return ret;
1698
1699 dev_pm_put_subsys_data(dev);
1700 if (remove)
1701 __pm_genpd_free_dev_data(dev, gpd_data);
1702
1703 return 0;
1606} 1704}
1607EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); 1705EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
1608 1706
1707int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
1708{
1709 struct cpuidle_driver *cpuidle_drv;
1710 struct gpd_cpu_data *cpu_data;
1711 struct cpuidle_state *idle_state;
1712 int ret = 0;
1713
1714 if (IS_ERR_OR_NULL(genpd) || state < 0)
1715 return -EINVAL;
1716
1717 genpd_acquire_lock(genpd);
1718
1719 if (genpd->cpu_data) {
1720 ret = -EEXIST;
1721 goto out;
1722 }
1723 cpu_data = kzalloc(sizeof(*cpu_data), GFP_KERNEL);
1724 if (!cpu_data) {
1725 ret = -ENOMEM;
1726 goto out;
1727 }
1728 cpuidle_drv = cpuidle_driver_ref();
1729 if (!cpuidle_drv) {
1730 ret = -ENODEV;
1731 goto out;
1732 }
1733 if (cpuidle_drv->state_count <= state) {
1734 ret = -EINVAL;
1735 goto err;
1736 }
1737 idle_state = &cpuidle_drv->states[state];
1738 if (!idle_state->disabled) {
1739 ret = -EAGAIN;
1740 goto err;
1741 }
1742 cpu_data->idle_state = idle_state;
1743 cpu_data->saved_exit_latency = idle_state->exit_latency;
1744 genpd->cpu_data = cpu_data;
1745 genpd_recalc_cpu_exit_latency(genpd);
1746
1747 out:
1748 genpd_release_lock(genpd);
1749 return ret;
1750
1751 err:
1752 cpuidle_driver_unref();
1753 goto out;
1754}
1755
1756int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
1757{
1758 struct gpd_cpu_data *cpu_data;
1759 struct cpuidle_state *idle_state;
1760 int ret = 0;
1761
1762 if (IS_ERR_OR_NULL(genpd))
1763 return -EINVAL;
1764
1765 genpd_acquire_lock(genpd);
1766
1767 cpu_data = genpd->cpu_data;
1768 if (!cpu_data) {
1769 ret = -ENODEV;
1770 goto out;
1771 }
1772 idle_state = cpu_data->idle_state;
1773 if (!idle_state->disabled) {
1774 ret = -EAGAIN;
1775 goto out;
1776 }
1777 idle_state->exit_latency = cpu_data->saved_exit_latency;
1778 cpuidle_driver_unref();
1779 genpd->cpu_data = NULL;
1780 kfree(cpu_data);
1781
1782 out:
1783 genpd_release_lock(genpd);
1784 return ret;
1785}
1786
1609/* Default device callbacks for generic PM domains. */ 1787/* Default device callbacks for generic PM domains. */
1610 1788
1611/** 1789/**
@@ -1615,16 +1793,24 @@ EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
1615static int pm_genpd_default_save_state(struct device *dev) 1793static int pm_genpd_default_save_state(struct device *dev)
1616{ 1794{
1617 int (*cb)(struct device *__dev); 1795 int (*cb)(struct device *__dev);
1618 struct device_driver *drv = dev->driver;
1619 1796
1620 cb = dev_gpd_data(dev)->ops.save_state; 1797 cb = dev_gpd_data(dev)->ops.save_state;
1621 if (cb) 1798 if (cb)
1622 return cb(dev); 1799 return cb(dev);
1623 1800
1624 if (drv && drv->pm && drv->pm->runtime_suspend) 1801 if (dev->type && dev->type->pm)
1625 return drv->pm->runtime_suspend(dev); 1802 cb = dev->type->pm->runtime_suspend;
1803 else if (dev->class && dev->class->pm)
1804 cb = dev->class->pm->runtime_suspend;
1805 else if (dev->bus && dev->bus->pm)
1806 cb = dev->bus->pm->runtime_suspend;
1807 else
1808 cb = NULL;
1626 1809
1627 return 0; 1810 if (!cb && dev->driver && dev->driver->pm)
1811 cb = dev->driver->pm->runtime_suspend;
1812
1813 return cb ? cb(dev) : 0;
1628} 1814}
1629 1815
1630/** 1816/**
@@ -1634,16 +1820,24 @@ static int pm_genpd_default_save_state(struct device *dev)
1634static int pm_genpd_default_restore_state(struct device *dev) 1820static int pm_genpd_default_restore_state(struct device *dev)
1635{ 1821{
1636 int (*cb)(struct device *__dev); 1822 int (*cb)(struct device *__dev);
1637 struct device_driver *drv = dev->driver;
1638 1823
1639 cb = dev_gpd_data(dev)->ops.restore_state; 1824 cb = dev_gpd_data(dev)->ops.restore_state;
1640 if (cb) 1825 if (cb)
1641 return cb(dev); 1826 return cb(dev);
1642 1827
1643 if (drv && drv->pm && drv->pm->runtime_resume) 1828 if (dev->type && dev->type->pm)
1644 return drv->pm->runtime_resume(dev); 1829 cb = dev->type->pm->runtime_resume;
1830 else if (dev->class && dev->class->pm)
1831 cb = dev->class->pm->runtime_resume;
1832 else if (dev->bus && dev->bus->pm)
1833 cb = dev->bus->pm->runtime_resume;
1834 else
1835 cb = NULL;
1645 1836
1646 return 0; 1837 if (!cb && dev->driver && dev->driver->pm)
1838 cb = dev->driver->pm->runtime_resume;
1839
1840 return cb ? cb(dev) : 0;
1647} 1841}
1648 1842
1649#ifdef CONFIG_PM_SLEEP 1843#ifdef CONFIG_PM_SLEEP