aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/power/domain.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 84f4beefa4f8..b6ff6ecf519d 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -366,7 +366,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
366 not_suspended = 0; 366 not_suspended = 0;
367 list_for_each_entry(pdd, &genpd->dev_list, list_node) 367 list_for_each_entry(pdd, &genpd->dev_list, list_node)
368 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev) 368 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
369 || pdd->dev->power.irq_safe)) 369 || pdd->dev->power.irq_safe || to_gpd_data(pdd)->always_on))
370 not_suspended++; 370 not_suspended++;
371 371
372 if (not_suspended > genpd->in_progress) 372 if (not_suspended > genpd->in_progress)
@@ -503,6 +503,9 @@ static int pm_genpd_runtime_suspend(struct device *dev)
503 503
504 might_sleep_if(!genpd->dev_irq_safe); 504 might_sleep_if(!genpd->dev_irq_safe);
505 505
506 if (dev_gpd_data(dev)->always_on)
507 return -EBUSY;
508
506 stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; 509 stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
507 if (stop_ok && !stop_ok(dev)) 510 if (stop_ok && !stop_ok(dev))
508 return -EBUSY; 511 return -EBUSY;
@@ -859,7 +862,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
859 if (IS_ERR(genpd)) 862 if (IS_ERR(genpd))
860 return -EINVAL; 863 return -EINVAL;
861 864
862 if (genpd->suspend_power_off 865 if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on
863 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))) 866 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
864 return 0; 867 return 0;
865 868
@@ -892,7 +895,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
892 if (IS_ERR(genpd)) 895 if (IS_ERR(genpd))
893 return -EINVAL; 896 return -EINVAL;
894 897
895 if (genpd->suspend_power_off 898 if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on
896 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))) 899 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
897 return 0; 900 return 0;
898 901
@@ -1012,7 +1015,8 @@ static int pm_genpd_freeze_noirq(struct device *dev)
1012 if (IS_ERR(genpd)) 1015 if (IS_ERR(genpd))
1013 return -EINVAL; 1016 return -EINVAL;
1014 1017
1015 return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev); 1018 return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ?
1019 0 : genpd_stop_dev(genpd, dev);
1016} 1020}
1017 1021
1018/** 1022/**
@@ -1032,7 +1036,8 @@ static int pm_genpd_thaw_noirq(struct device *dev)
1032 if (IS_ERR(genpd)) 1036 if (IS_ERR(genpd))
1033 return -EINVAL; 1037 return -EINVAL;
1034 1038
1035 return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev); 1039 return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ?
1040 0 : genpd_start_dev(genpd, dev);
1036} 1041}
1037 1042
1038/** 1043/**
@@ -1124,7 +1129,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
1124 1129
1125 pm_genpd_poweron(genpd); 1130 pm_genpd_poweron(genpd);
1126 1131
1127 return genpd_start_dev(genpd, dev); 1132 return dev_gpd_data(dev)->always_on ? 0 : genpd_start_dev(genpd, dev);
1128} 1133}
1129 1134
1130/** 1135/**
@@ -1320,6 +1325,26 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1320} 1325}
1321 1326
1322/** 1327/**
1328 * pm_genpd_dev_always_on - Set/unset the "always on" flag for a given device.
1329 * @dev: Device to set/unset the flag for.
1330 * @val: The new value of the device's "always on" flag.
1331 */
1332void pm_genpd_dev_always_on(struct device *dev, bool val)
1333{
1334 struct pm_subsys_data *psd;
1335 unsigned long flags;
1336
1337 spin_lock_irqsave(&dev->power.lock, flags);
1338
1339 psd = dev_to_psd(dev);
1340 if (psd && psd->domain_data)
1341 to_gpd_data(psd->domain_data)->always_on = val;
1342
1343 spin_unlock_irqrestore(&dev->power.lock, flags);
1344}
1345EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on);
1346
1347/**
1323 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. 1348 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1324 * @genpd: Master PM domain to add the subdomain to. 1349 * @genpd: Master PM domain to add the subdomain to.
1325 * @subdomain: Subdomain to be added. 1350 * @subdomain: Subdomain to be added.