diff options
author | Magnus Damm <damm@opensource.se> | 2011-10-19 23:52:50 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-10-22 00:20:12 +0200 |
commit | 382414b93ac1e8ee7693be710e60c83eacc97c6f (patch) | |
tree | 2b57a165a295af5468c611c553a9401a81f4b300 /arch/arm/mach-shmobile/pm-sh7372.c | |
parent | d93f5cdea968284f05aa9905ee9752874885a6fa (diff) |
ARM: mach-shmobile: sh7372 A4R support (v4)
This change adds support for the sh7372 A4R power domain.
The sh7372 A4R hardware power domain contains the
SH CPU Core and a set of I/O devices including
multimedia accelerators and I2C controllers.
One special case about A4R is the INTCS interrupt
controller that needs to be saved and restored to
keep working as expected. Also the LCDC hardware
blocks are in a different hardware power domain
but have their IRQs routed only through INTCS. So
as long as LCDCs are active we cannot power down
INTCS because that would risk losing interrupts.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch/arm/mach-shmobile/pm-sh7372.c')
-rw-r--r-- | arch/arm/mach-shmobile/pm-sh7372.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index fde619dd4c05..79612737c5b2 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -44,6 +44,7 @@ #define SPDCR 0xe6180008 #define SWUCR 0xe6180014 #define SBAR 0xe6180020 +#define WUPRMSK 0xe6180028 #define WUPSMSK 0xe618002c #define WUPSMSK2 0xe6180048 #define PSTR 0xe6180080 @@ -80,6 +81,12 @@ static int pd_power_down(struct generic_pm_domain *genpd) struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); unsigned int mask = 1 << sh7372_pd->bit_shift; + if (sh7372_pd->suspend) + sh7372_pd->suspend(); + + if (sh7372_pd->stay_on) + return 0; + if (__raw_readl(PSTR) & mask) { unsigned int retry_count; @@ -106,6 +113,9 @@ static int pd_power_up(struct generic_pm_domain *genpd) unsigned int retry_count; int ret = 0; + if (sh7372_pd->stay_on) + goto out; + if (__raw_readl(PSTR) & mask) goto out; @@ -122,14 +132,23 @@ static int pd_power_up(struct generic_pm_domain *genpd) if (__raw_readl(SWUCR) & mask) ret = -EIO; - out: if (!sh7372_pd->no_debug) pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n", mask, __raw_readl(PSTR)); + out: + if (ret == 0 && sh7372_pd->resume) + sh7372_pd->resume(); + return ret; } +static void sh7372_a4r_suspend(void) +{ + sh7372_intcs_suspend(); + __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */ +} + static bool pd_active_wakeup(struct device *dev) { return true; @@ -186,6 +205,14 @@ struct sh7372_pm_domain sh7372_d4 = { .bit_shift = 3, }; +struct sh7372_pm_domain sh7372_a4r = { + .bit_shift = 5, + .gov = &sh7372_always_on_gov, + .suspend = sh7372_a4r_suspend, + .resume = sh7372_intcs_resume, + .stay_on = true, +}; + struct sh7372_pm_domain sh7372_a3rv = { .bit_shift = 6, }; |