* [PATCH] PM / sh7372: Make domain stay_on bit only affect system suspend
@ 2011-12-04 22:08 Rafael J. Wysocki
2011-12-05 0:17 ` Rafael J. Wysocki
0 siblings, 1 reply; 3+ messages in thread
From: Rafael J. Wysocki @ 2011-12-04 22:08 UTC (permalink / raw)
To: Linux PM list; +Cc: LKML, Linux-sh list, Magnus Damm, Guennadi Liakhovetski
From: Rafael J. Wysocki <rjw@sisk.pl>
SH7372 uses two independent mechanisms for ensuring that power
domains will never be turned off: the stay_on flag and the "always
on" domain governor. However, the "always on" governor is only taken
into accout by runtime PM code paths, while the stay_on flag affects
all attempts to turn the given domain off. This is a problem for
domains that only need to stay in the "power on" state during system
sleep, but may be turned off by runtime PM if specific conditions are
satisfied. For this reason, make SH7372 register a PM notifier that
will enable the checking of the domain stay_on flag on during system
suspend and disable it during system resume. This way, the stay_on
flag will only affect system sleep states, while the "always on"
governor will only affect runtime PM.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
This patch is on top of linux-pm/pm-domains.
Thanks,
Rafael
---
arch/arm/mach-shmobile/pm-sh7372.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
Index: linux/arch/arm/mach-shmobile/pm-sh7372.c
=================================--- linux.orig/arch/arm/mach-shmobile/pm-sh7372.c
+++ linux/arch/arm/mach-shmobile/pm-sh7372.c
@@ -77,6 +77,8 @@
#ifdef CONFIG_PM
+static bool system_pm_transition;
+
static int pd_power_down(struct generic_pm_domain *genpd)
{
struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
@@ -85,7 +87,7 @@ static int pd_power_down(struct generic_
if (sh7372_pd->suspend)
sh7372_pd->suspend();
- if (sh7372_pd->stay_on)
+ if (system_pm_transition && sh7372_pd->stay_on)
return 0;
if (__raw_readl(PSTR) & mask) {
@@ -286,6 +288,21 @@ struct sh7372_pm_domain sh7372_a3sg = {
.bit_shift = 13,
};
+static int sh7372_pm_notifier_fn(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ system_pm_transition = true;
+ break;
+ case PM_POST_SUSPEND:
+ system_pm_transition = false;
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
#else /* !CONFIG_PM */
static inline void sh7372_a3sp_init(void) {}
@@ -509,6 +526,7 @@ static int sh7372_enter_suspend(suspend_
static void sh7372_suspend_init(void)
{
shmobile_suspend_ops.enter = sh7372_enter_suspend;
+ pm_notifier(sh7372_pm_notifier_fn, 0);
}
#else
static void sh7372_suspend_init(void) {}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] PM / sh7372: Make domain stay_on bit only affect system suspend
2011-12-04 22:08 [PATCH] PM / sh7372: Make domain stay_on bit only affect system suspend Rafael J. Wysocki
@ 2011-12-05 0:17 ` Rafael J. Wysocki
2011-12-05 0:21 ` [Update][PATCH] " Rafael J. Wysocki
0 siblings, 1 reply; 3+ messages in thread
From: Rafael J. Wysocki @ 2011-12-05 0:17 UTC (permalink / raw)
To: Linux PM list; +Cc: LKML, Linux-sh list, Magnus Damm, Guennadi Liakhovetski
On Sunday, December 04, 2011, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> SH7372 uses two independent mechanisms for ensuring that power
> domains will never be turned off: the stay_on flag and the "always
> on" domain governor. However, the "always on" governor is only taken
> into accout by runtime PM code paths, while the stay_on flag affects
> all attempts to turn the given domain off. This is a problem for
> domains that only need to stay in the "power on" state during system
> sleep, but may be turned off by runtime PM if specific conditions are
> satisfied. For this reason, make SH7372 register a PM notifier that
> will enable the checking of the domain stay_on flag on during system
> suspend and disable it during system resume. This way, the stay_on
> flag will only affect system sleep states, while the "always on"
> governor will only affect runtime PM.
Well, it's not that simple, because we need to make the domains that
should stay "on" during system suspend be powered on beforehand.
I'll send an updated patch in a while.
Thanks,
Rafael
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Update][PATCH] PM / sh7372: Make domain stay_on bit only affect system suspend
2011-12-05 0:17 ` Rafael J. Wysocki
@ 2011-12-05 0:21 ` Rafael J. Wysocki
0 siblings, 0 replies; 3+ messages in thread
From: Rafael J. Wysocki @ 2011-12-05 0:21 UTC (permalink / raw)
To: Linux-sh list; +Cc: Linux PM list, LKML, Magnus Damm, Guennadi Liakhovetski
From: Rafael J. Wysocki <rjw@sisk.pl>
SH7372 uses two independent mechanisms for ensuring that power
domains will never be turned off: the stay_on flag and the "always
on" domain governor. However, the "always on" governor is only taken
into accout by runtime PM code paths, while the stay_on flag affects
all attempts to turn the given domain off. This is a problem for
domains that only need to stay in the "power on" state during system
sleep, but may be turned off by runtime PM if specific conditions are
satisfied.
For this reason, make SH7372 register a PM notifier that will enable
the checking of the domain stay_on flag on during system suspend and
disable it during system resume. This way, the stay_on flag will
only affect system sleep states, while the "always on" governor will
only affect runtime PM.
In addition to that, make sure that all domains which should be in
the "power on" state during system sleep are turned on beforehand, by
executing pm_genpd_poweron() for all of them.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
arch/arm/mach-shmobile/pm-sh7372.c | 34 +++++++++++++++++++++++++++++++---
drivers/base/power/domain.c | 28 ++++++++++++++++++++--------
include/linux/pm_domain.h | 4 ++++
3 files changed, 55 insertions(+), 11 deletions(-)
Index: linux/arch/arm/mach-shmobile/pm-sh7372.c
=================================--- linux.orig/arch/arm/mach-shmobile/pm-sh7372.c
+++ linux/arch/arm/mach-shmobile/pm-sh7372.c
@@ -77,6 +77,8 @@
#ifdef CONFIG_PM
+static bool system_pm_transition;
+
static int pd_power_down(struct generic_pm_domain *genpd)
{
struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
@@ -85,8 +87,8 @@ static int pd_power_down(struct generic_
if (sh7372_pd->suspend)
sh7372_pd->suspend();
- if (sh7372_pd->stay_on)
- return 0;
+ if (system_pm_transition && sh7372_pd->stay_on)
+ return -EBUSY;
if (__raw_readl(PSTR) & mask) {
unsigned int retry_count;
@@ -113,7 +115,7 @@ static int __pd_power_up(struct sh7372_p
unsigned int retry_count;
int ret = 0;
- if (sh7372_pd->stay_on)
+ if (sh7372_pd->genpd.status != GPD_STATE_POWER_OFF)
goto out;
if (__raw_readl(PSTR) & mask)
@@ -506,9 +508,35 @@ static int sh7372_enter_suspend(suspend_
return 0;
}
+static void sh7372_pm_power_on_for_suspend(struct generic_pm_domain *genpd)
+{
+ struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
+
+ if (sh7372_pd->stay_on)
+ pm_genpd_poweron(genpd);
+}
+
+static int sh7372_pm_notifier_fn(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ system_pm_transition = true;
+ pm_genpd_for_each_domain(sh7372_pm_power_on_for_suspend);
+ break;
+ case PM_POST_SUSPEND:
+ system_pm_transition = false;
+ pm_genpd_poweroff_unused();
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
static void sh7372_suspend_init(void)
{
shmobile_suspend_ops.enter = sh7372_enter_suspend;
+ pm_notifier(sh7372_pm_notifier_fn, 0);
}
#else
static void sh7372_suspend_init(void) {}
Index: linux/drivers/base/power/domain.c
=================================--- linux.orig/drivers/base/power/domain.c
+++ linux/drivers/base/power/domain.c
@@ -243,6 +243,25 @@ int pm_genpd_poweron(struct generic_pm_d
return ret;
}
+/**
+ * pm_genpd_for_each_domain - Execute function for each generic PM domain.
+ * @fun: Function to execute.
+ */
+void pm_genpd_for_each_domain(void (*fun)(struct generic_pm_domain *))
+{
+ struct generic_pm_domain *genpd;
+
+ if (!fun)
+ return;
+
+ mutex_lock(&gpd_list_lock);
+
+ list_for_each_entry(genpd, &gpd_list, gpd_list_node)
+ fun(genpd);
+
+ mutex_unlock(&gpd_list_lock);
+}
+
#endif /* CONFIG_PM */
#ifdef CONFIG_PM_RUNTIME
@@ -598,14 +617,7 @@ static int pm_genpd_runtime_resume(struc
*/
void pm_genpd_poweroff_unused(void)
{
- struct generic_pm_domain *genpd;
-
- mutex_lock(&gpd_list_lock);
-
- list_for_each_entry(genpd, &gpd_list, gpd_list_node)
- genpd_queue_power_off_work(genpd);
-
- mutex_unlock(&gpd_list_lock);
+ pm_genpd_for_each_domain(genpd_queue_power_off_work);
}
#else
Index: linux/include/linux/pm_domain.h
=================================--- linux.orig/include/linux/pm_domain.h
+++ linux/include/linux/pm_domain.h
@@ -137,6 +137,7 @@ extern void pm_genpd_init(struct generic
struct dev_power_governor *gov, bool is_off);
extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
+extern void pm_genpd_for_each_domain(void (*fun)(struct generic_pm_domain *));
extern bool default_stop_ok(struct device *dev);
@@ -189,6 +190,9 @@ static inline int pm_genpd_poweron(struc
{
return -ENOSYS;
}
+static inline void pm_genpd_for_each_domain(void (*fun)(struct generic_pm_domain *))
+{
+}
static inline bool default_stop_ok(struct device *dev)
{
return false;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-12-05 0:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-04 22:08 [PATCH] PM / sh7372: Make domain stay_on bit only affect system suspend Rafael J. Wysocki
2011-12-05 0:17 ` Rafael J. Wysocki
2011-12-05 0:21 ` [Update][PATCH] " Rafael J. Wysocki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).