On Monday, May 14, 2012, Marek Szyprowski wrote: > Hello, > > On 5/14/2012 9:04 PM, Rafael J. Wysocki wrote: > > On Monday, May 14, 2012, Marek Szyprowski wrote: [...] > >> I'm fine with this solution. Thanks for your help! > > > > OK, no problem. > > > > Do you want me to apply the patch literally in the above form or should I skip > > the arch/arm/mach-exynos/pm_domains.c change for now? > > Yes, please skip arch/arm/mach-exynos/pm_domains.c part. We will handle > it with a separate patch on Samsung tree. OK, so below it goes again without that hunk and with a changelog. Thanks, Rafael --- From: Rafael J. Wysocki <rjw@xxxxxxx> Subject: PM / Domains: Make it possible to add devices to inactive domains The generic PM domains core code currently requires domains to be in the "power on" state for adding devices to them, but this limitation turns out to be inconvenient in some situations, so remove it. For this purpose, make __pm_genpd_add_device() set the device's need_restore flag if the domain is in the "power off" state, so that the device's "restore state" (usually .runtime_resume()) callback is executed when it is resumed after the domain has been turned on. If the domain is in the "power on" state, the device's need_restore flag will be cleared by __pm_genpd_add_device(), so that its "save state" (usually .runtime_suspend()) callback is executed when the domain is about to be turned off. However, since that default behavior need not be always desirable, add a helper function pm_genpd_dev_need_restore() allowing a device's need_restore flag to be set/unset at any time. Signed-off-by: Rafael J. Wysocki <rjw@xxxxxxx> --- arch/arm/mach-exynos/pm_domains.c | 2 ++ drivers/base/power/domain.c | 27 +++++++++++++++++++++------ include/linux/pm_domain.h | 2 ++ 3 files changed, 25 insertions(+), 6 deletions(-) Index: linux/drivers/base/power/domain.c =================================================================== --- linux.orig/drivers/base/power/domain.c +++ linux/drivers/base/power/domain.c @@ -1269,11 +1269,6 @@ int __pm_genpd_add_device(struct generic genpd_acquire_lock(genpd); - if (genpd->status == GPD_STATE_POWER_OFF) { - ret = -EINVAL; - goto out; - } - if (genpd->prepared_count > 0) { ret = -EAGAIN; goto out; @@ -1296,7 +1291,7 @@ int __pm_genpd_add_device(struct generic dev->power.subsys_data->domain_data = &gpd_data->base; gpd_data->base.dev = dev; list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); - gpd_data->need_restore = false; + gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF; if (td) gpd_data->td = *td; @@ -1424,6 +1419,26 @@ void pm_genpd_dev_always_on(struct devic EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on); /** + * pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag. + * @dev: Device to set/unset the flag for. + * @val: The new value of the device's "need restore" flag. + */ +void pm_genpd_dev_need_restore(struct device *dev, bool val) +{ + struct pm_subsys_data *psd; + unsigned long flags; + + spin_lock_irqsave(&dev->power.lock, flags); + + psd = dev_to_psd(dev); + if (psd && psd->domain_data) + to_gpd_data(psd->domain_data)->need_restore = val; + + spin_unlock_irqrestore(&dev->power.lock, flags); +} +EXPORT_SYMBOL_GPL(pm_genpd_dev_need_restore); + +/** * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. * @genpd: Master PM domain to add the subdomain to. * @subdomain: Subdomain to be added. Index: linux/include/linux/pm_domain.h =================================================================== --- linux.orig/include/linux/pm_domain.h +++ linux/include/linux/pm_domain.h @@ -146,6 +146,7 @@ static inline int pm_genpd_of_add_device extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev); extern void pm_genpd_dev_always_on(struct device *dev, bool val); +extern void pm_genpd_dev_need_restore(struct device *dev, bool val); extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *new_subdomain); extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, @@ -189,6 +190,7 @@ static inline int pm_genpd_remove_device return -ENOSYS; } static inline void pm_genpd_dev_always_on(struct device *dev, bool val) {} +static inline void pm_genpd_dev_need_restore(struct device *dev, bool val) {} static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *new_sd) { -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html