Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PM: domains: Enable dev_pm_genpd_suspend|resume() for suspend-to-idle

The dev_pm_genpd_suspend|resume() have so far only been used during the
syscore suspend/resume phases. However, during suspend-to-idle, where the
syscore phases doesn't exist, similar operations are sometimes needed.

An existing example are the timekeeping_suspend|resume() functions, which
are being called both through a registered syscore ops during the syscore
phases, but also as regular functions calls from cpuidle (via
tick_freeze()) during suspend-to-idle.

For similar reasons, let's enable the dev_pm_genpd_suspend|resume() APIs to
be re-used for corresponding CPU devices that are attached to a genpd,
during suspend-to-idle.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Ulf Hansson and committed by
Rafael J. Wysocki
b9795a3e fc519890

+16 -4
+16 -4
drivers/base/power/domain.c
··· 1366 1366 static void genpd_switch_state(struct device *dev, bool suspend) 1367 1367 { 1368 1368 struct generic_pm_domain *genpd; 1369 + bool use_lock; 1369 1370 1370 1371 genpd = dev_to_genpd_safe(dev); 1371 1372 if (!genpd) 1372 1373 return; 1373 1374 1375 + use_lock = genpd_is_irq_safe(genpd); 1376 + 1377 + if (use_lock) 1378 + genpd_lock(genpd); 1379 + 1374 1380 if (suspend) { 1375 1381 genpd->suspended_count++; 1376 - genpd_sync_power_off(genpd, false, 0); 1382 + genpd_sync_power_off(genpd, use_lock, 0); 1377 1383 } else { 1378 - genpd_sync_power_on(genpd, false, 0); 1384 + genpd_sync_power_on(genpd, use_lock, 0); 1379 1385 genpd->suspended_count--; 1380 1386 } 1387 + 1388 + if (use_lock) 1389 + genpd_unlock(genpd); 1381 1390 } 1382 1391 1383 1392 /** ··· 1394 1385 * @dev: The device that is attached to the genpd, that can be suspended. 1395 1386 * 1396 1387 * This routine should typically be called for a device that needs to be 1397 - * suspended during the syscore suspend phase. 1388 + * suspended during the syscore suspend phase. It may also be called during 1389 + * suspend-to-idle to suspend a corresponding CPU device that is attached to a 1390 + * genpd. 1398 1391 */ 1399 1392 void dev_pm_genpd_suspend(struct device *dev) 1400 1393 { ··· 1409 1398 * @dev: The device that is attached to the genpd, which needs to be resumed. 1410 1399 * 1411 1400 * This routine should typically be called for a device that needs to be resumed 1412 - * during the syscore resume phase. 1401 + * during the syscore resume phase. It may also be called during suspend-to-idle 1402 + * to resume a corresponding CPU device that is attached to a genpd. 1413 1403 */ 1414 1404 void dev_pm_genpd_resume(struct device *dev) 1415 1405 {