From f721889ff65afa6243c463832c74dee3bed418d5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 1 Jul 2011 22:12:45 +0200 Subject: PM / Domains: Support for generic I/O PM domains (v8) Introduce common headers, helper functions and callbacks allowing platforms to use simple generic power domains for runtime power management. Introduce struct generic_pm_domain to be used for representing power domains that each contain a number of devices and may be parent domains or subdomains with respect to other power domains. Among other things, this structure includes callbacks to be provided by platforms for performing specific tasks related to power management (i.e. ->stop_device() may disable a device's clocks, while ->start_device() may enable them, ->power_off() is supposed to remove power from the entire power domain and ->power_on() is supposed to restore it). Introduce functions that can be used as power domain runtime PM callbacks, pm_genpd_runtime_suspend() and pm_genpd_runtime_resume(), as well as helper functions for the initialization of a power domain represented by a struct generic_power_domain object, adding a device to or removing a device from it and adding or removing subdomains. Introduce configuration option CONFIG_PM_GENERIC_DOMAINS to be selected by the platforms that want to use the new code. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Reviewed-by: Kevin Hilman --- kernel/power/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel/power') diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 87f4d24b55b0..e83ac2556c86 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -227,3 +227,7 @@ config PM_OPP config PM_RUNTIME_CLK def_bool y depends on PM_RUNTIME && HAVE_CLK + +config PM_GENERIC_DOMAINS + bool + depends on PM -- cgit v1.2.3 From b7b95920aa2e89e655afe9913ee0e55855ceda90 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 1 Jul 2011 22:13:37 +0200 Subject: PM: Allow the clocks management code to be used during system suspend The common clocks management code in drivers/base/power/clock_ops.c is going to be used during system-wide power transitions as well as for runtime PM, so it shouldn't depend on CONFIG_PM_RUNTIME. However, the suspend/resume functions provided by it for CONFIG_PM_RUNTIME unset, to be used during system-wide power transitions, should not behave in the same way as their counterparts defined for CONFIG_PM_RUNTIME set, because in that case the clocks are managed differently at run time. The names of the functions still contain the word "runtime" after this change, but that is going to be modified by a separate patch later. Signed-off-by: Rafael J. Wysocki Reviewed-by: Kevin Hilman --- drivers/base/power/clock_ops.c | 60 +++++++++++++++++++++++++++++++++++++++++- include/linux/pm_runtime.h | 2 +- kernel/power/Kconfig | 4 +-- 3 files changed, 62 insertions(+), 4 deletions(-) (limited to 'kernel/power') diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index c5624818259e..2fb9c121c64b 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -15,7 +15,7 @@ #include #include -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM struct pm_runtime_clk_data { struct list_head clock_list; @@ -191,6 +191,10 @@ void pm_runtime_clk_destroy(struct device *dev) kfree(prd); } +#endif /* CONFIG_PM */ + +#ifdef CONFIG_PM_RUNTIME + /** * pm_runtime_clk_acquire - Acquire a device clock. * @dev: Device whose clock is to be acquired. @@ -330,6 +334,60 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, #else /* !CONFIG_PM_RUNTIME */ +#ifdef CONFIG_PM + +/** + * pm_runtime_clk_suspend - Disable clocks in a device's PM clock list. + * @dev: Device to disable the clocks for. + */ +int pm_runtime_clk_suspend(struct device *dev) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce; + + dev_dbg(dev, "%s()\n", __func__); + + /* If there is no driver, the clocks are already disabled. */ + if (!prd || !dev->driver) + return 0; + + mutex_lock(&prd->lock); + + list_for_each_entry_reverse(ce, &prd->clock_list, node) + clk_disable(ce->clk); + + mutex_unlock(&prd->lock); + + return 0; +} + +/** + * pm_runtime_clk_resume - Enable clocks in a device's PM clock list. + * @dev: Device to enable the clocks for. + */ +int pm_runtime_clk_resume(struct device *dev) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce; + + dev_dbg(dev, "%s()\n", __func__); + + /* If there is no driver, the clocks should remain disabled. */ + if (!prd || !dev->driver) + return 0; + + mutex_lock(&prd->lock); + + list_for_each_entry(ce, &prd->clock_list, node) + clk_enable(ce->clk); + + mutex_unlock(&prd->lock); + + return 0; +} + +#endif /* CONFIG_PM */ + /** * enable_clock - Enable a device clock. * @dev: Device whose clock is to be enabled. diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index ef91904c7110..1bd5063a2cc8 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -251,7 +251,7 @@ struct pm_clk_notifier_block { char *con_ids[]; }; -#ifdef CONFIG_PM_RUNTIME_CLK +#ifdef CONFIG_PM_CLK extern int pm_runtime_clk_init(struct device *dev); extern void pm_runtime_clk_destroy(struct device *dev); extern int pm_runtime_clk_add(struct device *dev, const char *con_id); diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index e83ac2556c86..7b856b3458d2 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -224,9 +224,9 @@ config PM_OPP implementations a ready to use framework to manage OPPs. For more information, read -config PM_RUNTIME_CLK +config PM_CLK def_bool y - depends on PM_RUNTIME && HAVE_CLK + depends on PM && HAVE_CLK config PM_GENERIC_DOMAINS bool -- cgit v1.2.3