From ba20bb126940ce4847e146a0d00b7f7b0868d773 Mon Sep 17 00:00:00 2001 From: Peter 'p2' De Schrijver Date: Wed, 15 Oct 2008 17:48:43 +0300 Subject: OMAP: PM counter infrastructure. This patch provides the infrastructure to count how many times a powerdomain entered a given power state (on, inactive, retention, off). A number of functions are provided which will be called by the chip specific powerdomain and clockdomain code whenever a transition might have happened. Signed-off-by: Peter 'p2' De Schrijver Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/clockdomain.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/mach-omap2/clockdomain.c') diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 0e7d501865b..26912a95dc1 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -484,6 +484,8 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm) v << __ffs(clkdm->clktrctrl_mask), clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL); + + pwrdm_clkdm_state_switch(clkdm); } /** -- cgit v1.2.3-70-g09d2 From fe617af716bc09cbbdd11ad820d5818017a9f481 Mon Sep 17 00:00:00 2001 From: Peter 'p2' De Schrijver Date: Wed, 15 Oct 2008 17:48:44 +0300 Subject: OMAP: PM: Hook into PM counters This patch modifies the clock, clockdomain and OMAP3 specific powerdomain code to call the PM counter infrastructure whenever one or more powerdomains might have changed state. Signed-off-by: Peter 'p2' De Schrijver Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/clock.c | 2 ++ arch/arm/mach-omap2/clockdomain.c | 3 +++ arch/arm/mach-omap2/pm34xx.c | 6 ++++++ 3 files changed, 11 insertions(+) (limited to 'arch/arm/mach-omap2/clockdomain.c') diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 456e2ad5f62..f2a92d614f0 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -1043,5 +1043,7 @@ void omap2_clk_disable_unused(struct clk *clk) omap2_clk_disable(clk); } else _omap2_clk_disable(clk); + if (clk->clkdm != NULL) + pwrdm_clkdm_state_switch(clk->clkdm); } #endif diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 26912a95dc1..5b0b90b76e1 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -574,6 +574,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) omap2_clkdm_wakeup(clkdm); pwrdm_wait_transition(clkdm->pwrdm.ptr); + pwrdm_clkdm_state_switch(clkdm); return 0; } @@ -626,6 +627,8 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) else omap2_clkdm_sleep(clkdm); + pwrdm_clkdm_state_switch(clkdm); + return 0; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 488d595d8e4..f1976242f99 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -170,6 +170,8 @@ static void omap_sram_idle(void) printk(KERN_ERR "Invalid mpu state in sram_idle\n"); return; } + pwrdm_pre_transition(); + omap2_gpio_prepare_for_retention(); omap_uart_prepare_idle(0); omap_uart_prepare_idle(1); @@ -182,6 +184,9 @@ static void omap_sram_idle(void) omap_uart_resume_idle(1); omap_uart_resume_idle(0); omap2_gpio_resume_after_retention(); + + pwrdm_post_transition(); + } /* @@ -271,6 +276,7 @@ static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) if (sleep_switch) { omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); pwrdm_wait_transition(pwrdm); + pwrdm_state_switch(pwrdm); } err: -- cgit v1.2.3-70-g09d2 From a23456e9b02b3fae0fc78cb33fad69803a50e5bc Mon Sep 17 00:00:00 2001 From: Peter 'p2' De Schrijver Date: Wed, 15 Oct 2008 18:13:47 +0300 Subject: OMAP: PM: Add closures to clkdm_for_each and pwrdm_for_each. Add some infrastructure to easily iterate over clock and power domains. Signed-off-by: Peter 'p2' De Schrijver Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/clockdomain.c | 5 +++-- arch/arm/mach-omap2/pm24xx.c | 4 ++-- arch/arm/mach-omap2/pm34xx.c | 8 ++++---- arch/arm/plat-omap/include/mach/clockdomain.h | 3 ++- arch/arm/plat-omap/include/mach/powerdomain.h | 3 ++- 5 files changed, 13 insertions(+), 10 deletions(-) (limited to 'arch/arm/mach-omap2/clockdomain.c') diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 5b0b90b76e1..4ef7b4f5474 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -299,7 +299,8 @@ struct clockdomain *clkdm_lookup(const char *name) * anything else to indicate failure; or -EINVAL if the function pointer * is null. */ -int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) +int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), + void *user) { struct clockdomain *clkdm; int ret = 0; @@ -309,7 +310,7 @@ int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) mutex_lock(&clkdm_mutex); list_for_each_entry(clkdm, &clkdm_list, node) { - ret = (*fn)(clkdm); + ret = (*fn)(clkdm, user); if (ret) break; } diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 528dbdc26e2..bff5c4e8974 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -333,7 +333,7 @@ static struct platform_suspend_ops omap_pm_ops = { .valid = suspend_valid_only_mem, }; -static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm) +static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm, void *unused) { omap2_clkdm_allow_idle(clkdm); return 0; @@ -385,7 +385,7 @@ static void __init prcm_setup_regs(void) omap2_clkdm_sleep(gfx_clkdm); /* Enable clockdomain hardware-supervised control for all clkdms */ - clkdm_for_each(_pm_clkdm_enable_hwsup); + clkdm_for_each(_pm_clkdm_enable_hwsup, NULL); /* Enable clock autoidle for all domains */ cm_write_mod_reg(OMAP24XX_AUTO_CAM | diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index f1976242f99..331dfca93ed 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -664,7 +664,7 @@ static void __init prcm_setup_regs(void) omap3_d2d_idle(); } -static int __init pwrdms_setup(struct powerdomain *pwrdm) +static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) { struct power_state *pwrst; @@ -689,7 +689,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) * supported. Initiate sleep transition for other clockdomains, if * they are not used */ -static int __init clkdms_setup(struct clockdomain *clkdm) +static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) { if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) omap2_clkdm_allow_idle(clkdm); @@ -722,13 +722,13 @@ static int __init omap3_pm_init(void) goto err1; } - ret = pwrdm_for_each(pwrdms_setup); + ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { printk(KERN_ERR "Failed to setup powerdomains\n"); goto err2; } - (void) clkdm_for_each(clkdms_setup); + (void) clkdm_for_each(clkdms_setup, NULL); mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); if (mpu_pwrdm == NULL) { diff --git a/arch/arm/plat-omap/include/mach/clockdomain.h b/arch/arm/plat-omap/include/mach/clockdomain.h index b9d0dd2da89..99ebd886f13 100644 --- a/arch/arm/plat-omap/include/mach/clockdomain.h +++ b/arch/arm/plat-omap/include/mach/clockdomain.h @@ -95,7 +95,8 @@ int clkdm_register(struct clockdomain *clkdm); int clkdm_unregister(struct clockdomain *clkdm); struct clockdomain *clkdm_lookup(const char *name); -int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)); +int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), + void *user); struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm); void omap2_clkdm_allow_idle(struct clockdomain *clkdm); diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h index 52663fc549d..de03f3dbbf3 100644 --- a/arch/arm/plat-omap/include/mach/powerdomain.h +++ b/arch/arm/plat-omap/include/mach/powerdomain.h @@ -128,7 +128,8 @@ int pwrdm_register(struct powerdomain *pwrdm); int pwrdm_unregister(struct powerdomain *pwrdm); struct powerdomain *pwrdm_lookup(const char *name); -int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)); +int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), + void *user); int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); -- cgit v1.2.3-70-g09d2