In clkdm_sleep(), the powerdomain should be eligible to switch power
states right after the call to the low-level clockdomain sleep
function. We should have been tracking that with the
pwrdm_state_switch() code, but we weren't, for whatever reason. Fix that.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clockdomain.c | 1 +
1 file changed, 1 insertion(+)
Fix the following sparse warnings in the OMAP3/4 CPUIdle code:
arch/arm/mach-omap2/cpuidle34xx.c:272:1: warning: symbol 'omap3_idle_dev' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle34xx.c:274:23: warning: symbol 'omap3_idle_driver' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:164:1: warning: symbol 'omap4_idle_dev' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:166:23: warning: symbol 'omap4_idle_driver' was not declared. Should it be static?
Also fix the following checkpatch warnings:
WARNING: please, no space before tabs
#44: FILE: arch/arm/mach-omap2/cpuidle34xx.c:105:
+^I.name = ^I"omap3_idle",$
WARNING: please, no space before tabs
#45: FILE: arch/arm/mach-omap2/cpuidle34xx.c:106:
+^I.owner = ^ITHIS_MODULE,$
ERROR: code indent should use tabs where possible
#211: FILE: arch/arm/mach-omap2/cpuidle44xx.c:74:
+ /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */$
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/cpuidle34xx.c | 14 +++++++++-----
arch/arm/mach-omap2/cpuidle44xx.c | 28 ++++++++++++++++------------
2 files changed, 25 insertions(+), 17 deletions(-)
Fix the following sparse warnings in the OMAP3/4 CPUIdle code:
arch/arm/mach-omap2/cpuidle34xx.c:272:1: warning: symbol 'omap3_idle_dev' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle34xx.c:274:23: warning: symbol 'omap3_idle_driver' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:164:1: warning: symbol 'omap4_idle_dev' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:166:23: warning: symbol 'omap4_idle_driver' was not declared. Should it be static?
Also fix the following checkpatch warnings:
WARNING: please, no space before tabs
#44: FILE: arch/arm/mach-omap2/cpuidle34xx.c:105:
+^I.name = ^I"omap3_idle",$
WARNING: please, no space before tabs
#45: FILE: arch/arm/mach-omap2/cpuidle34xx.c:106:
+^I.owner = ^ITHIS_MODULE,$
ERROR: code indent should use tabs where possible
#211: FILE: arch/arm/mach-omap2/cpuidle44xx.c:74:
+ /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */$
Paul,
I am using your "paul-linux-pwrdm_post_fpwrst_devel_a_3.9" branch, where
all the patches which you have posted are present (I believe so) and I
am getting following sparse warning -
CHECK arch/arm/mach-omap2/powerdomain.c
arch/arm/mach-omap2/powerdomain.c:811:2: warning: context imbalance in
'pwrdm_lock': unexpected unlock
arch/arm/mach-omap2/powerdomain.c:811:2: default context: wanted 1, got 0
include/linux/spinlock.h:340:2: warning: context problem in
'pwrdm_unlock': '_raw_spin_unlock_irqrestore' expected different context
include/linux/spinlock.h:340:2: context 'lock': wanted >= 1, got 0
arch/arm/mach-omap2/powerdomain.c:1130:14: warning: context problem in
'pwrdm_state_switch': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1130:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1295:14: warning: context problem in
'pwrdm_set_next_fpwrst': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1295:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1317:14: warning: context problem in
'pwrdm_read_next_fpwrst': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1317:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1382:14: warning: context problem in
'pwrdm_set_fpwrst': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1382:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1407:14: warning: context problem in
'pwrdm_read_fpwrst': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1407:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1432:14: warning: context problem in
'pwrdm_read_prev_fpwrst': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1432:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1505:14: warning: context problem in
'pwrdm_dbg_show_counter': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1505:14: default context: wanted >=
1, got 0
arch/arm/mach-omap2/powerdomain.c:1542:14: warning: context problem in
'pwrdm_dbg_show_timer': 'pwrdm_unlock' expected different context
arch/arm/mach-omap2/powerdomain.c:1542:14: default context: wanted >=
1, got 0
CC arch/arm/mach-omap2/powerdomain.o
On the other hand, I have boot tested it on BeagleBone platform.
Thanks,
Vaibhav
I am using your "paul-linux-pwrdm_post_fpwrst_devel_a_3.9" branch, where
all the patches which you have posted are present (I believe so) and I
am getting following sparse warning -
The branch name to use is:
"TEST_pwrdm_post_fpwrst_devel_a_3.9"
- Paul
On Thu, Dec 13, 2012 at 11:11:49, Paul Walmsley wrote:
On Wed, 12 Dec 2012, Vaibhav Hiremath wrote:
quoted
I am using your "paul-linux-pwrdm_post_fpwrst_devel_a_3.9" branch, where
all the patches which you have posted are present (I believe so) and I
am getting following sparse warning -
The branch name to use is:
"TEST_pwrdm_post_fpwrst_devel_a_3.9"
If I am correct, it only includes one additional patch (merge commit),
right???
commit d94831e0005fee743cefd28f4c20b7c435c71236
Merge: 3e885c6 80ab3b2
Author: Paul Walmsley [off-list ref]
Date: Sun Dec 9 13:06:51 2012 -0700
build fixes
Does this also fix sparse warnings?
Thanks,
Vaibhav
On Thu, Dec 13, 2012 at 11:11:49, Paul Walmsley wrote:
quoted
The branch name to use is:
"TEST_pwrdm_post_fpwrst_devel_a_3.9"
If I am correct, it only includes one additional patch (merge commit),
right???
commit d94831e0005fee743cefd28f4c20b7c435c71236
Merge: 3e885c6 80ab3b2
Author: Paul Walmsley [off-list ref]
Date: Sun Dec 9 13:06:51 2012 -0700
build fixes
Does this also fix sparse warnings?
Just ran a quick sparse check on mach-omap2 at 3e885c6 and d94831e with
'make -j4 C=2 arch/arm/mach-omap2', and no warnings showed up. There were
some sparse issues that got fixed at an earlier point, though, so perhaps
you have an older copy of the branches somehow?
- Paul
paul at dusk:/kernel/kernel/current$ git log -1
commit d94831e0005fee743cefd28f4c20b7c435c71236
Merge: 3e885c6 80ab3b2
Author: Paul Walmsley [off-list ref]
Date: Sun Dec 9 13:06:51 2012 -0700
build fixes
paul at dusk:/kernel/kernel/current$ make C=2 -j4 arch/arm/mach-omap2/
CHK include/generated/uapi/linux/version.h
CHECK scripts/mod/empty.c
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
CC kernel/bounds.s
GEN include/generated/bounds.h
CC arch/arm/kernel/asm-offsets.s
GEN include/generated/asm-offsets.h
CALL scripts/checksyscalls.sh
CHECK arch/arm/mach-omap2/id.c
CHECK arch/arm/mach-omap2/io.c
CHECK arch/arm/mach-omap2/control.c
CHECK arch/arm/mach-omap2/mux.c
CC arch/arm/mach-omap2/id.o
CC arch/arm/mach-omap2/control.o
CC arch/arm/mach-omap2/io.o
CC arch/arm/mach-omap2/mux.o
CHECK arch/arm/mach-omap2/devices.c
CHECK arch/arm/mach-omap2/serial.c
CHECK arch/arm/mach-omap2/gpmc.c
CC arch/arm/mach-omap2/devices.o
CC arch/arm/mach-omap2/serial.o
CC arch/arm/mach-omap2/gpmc.o
CHECK arch/arm/mach-omap2/timer.c
CHECK arch/arm/mach-omap2/pm.c
CC arch/arm/mach-omap2/timer.o
CC arch/arm/mach-omap2/pm.o
CHECK arch/arm/mach-omap2/common.c
CC arch/arm/mach-omap2/common.o
CHECK arch/arm/mach-omap2/gpio.c
CC arch/arm/mach-omap2/gpio.o
CHECK arch/arm/mach-omap2/dma.c
CC arch/arm/mach-omap2/dma.o
CHECK arch/arm/mach-omap2/wd_timer.c
CHECK arch/arm/mach-omap2/display.c
CHECK arch/arm/mach-omap2/i2c.c
CC arch/arm/mach-omap2/wd_timer.o
CC arch/arm/mach-omap2/i2c.o
CC arch/arm/mach-omap2/display.o
CHECK arch/arm/mach-omap2/hdq1w.c
CC arch/arm/mach-omap2/hdq1w.o
CHECK arch/arm/mach-omap2/omap_hwmod.c
CHECK arch/arm/mach-omap2/omap_device.c
CC arch/arm/mach-omap2/omap_hwmod.o
CC arch/arm/mach-omap2/omap_device.o
CHECK arch/arm/mach-omap2/irq.c
CHECK arch/arm/mach-omap2/omap_hwmod_common_data.c
CC arch/arm/mach-omap2/irq.o
CC arch/arm/mach-omap2/omap_hwmod_common_data.o
CHECK arch/arm/mach-omap2/omap-secure.c
CC arch/arm/mach-omap2/omap-secure.o
CHECK arch/arm/mach-omap2/prm44xx.c
CHECK arch/arm/mach-omap2/mcbsp.c
CC arch/arm/mach-omap2/prm44xx.o
CC arch/arm/mach-omap2/mcbsp.o
CHECK arch/arm/mach-omap2/omap_twl.c
CC arch/arm/mach-omap2/omap_twl.o
CHECK arch/arm/mach-omap2/sdrc.c
CC arch/arm/mach-omap2/sdrc.o
CHECK arch/arm/mach-omap2/omap-smp.c
CHECK arch/arm/mach-omap2/omap-hotplug.c
CC arch/arm/mach-omap2/omap-smp.o
CC arch/arm/mach-omap2/omap-hotplug.o
CHECK arch/arm/mach-omap2/omap4-common.c
CC arch/arm/mach-omap2/omap4-common.o
CHECK arch/arm/mach-omap2/omap-wakeupgen.c
AS arch/arm/mach-omap2/sram242x.o
AS arch/arm/mach-omap2/sram243x.o
CC arch/arm/mach-omap2/omap-wakeupgen.o
AS arch/arm/mach-omap2/sram34xx.o
CHECK arch/arm/mach-omap2/omap2-restart.c
CHECK arch/arm/mach-omap2/omap3-restart.c
CC arch/arm/mach-omap2/omap2-restart.o
CC arch/arm/mach-omap2/omap3-restart.o
CHECK arch/arm/mach-omap2/mux2420.c
CC arch/arm/mach-omap2/mux2420.o
CHECK arch/arm/mach-omap2/mux2430.c
CHECK arch/arm/mach-omap2/mux34xx.c
CHECK arch/arm/mach-omap2/mux44xx.c
CC arch/arm/mach-omap2/mux2430.o
CC arch/arm/mach-omap2/mux34xx.o
CC arch/arm/mach-omap2/mux44xx.o
CHECK arch/arm/mach-omap2/sdrc2xxx.c
CHECK arch/arm/mach-omap2/opp.c
CC arch/arm/mach-omap2/sdrc2xxx.o
CC arch/arm/mach-omap2/opp.o
CHECK arch/arm/mach-omap2/opp3xxx_data.c
CHECK arch/arm/mach-omap2/opp4xxx_data.c
CC arch/arm/mach-omap2/opp3xxx_data.o
CC arch/arm/mach-omap2/opp4xxx_data.o
CHECK arch/arm/mach-omap2/pm24xx.c
AS arch/arm/mach-omap2/sleep24xx.o
CHECK arch/arm/mach-omap2/pm34xx.c
AS arch/arm/mach-omap2/sleep34xx.o
CHECK arch/arm/mach-omap2/pm44xx.c
CC arch/arm/mach-omap2/pm24xx.o
CHECK arch/arm/mach-omap2/omap-mpuss-lowpower.c
CC arch/arm/mach-omap2/pm34xx.o
CC arch/arm/mach-omap2/pm44xx.o
CC arch/arm/mach-omap2/omap-mpuss-lowpower.o
CHECK arch/arm/mach-omap2/pm-debug.c
CHECK arch/arm/mach-omap2/prm_common.c
CC arch/arm/mach-omap2/pm-debug.o
CHECK arch/arm/mach-omap2/cm_common.c
CC arch/arm/mach-omap2/prm_common.o
CC arch/arm/mach-omap2/cm_common.o
CHECK arch/arm/mach-omap2/prm2xxx_3xxx.c
CC arch/arm/mach-omap2/prm2xxx_3xxx.o
CHECK arch/arm/mach-omap2/prm2xxx.c
CHECK arch/arm/mach-omap2/cm2xxx.c
CC arch/arm/mach-omap2/prm2xxx.o
CC arch/arm/mach-omap2/cm2xxx.o
CHECK arch/arm/mach-omap2/prm3xxx.c
CC arch/arm/mach-omap2/prm3xxx.o
CHECK arch/arm/mach-omap2/cm3xxx.c
CC arch/arm/mach-omap2/cm3xxx.o
CHECK arch/arm/mach-omap2/vc3xxx_data.c
CHECK arch/arm/mach-omap2/vp3xxx_data.c
CC arch/arm/mach-omap2/vc3xxx_data.o
CC arch/arm/mach-omap2/vp3xxx_data.o
CHECK arch/arm/mach-omap2/prm33xx.c
CC arch/arm/mach-omap2/prm33xx.o
CHECK arch/arm/mach-omap2/cm33xx.c
CHECK arch/arm/mach-omap2/cminst44xx.c
CC arch/arm/mach-omap2/cm33xx.o
CC arch/arm/mach-omap2/cminst44xx.o
CHECK arch/arm/mach-omap2/cm44xx.c
CC arch/arm/mach-omap2/cm44xx.o
CHECK arch/arm/mach-omap2/prcm_mpu44xx.c
CC arch/arm/mach-omap2/prcm_mpu44xx.o
CHECK arch/arm/mach-omap2/prminst44xx.c
CHECK arch/arm/mach-omap2/vc44xx_data.c
CC arch/arm/mach-omap2/prminst44xx.o
CHECK arch/arm/mach-omap2/vp44xx_data.c
CC arch/arm/mach-omap2/vc44xx_data.o
CHECK arch/arm/mach-omap2/voltage.c
CC arch/arm/mach-omap2/vp44xx_data.o
CC arch/arm/mach-omap2/voltage.o
CHECK arch/arm/mach-omap2/vc.c
CC arch/arm/mach-omap2/vc.o
CHECK arch/arm/mach-omap2/vp.c
CHECK arch/arm/mach-omap2/voltagedomains2xxx_data.c
CC arch/arm/mach-omap2/voltagedomains2xxx_data.o
CC arch/arm/mach-omap2/vp.o
CHECK arch/arm/mach-omap2/voltagedomains3xxx_data.c
CC arch/arm/mach-omap2/voltagedomains3xxx_data.o
CHECK arch/arm/mach-omap2/voltagedomains44xx_data.c
CHECK arch/arm/mach-omap2/voltagedomains33xx_data.c
CC arch/arm/mach-omap2/voltagedomains33xx_data.o
CC arch/arm/mach-omap2/voltagedomains44xx_data.o
CHECK arch/arm/mach-omap2/powerdomain.c
CC arch/arm/mach-omap2/powerdomain.o
CHECK arch/arm/mach-omap2/powerdomain-common.c
CC arch/arm/mach-omap2/powerdomain-common.o
CHECK arch/arm/mach-omap2/powerdomains2xxx_data.c
CC arch/arm/mach-omap2/powerdomains2xxx_data.o
CHECK arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
CC arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.o
CHECK arch/arm/mach-omap2/powerdomains3xxx_data.c
CHECK arch/arm/mach-omap2/powerdomains44xx_data.c
CC arch/arm/mach-omap2/powerdomains3xxx_data.o
CHECK arch/arm/mach-omap2/powerdomains33xx_data.c
CC arch/arm/mach-omap2/powerdomains33xx_data.o
CC arch/arm/mach-omap2/powerdomains44xx_data.o
CHECK arch/arm/mach-omap2/clockdomain.c
CC arch/arm/mach-omap2/clockdomain.o
CHECK arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
CC arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.o
CHECK arch/arm/mach-omap2/clockdomains2420_data.c
CHECK arch/arm/mach-omap2/clockdomains2430_data.c
CC arch/arm/mach-omap2/clockdomains2420_data.o
CC arch/arm/mach-omap2/clockdomains2430_data.o
CHECK arch/arm/mach-omap2/clockdomains3xxx_data.c
CHECK arch/arm/mach-omap2/clockdomains44xx_data.c
CC arch/arm/mach-omap2/clockdomains3xxx_data.o
CHECK arch/arm/mach-omap2/clockdomains33xx_data.c
CC arch/arm/mach-omap2/clockdomains44xx_data.o
CC arch/arm/mach-omap2/clockdomains33xx_data.o
CHECK arch/arm/mach-omap2/clock.c
CHECK arch/arm/mach-omap2/clock_common_data.c
CC arch/arm/mach-omap2/clock_common_data.o
CC arch/arm/mach-omap2/clock.o
CHECK arch/arm/mach-omap2/clkt_dpll.c
CHECK arch/arm/mach-omap2/clkt_clksel.c
CC arch/arm/mach-omap2/clkt_dpll.o
CHECK arch/arm/mach-omap2/clock2xxx.c
CC arch/arm/mach-omap2/clkt_clksel.o
CC arch/arm/mach-omap2/clock2xxx.o
CHECK arch/arm/mach-omap2/clkt2xxx_sys.c
CC arch/arm/mach-omap2/clkt2xxx_sys.o
CHECK arch/arm/mach-omap2/clkt2xxx_dpllcore.c
CC arch/arm/mach-omap2/clkt2xxx_dpllcore.o
CHECK arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
CC arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.o
CHECK arch/arm/mach-omap2/clkt2xxx_apll.c
CC arch/arm/mach-omap2/clkt2xxx_apll.o
CHECK arch/arm/mach-omap2/clkt2xxx_osc.c
CC arch/arm/mach-omap2/clkt2xxx_osc.o
CHECK arch/arm/mach-omap2/clkt2xxx_dpll.c
CC arch/arm/mach-omap2/clkt2xxx_dpll.o
CHECK arch/arm/mach-omap2/clkt_iclk.c
CC arch/arm/mach-omap2/clkt_iclk.o
CHECK arch/arm/mach-omap2/clock2420_data.c
CHECK arch/arm/mach-omap2/clock2430.c
CHECK arch/arm/mach-omap2/clock2430_data.c
CC arch/arm/mach-omap2/clock2430.o
CC arch/arm/mach-omap2/clock2420_data.o
CC arch/arm/mach-omap2/clock2430_data.o
CHECK arch/arm/mach-omap2/clock3xxx.c
CC arch/arm/mach-omap2/clock3xxx.o
CHECK arch/arm/mach-omap2/clock34xx.c
CC arch/arm/mach-omap2/clock34xx.o
CHECK arch/arm/mach-omap2/clkt34xx_dpll3m2.c
CHECK arch/arm/mach-omap2/clock3517.c
CHECK arch/arm/mach-omap2/clock36xx.c
CC arch/arm/mach-omap2/clock3517.o
CC arch/arm/mach-omap2/clkt34xx_dpll3m2.o
CC arch/arm/mach-omap2/clock36xx.o
CHECK arch/arm/mach-omap2/dpll3xxx.c
CC arch/arm/mach-omap2/dpll3xxx.o
CHECK arch/arm/mach-omap2/clock3xxx_data.c
CHECK arch/arm/mach-omap2/clock44xx_data.c
CHECK arch/arm/mach-omap2/dpll44xx.c
CC arch/arm/mach-omap2/clock3xxx_data.o
CC arch/arm/mach-omap2/dpll44xx.o
CC arch/arm/mach-omap2/clock44xx_data.o
CHECK arch/arm/mach-omap2/clock33xx_data.c
CHECK arch/arm/mach-omap2/opp2420_data.c
CC arch/arm/mach-omap2/opp2420_data.o
CHECK arch/arm/mach-omap2/opp2430_data.c
CHECK arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
CC arch/arm/mach-omap2/clock33xx_data.o
CC arch/arm/mach-omap2/opp2430_data.o
CHECK arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
CC arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.o
CC arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.o
CHECK arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
CC arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.o
CHECK arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c
CHECK arch/arm/mach-omap2/omap_hwmod_2420_data.c
CHECK arch/arm/mach-omap2/omap_hwmod_2430_data.c
CC arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.o
CC arch/arm/mach-omap2/omap_hwmod_2420_data.o
CC arch/arm/mach-omap2/omap_hwmod_2430_data.o
CHECK arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
CC arch/arm/mach-omap2/omap_hwmod_3xxx_data.o
CHECK arch/arm/mach-omap2/omap_hwmod_33xx_data.c
CHECK arch/arm/mach-omap2/omap_hwmod_44xx_data.c
CHECK arch/arm/mach-omap2/pmu.c
CC arch/arm/mach-omap2/omap_hwmod_33xx_data.o
CC arch/arm/mach-omap2/omap_hwmod_44xx_data.o
CC arch/arm/mach-omap2/pmu.o
CHECK arch/arm/mach-omap2/msdi.c
CC arch/arm/mach-omap2/msdi.o
CHECK arch/arm/mach-omap2/board-generic.c
CHECK arch/arm/mach-omap2/board-h4.c
CC arch/arm/mach-omap2/board-generic.o
CHECK arch/arm/mach-omap2/board-2430sdp.c
CC arch/arm/mach-omap2/board-h4.o
CC arch/arm/mach-omap2/board-2430sdp.o
CHECK arch/arm/mach-omap2/board-apollon.c
CHECK arch/arm/mach-omap2/board-omap3beagle.c
CC arch/arm/mach-omap2/board-apollon.o
CC arch/arm/mach-omap2/board-omap3beagle.o
CHECK arch/arm/mach-omap2/board-devkit8000.c
CC arch/arm/mach-omap2/board-devkit8000.o
CHECK arch/arm/mach-omap2/board-ldp.c
CHECK arch/arm/mach-omap2/board-omap3logic.c
CC arch/arm/mach-omap2/board-ldp.o
CC arch/arm/mach-omap2/board-omap3logic.o
CHECK arch/arm/mach-omap2/board-overo.c
CC arch/arm/mach-omap2/board-overo.o
CHECK arch/arm/mach-omap2/board-omap3evm.c
CC arch/arm/mach-omap2/board-omap3evm.o
CHECK arch/arm/mach-omap2/board-omap3pandora.c
CHECK arch/arm/mach-omap2/board-3430sdp.c
CC arch/arm/mach-omap2/board-omap3pandora.o
CC arch/arm/mach-omap2/board-3430sdp.o
CHECK arch/arm/mach-omap2/board-n8x0.c
CC arch/arm/mach-omap2/board-n8x0.o
CHECK arch/arm/mach-omap2/board-rm680.c
CC arch/arm/mach-omap2/board-rm680.o
CHECK arch/arm/mach-omap2/sdram-nokia.c
CHECK arch/arm/mach-omap2/board-rx51.c
CC arch/arm/mach-omap2/sdram-nokia.o
CC arch/arm/mach-omap2/board-rx51.o
CHECK arch/arm/mach-omap2/board-rx51-peripherals.c
CC arch/arm/mach-omap2/board-rx51-peripherals.o
CHECK arch/arm/mach-omap2/board-rx51-video.c
CC arch/arm/mach-omap2/board-rx51-video.o
CHECK arch/arm/mach-omap2/board-zoom-peripherals.c
CHECK arch/arm/mach-omap2/board-zoom.c
CC arch/arm/mach-omap2/board-zoom.o
CC arch/arm/mach-omap2/board-zoom-peripherals.o
CHECK arch/arm/mach-omap2/board-zoom-display.c
CHECK arch/arm/mach-omap2/board-zoom-debugboard.c
CC arch/arm/mach-omap2/board-zoom-display.o
CC arch/arm/mach-omap2/board-zoom-debugboard.o
CHECK arch/arm/mach-omap2/board-3630sdp.c
CHECK arch/arm/mach-omap2/board-cm-t35.c
CC arch/arm/mach-omap2/board-3630sdp.o
CHECK arch/arm/mach-omap2/board-cm-t3517.c
CC arch/arm/mach-omap2/board-cm-t35.o
CC arch/arm/mach-omap2/board-cm-t3517.o
CHECK arch/arm/mach-omap2/board-igep0020.c
CHECK arch/arm/mach-omap2/board-omap3touchbook.c
CC arch/arm/mach-omap2/board-igep0020.o
CC arch/arm/mach-omap2/board-omap3touchbook.o
CHECK arch/arm/mach-omap2/board-4430sdp.c
CHECK arch/arm/mach-omap2/board-omap4panda.c
CC arch/arm/mach-omap2/board-4430sdp.o
CC arch/arm/mach-omap2/board-omap4panda.o
CHECK arch/arm/mach-omap2/board-am3517evm.c
CHECK arch/arm/mach-omap2/board-omap3stalker.c
CC arch/arm/mach-omap2/board-am3517evm.o
CC arch/arm/mach-omap2/board-omap3stalker.o
CHECK arch/arm/mach-omap2/board-ti8168evm.c
CC arch/arm/mach-omap2/board-ti8168evm.o
CHECK arch/arm/mach-omap2/board-flash.c
CC arch/arm/mach-omap2/board-flash.o
CHECK arch/arm/mach-omap2/hsmmc.c
CHECK arch/arm/mach-omap2/usb-musb.c
CC arch/arm/mach-omap2/hsmmc.o
CHECK arch/arm/mach-omap2/omap_phy_internal.c
CC arch/arm/mach-omap2/usb-musb.o
CC arch/arm/mach-omap2/omap_phy_internal.o
CHECK arch/arm/mach-omap2/usb-tusb6010.c
CHECK arch/arm/mach-omap2/usb-host.c
CC arch/arm/mach-omap2/usb-tusb6010.o
CC arch/arm/mach-omap2/usb-host.o
CHECK arch/arm/mach-omap2/gpmc-onenand.c
CC arch/arm/mach-omap2/gpmc-onenand.o
CHECK arch/arm/mach-omap2/gpmc-nand.c
CHECK arch/arm/mach-omap2/gpmc-smc91x.c
CC arch/arm/mach-omap2/gpmc-smc91x.o
CC arch/arm/mach-omap2/gpmc-nand.o
CHECK arch/arm/mach-omap2/gpmc-smsc911x.c
CC arch/arm/mach-omap2/gpmc-smsc911x.o
CHECK arch/arm/mach-omap2/common-board-devices.c
CHECK arch/arm/mach-omap2/twl-common.c
CC arch/arm/mach-omap2/common-board-devices.o
CC arch/arm/mach-omap2/twl-common.o
LD arch/arm/mach-omap2/built-in.o
paul at dusk:/kernel/kernel/current$
On Thu, Dec 13, 2012 at 12:59:49, Paul Walmsley wrote:
On Thu, 13 Dec 2012, Hiremath, Vaibhav wrote:
quoted
On Thu, Dec 13, 2012 at 11:11:49, Paul Walmsley wrote:
quoted
The branch name to use is:
"TEST_pwrdm_post_fpwrst_devel_a_3.9"
If I am correct, it only includes one additional patch (merge commit),
right???
commit d94831e0005fee743cefd28f4c20b7c435c71236
Merge: 3e885c6 80ab3b2
Author: Paul Walmsley [off-list ref]
Date: Sun Dec 9 13:06:51 2012 -0700
build fixes
Does this also fix sparse warnings?
Just ran a quick sparse check on mach-omap2 at 3e885c6 and d94831e with
'make -j4 C=2 arch/arm/mach-omap2', and no warnings showed up. There were
some sparse issues that got fixed at an earlier point, though, so perhaps
you have an older copy of the branches somehow?
Ignore my earlier comment on sparse warning, it was my wrong sparse tool
which was culprit here. I am working on remote server, which has sparse
present inside /usr/bin, and somehow my default config using that one
instead of what I was building.
I fixed this by changing the PATH, and now I do not see any issues/warnings.
Thanks,
Vaibhav
On Sunday 09 December 2012 02:23 AM, Paul Walmsley wrote:
Fix the following sparse warnings in the OMAP3/4 CPUIdle code:
arch/arm/mach-omap2/cpuidle34xx.c:272:1: warning: symbol 'omap3_idle_dev' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle34xx.c:274:23: warning: symbol 'omap3_idle_driver' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:164:1: warning: symbol 'omap4_idle_dev' was not declared. Should it be static?
arch/arm/mach-omap2/cpuidle44xx.c:166:23: warning: symbol 'omap4_idle_driver' was not declared. Should it be static?
Also fix the following checkpatch warnings:
WARNING: please, no space before tabs
#44: FILE: arch/arm/mach-omap2/cpuidle34xx.c:105:
+^I.name = ^I"omap3_idle",$
WARNING: please, no space before tabs
#45: FILE: arch/arm/mach-omap2/cpuidle34xx.c:106:
+^I.owner = ^ITHIS_MODULE,$
ERROR: code indent should use tabs where possible
#211: FILE: arch/arm/mach-omap2/cpuidle44xx.c:74:
+ /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */$
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <redacted>
---
Don't attempt to put clockdomains to sleep; this should be handled by the
clock framework. It should be enough to program the next-power-state,
and then let the code in omap_pm_clkdms_setup() deal with the rest.
Start out by programming the MPU and CORE powerdomains to stay ON.
Then control the MPU and CORE powerdomain states directly in
omap2_enter_full_retention() and omap2_enter_mpu_retention(). Not the
most optimal way to do it, but certainly is the most conservative until
OMAP2xxx PM is working again.
Get rid of the open-coded PM_PWSTCTRL_MPU writes in
omap2_enter_mpu_retention(); use the powerdomain code instead.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/pm24xx.c | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)
@@ -89,11 +89,7 @@ static int omap2_enter_full_retention(void)omap2_prm_write_mod_reg(0xffffffff,CORE_MOD,OMAP24XX_PM_WKST2);omap2_prm_write_mod_reg(0xffffffff,WKUP_MOD,PM_WKST);-/*-*SetMPUpowerdomain'snextpowerstatetoRETENTION;-*preservelogicstateduringretention-*/-pwrdm_set_logic_retst(mpu_pwrdm,PWRDM_POWER_RET);+pwrdm_set_next_pwrst(core_pwrdm,PWRDM_POWER_RET);pwrdm_set_next_pwrst(mpu_pwrdm,PWRDM_POWER_RET);/* Workaround to kill USB */
@@ -185,17 +184,16 @@ static void omap2_enter_mpu_retention(void)omap2_prm_write_mod_reg(0xffffffff,WKUP_MOD,PM_WKST);/* Try to enter MPU retention */-omap2_prm_write_mod_reg((0x01<<OMAP_POWERSTATE_SHIFT)|-OMAP_LOGICRETSTATE_MASK,-MPU_MOD,OMAP2_PM_PWSTCTRL);+pwrdm_set_next_pwrst(mpu_pwrdm,PWRDM_POWER_RET);+}else{/* Block MPU retention */--omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK,MPU_MOD,-OMAP2_PM_PWSTCTRL);+pwrdm_set_next_pwrst(mpu_pwrdm,PWRDM_POWER_ON);}omap2_sram_idle();++pwrdm_set_next_pwrst(mpu_pwrdm,PWRDM_POWER_ON);}staticintomap2_can_sleep(void)
@@ -250,25 +248,17 @@ static void __init prcm_setup_regs(void)for(i=0;i<num_mem_banks;i++)pwrdm_set_mem_retst(core_pwrdm,i,PWRDM_POWER_RET);-/* Set CORE powerdomain's next power state to RETENTION */-pwrdm_set_next_pwrst(core_pwrdm,PWRDM_POWER_RET);+pwrdm_set_logic_retst(core_pwrdm,PWRDM_POWER_RET);-/*-*SetMPUpowerdomain'snextpowerstatetoRETENTION;-*preservelogicstateduringretention-*/pwrdm_set_logic_retst(mpu_pwrdm,PWRDM_POWER_RET);-pwrdm_set_next_pwrst(mpu_pwrdm,PWRDM_POWER_RET);/* Force-power down DSP, GFX powerdomains */pwrdm=clkdm_get_pwrdm(dsp_clkdm);pwrdm_set_next_pwrst(pwrdm,PWRDM_POWER_OFF);-clkdm_sleep(dsp_clkdm);pwrdm=clkdm_get_pwrdm(gfx_clkdm);pwrdm_set_next_pwrst(pwrdm,PWRDM_POWER_OFF);-clkdm_sleep(gfx_clkdm);/* Enable hardware-supervised idle for all clkdms */clkdm_for_each(omap_pm_clkdms_setup,NULL);
Drop an unnecessary pwrdm_wait_transition() from mach-omap2/pm.c -
it's called by the subsequent pwrdm_state_switch().
Also get rid of pwrdm_wait_transition() in the powerdomain code - there's
no longer any need to export this function.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/pm.c | 1 -
arch/arm/mach-omap2/powerdomain.c | 30 +++++-------------------------
arch/arm/mach-omap2/powerdomain.h | 2 --
3 files changed, 5 insertions(+), 28 deletions(-)
Move omap_set_pwrdm_state() from the PM code to the powerdomain code,
and refactor it to split it up into several functions. A subsequent patch
will rename it to conform with the existing powerdomain function names.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Jean Pihet <redacted>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/pm.c | 61 --------------------
arch/arm/mach-omap2/pm.h | 1
arch/arm/mach-omap2/powerdomain.c | 112 +++++++++++++++++++++++++++----------
arch/arm/mach-omap2/powerdomain.h | 3 +
4 files changed, 85 insertions(+), 92 deletions(-)
@@ -76,10 +76,6 @@ static void __init omap2_init_processor_devices(void)}}-/* Types of sleep_switch used in omap_set_pwrdm_state */-#define FORCEWAKEUP_SWITCH 0-#define LOWPOWERSTATE_SWITCH 1-int__initomap_pm_clkdms_setup(structclockdomain*clkdm,void*unused){if((clkdm->flags&CLKDM_CAN_ENABLE_AUTO)&&
@@ -92,63 +88,6 @@ int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)}/*-*Thissetspwrdmstate(otherthanmpu&core.CurrentlyonlyON&-*RETaresupported.-*/-intomap_set_pwrdm_state(structpowerdomain*pwrdm,u32pwrst)-{-u8curr_pwrst,next_pwrst;-intsleep_switch=-1,ret=0,hwsup=0;--if(!pwrdm||IS_ERR(pwrdm))-return-EINVAL;--while(!(pwrdm->pwrsts&(1<<pwrst))){-if(pwrst==PWRDM_POWER_OFF)-returnret;-pwrst--;-}--next_pwrst=pwrdm_read_next_pwrst(pwrdm);-if(next_pwrst==pwrst)-returnret;--curr_pwrst=pwrdm_read_pwrst(pwrdm);-if(curr_pwrst<PWRDM_POWER_ON){-if((curr_pwrst>pwrst)&&-(pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE)){-sleep_switch=LOWPOWERSTATE_SWITCH;-}else{-hwsup=clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);-clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);-sleep_switch=FORCEWAKEUP_SWITCH;-}-}--ret=pwrdm_set_next_pwrst(pwrdm,pwrst);-if(ret)-pr_err("%s: unable to set power state of powerdomain: %s\n",-__func__,pwrdm->name);--switch(sleep_switch){-caseFORCEWAKEUP_SWITCH:-if(hwsup)-clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);-else-clkdm_sleep(pwrdm->pwrdm_clkdms[0]);-break;-caseLOWPOWERSTATE_SWITCH:-pwrdm_set_lowpwrstchange(pwrdm);-pwrdm_state_switch(pwrdm);-break;-}--returnret;-}----/**ThisAPIistobecalledduringinittosetthevariousvoltage*domainstothevoltageaspertheopptable.Typicallywebootup*atthenominalvoltage.Sothisfunctionfindsouttherateof
@@ -984,6 +955,89 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)return0;}+/* Types of sleep_switch used in omap_set_pwrdm_state */+#define ALREADYACTIVE_SWITCH 0+#define FORCEWAKEUP_SWITCH 1+#define LOWPOWERSTATE_SWITCH 2++staticu8_pwrdm_save_clkdm_state_and_activate(structpowerdomain*pwrdm,+u8pwrst,bool*hwsup)+{+u8curr_pwrst,sleep_switch;++curr_pwrst=pwrdm_read_pwrst(pwrdm);+if(curr_pwrst<PWRDM_POWER_ON){+if(curr_pwrst>pwrst&&+pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE&&+arch_pwrdm->pwrdm_set_lowpwrstchange){+sleep_switch=LOWPOWERSTATE_SWITCH;+}else{+*hwsup=clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);+clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);+sleep_switch=FORCEWAKEUP_SWITCH;+}+}else{+sleep_switch=ALREADYACTIVE_SWITCH;+}++returnsleep_switch;+}++staticvoid_pwrdm_restore_clkdm_state(structpowerdomain*pwrdm,+u8sleep_switch,boolhwsup)+{+switch(sleep_switch){+caseFORCEWAKEUP_SWITCH:+if(hwsup)+clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);+else+clkdm_sleep(pwrdm->pwrdm_clkdms[0]);+break;+caseLOWPOWERSTATE_SWITCH:+if(pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE&&+arch_pwrdm->pwrdm_set_lowpwrstchange)+arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);+pwrdm_state_switch(pwrdm);+break;+}+}++/*+*Thissetspwrdmstate(otherthanmpu&core.CurrentlyonlyON&+*RETaresupported.+*/+intomap_set_pwrdm_state(structpowerdomain*pwrdm,u8pwrst)+{+u8next_pwrst,sleep_switch;+intret=0;+boolhwsup=false;++if(!pwrdm||IS_ERR(pwrdm))+return-EINVAL;++while(!(pwrdm->pwrsts&(1<<pwrst))){+if(pwrst==PWRDM_POWER_OFF)+returnret;+pwrst--;+}++next_pwrst=pwrdm_read_next_pwrst(pwrdm);+if(next_pwrst==pwrst)+returnret;++sleep_switch=_pwrdm_save_clkdm_state_and_activate(pwrdm,pwrst,+&hwsup);++ret=pwrdm_set_next_pwrst(pwrdm,pwrst);+if(ret)+pr_err("%s: unable to set power state of powerdomain: %s\n",+__func__,pwrdm->name);++_pwrdm_restore_clkdm_state(pwrdm,sleep_switch,hwsup);++returnret;+}+/***pwrdm_get_context_loss_count-getpowerdomain'scontextlosscount*@pwrdm:structpowerdomain*towaitfor
From: Jean Pihet <hidden> Date: 2012-12-12 09:31:33
Hi Paul,
On Sun, Dec 9, 2012 at 2:23 AM, Paul Walmsley [off-list ref] wrote:
Move omap_set_pwrdm_state() from the PM code to the powerdomain code,
and refactor it to split it up into several functions. A subsequent patch
will rename it to conform with the existing powerdomain function names.
Glad to see this rather cryptic function getting a rewrite. It had never
been clear what the function is doing so I think it owes some more comments.
More comments below.
@@ -76,10 +76,6 @@ static void __init omap2_init_processor_devices(void)}}-/* Types of sleep_switch used in omap_set_pwrdm_state */-#define FORCEWAKEUP_SWITCH 0-#define LOWPOWERSTATE_SWITCH 1-int__initomap_pm_clkdms_setup(structclockdomain*clkdm,void*unused){if((clkdm->flags&CLKDM_CAN_ENABLE_AUTO)&&
@@ -92,63 +88,6 @@ int __init omap_pm_clkdms_setup(struct clockdomain
*clkdm, void *unused)
}
/*
- * This sets pwrdm state (other than mpu & core. Currently only ON &
- * RET are supported.
- */
-int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
-{
- u8 curr_pwrst, next_pwrst;
- int sleep_switch = -1, ret = 0, hwsup = 0;
-
- if (!pwrdm || IS_ERR(pwrdm))
- return -EINVAL;
-
- while (!(pwrdm->pwrsts & (1 << pwrst))) {
- if (pwrst == PWRDM_POWER_OFF)
- return ret;
- pwrst--;
- }
-
- next_pwrst = pwrdm_read_next_pwrst(pwrdm);
- if (next_pwrst == pwrst)
- return ret;
-
- curr_pwrst = pwrdm_read_pwrst(pwrdm);
- if (curr_pwrst < PWRDM_POWER_ON) {
- if ((curr_pwrst > pwrst) &&
- (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
- sleep_switch = LOWPOWERSTATE_SWITCH;
- } else {
- hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
- clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- sleep_switch = FORCEWAKEUP_SWITCH;
- }
- }
-
- ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
- if (ret)
- pr_err("%s: unable to set power state of powerdomain:
%s\n",
- __func__, pwrdm->name);
-
- switch (sleep_switch) {
- case FORCEWAKEUP_SWITCH:
- if (hwsup)
- clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
- else
- clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
- break;
- case LOWPOWERSTATE_SWITCH:
- pwrdm_set_lowpwrstchange(pwrdm);
- pwrdm_state_switch(pwrdm);
- break;
- }
-
- return ret;
-}
-
-
-
-/*
* This API is to be called during init to set the various voltage
* domains to the voltage as per the opp table. Typically we boot up
* at the nominal voltage. So this function finds out the rate of
Hi,
(redacted irrelevant code sections)
On Wed, 12 Dec 2012, Jean Pihet wrote:
On Sun, Dec 9, 2012 at 2:23 AM, Paul Walmsley [off-list ref] wrote:
quoted
-/**
- * pwrdm_set_lowpwrstchange - Request a low power state change
- * @pwrdm: struct powerdomain *
- *
- * Allows a powerdomain to transtion to a lower power sleep state
- * from an existing sleep state without waking up the powerdomain.
- * Returns -EINVAL if the powerdomain pointer is null or if the
- * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
- * upon success.
- */
Can this kerneldoc be reused in the new code?
Not directly, since the function is being removed. But I've added some
LOWPOWERSTATECHANGE-related documentation in powerdomain.h in the updated
patch (below).
quoted
@@ -984,6 +955,89 @@ int pwrdm_post_transition(struct powerdomain *pwrdm) return 0; }+/* Types of sleep_switch used in omap_set_pwrdm_state */+#define ALREADYACTIVE_SWITCH 0+#define FORCEWAKEUP_SWITCH 1+#define LOWPOWERSTATE_SWITCH 2
Could you add some more documentation here?
What is the goal of the function, what does it return etc. ?
I've added some related kerneldoc to omap_set_pwrdm_state().
+/*
+ * This sets pwrdm state (other than mpu & core. Currently only ON &
+ * RET are supported.
+ */
Is this one correct?
This is just a cut and paste from the previous comments in the file. I
agree that it is not helpful, so I've added kerneldoc for
omap_set_pwrdm_state().
The updated patch follows.
- Paul
From: Paul Walmsley <paul@pwsan.com>
Date: Tue, 29 Jan 2013 13:45:09 -0700
Subject: [PATCH] ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to
powerdomain code
Move omap_set_pwrdm_state() from the PM code to the powerdomain code,
and refactor it to split it up into several functions. A subsequent patch
will rename it to conform with the existing powerdomain function names.
This version includes some additional documentation, based on a
suggestion from Jean Pihet. It also modifies omap_set_pwrdm_state()
to not bail out early unless both the powerdomain current power state
and the next power state are equal. (Previously it would terminate
early if the next power state was equal to the target power state,
which was insufficiently rigorous.)
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Jean Pihet <redacted>
Cc: Kevin Hilman <redacted>
Cc: Tero Kristo <redacted>
---
arch/arm/mach-omap2/pm.c | 61 --------------
arch/arm/mach-omap2/pm.h | 1 -
arch/arm/mach-omap2/powerdomain.c | 161 ++++++++++++++++++++++++++++++-------
arch/arm/mach-omap2/powerdomain.h | 13 ++-
4 files changed, 144 insertions(+), 92 deletions(-)
@@ -108,10 +108,6 @@ static void __init omap2_init_processor_devices(void)}}-/* Types of sleep_switch used in omap_set_pwrdm_state */-#define FORCEWAKEUP_SWITCH 0-#define LOWPOWERSTATE_SWITCH 1-int__initomap_pm_clkdms_setup(structclockdomain*clkdm,void*unused){if((clkdm->flags&CLKDM_CAN_ENABLE_AUTO)&&
@@ -124,63 +120,6 @@ int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)}/*-*Thissetspwrdmstate(otherthanmpu&core.CurrentlyonlyON&-*RETaresupported.-*/-intomap_set_pwrdm_state(structpowerdomain*pwrdm,u32pwrst)-{-u8curr_pwrst,next_pwrst;-intsleep_switch=-1,ret=0,hwsup=0;--if(!pwrdm||IS_ERR(pwrdm))-return-EINVAL;--while(!(pwrdm->pwrsts&(1<<pwrst))){-if(pwrst==PWRDM_POWER_OFF)-returnret;-pwrst--;-}--next_pwrst=pwrdm_read_next_pwrst(pwrdm);-if(next_pwrst==pwrst)-returnret;--curr_pwrst=pwrdm_read_pwrst(pwrdm);-if(curr_pwrst<PWRDM_POWER_ON){-if((curr_pwrst>pwrst)&&-(pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE)){-sleep_switch=LOWPOWERSTATE_SWITCH;-}else{-hwsup=clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);-clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);-sleep_switch=FORCEWAKEUP_SWITCH;-}-}--ret=pwrdm_set_next_pwrst(pwrdm,pwrst);-if(ret)-pr_err("%s: unable to set power state of powerdomain: %s\n",-__func__,pwrdm->name);--switch(sleep_switch){-caseFORCEWAKEUP_SWITCH:-if(hwsup)-clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);-else-clkdm_sleep(pwrdm->pwrdm_clkdms[0]);-break;-caseLOWPOWERSTATE_SWITCH:-pwrdm_set_lowpwrstchange(pwrdm);-pwrdm_state_switch(pwrdm);-break;-}--returnret;-}----/**ThisAPIistobecalledduringinittosetthevariousvoltage*domainstothevoltageaspertheopptable.Typicallywebootup*atthenominalvoltage.Sothisfunctionfindsouttherateof
@@ -985,6 +1040,54 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)}/**+*omap_set_pwrdm_state-changeapowerdomain'scurrentpowerstate+*@pwrdm:structpowerdomain*tochangethepowerstateof+*@pwrst:powerstatetochangeto+*+*Changethecurrenthardwarepowerstateofthepowerdomain+*representedby@pwrdmtothepowerstaterepresentedby@pwrst.+*Returns-EINVALif@pwrdmisnullorinvalidorifthe+*powerdomain'scurrentpowerstatecouldnotberead,orreturns0+*uponsuccessorif@pwrdmdoesnotsupport@pwrstorany+*lower-powerstate.XXXShouldnotreturn0ifthe@pwrdmdoesnot+*support@pwrstoranylower-powerstate:thisshouldbeanerror.+*/+intomap_set_pwrdm_state(structpowerdomain*pwrdm,u8pwrst)+{+u8curr_pwrst,next_pwrst,sleep_switch;+intret=0;+boolhwsup=false;++if(!pwrdm||IS_ERR(pwrdm))+return-EINVAL;++while(!(pwrdm->pwrsts&(1<<pwrst))){+if(pwrst==PWRDM_POWER_OFF)+returnret;+pwrst--;+}++curr_pwrst=pwrdm_read_pwrst(pwrdm);+next_pwrst=pwrdm_read_next_pwrst(pwrdm);+if(curr_pwrst==pwrst&&next_pwrst==pwrst)+returnret;++sleep_switch=_pwrdm_save_clkdm_state_and_activate(pwrdm,curr_pwrst,+pwrst,&hwsup);+if(sleep_switch==ERROR_SWITCH)+return-EINVAL;++ret=pwrdm_set_next_pwrst(pwrdm,pwrst);+if(ret)+pr_err("%s: unable to set power state of powerdomain: %s\n",+__func__,pwrdm->name);++_pwrdm_restore_clkdm_state(pwrdm,sleep_switch,hwsup);++returnret;+}++/***pwrdm_get_context_loss_count-getpowerdomain'scontextlosscount*@pwrdm:structpowerdomain*towaitfor*
Minor comment below,
On 12/9/2012 6:53 AM, Paul Walmsley wrote:
quoted hunk
Move omap_set_pwrdm_state() from the PM code to the powerdomain code,
and refactor it to split it up into several functions. A subsequent patch
will rename it to conform with the existing powerdomain function names.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Jean Pihet <redacted>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/pm.c | 61 --------------------
arch/arm/mach-omap2/pm.h | 1
arch/arm/mach-omap2/powerdomain.c | 112 +++++++++++++++++++++++++++----------
arch/arm/mach-omap2/powerdomain.h | 3 +
4 files changed, 85 insertions(+), 92 deletions(-)
- return -EINVAL;
-
- while (!(pwrdm->pwrsts & (1 << pwrst))) {
- if (pwrst == PWRDM_POWER_OFF)
- return ret;
- pwrst--;
- }
-
- next_pwrst = pwrdm_read_next_pwrst(pwrdm);
- if (next_pwrst == pwrst)
- return ret;
-
- curr_pwrst = pwrdm_read_pwrst(pwrdm);
- if (curr_pwrst < PWRDM_POWER_ON) {
- if ((curr_pwrst > pwrst) &&
- (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
- sleep_switch = LOWPOWERSTATE_SWITCH;
- } else {
- hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
- clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- sleep_switch = FORCEWAKEUP_SWITCH;
- }
- }
-
- ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
- if (ret)
- pr_err("%s: unable to set power state of powerdomain: %s\n",
- __func__, pwrdm->name);
-
- switch (sleep_switch) {
- case FORCEWAKEUP_SWITCH:
- if (hwsup)
- clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
- else
- clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
- break;
- case LOWPOWERSTATE_SWITCH:
- pwrdm_set_lowpwrstchange(pwrdm);
- pwrdm_state_switch(pwrdm);
- break;
- }
-
- return ret;
-}
-
-
-
-/*
* This API is to be called during init to set the various voltage
* domains to the voltage as per the opp table. Typically we boot up
* at the nominal voltage. So this function finds out the rate of
@@ -984,6 +955,89 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)return0;}+/* Types of sleep_switch used in omap_set_pwrdm_state */+#define ALREADYACTIVE_SWITCH 0+#define FORCEWAKEUP_SWITCH 1+#define LOWPOWERSTATE_SWITCH 2++staticu8_pwrdm_save_clkdm_state_and_activate(structpowerdomain*pwrdm,+u8pwrst,bool*hwsup)+{+u8curr_pwrst,sleep_switch;++curr_pwrst=pwrdm_read_pwrst(pwrdm);+if(curr_pwrst<PWRDM_POWER_ON){+if(curr_pwrst>pwrst&&+pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE&&+arch_pwrdm->pwrdm_set_lowpwrstchange){+sleep_switch=LOWPOWERSTATE_SWITCH;+}else{+*hwsup=clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);+clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);+sleep_switch=FORCEWAKEUP_SWITCH;+}+}else{+sleep_switch=ALREADYACTIVE_SWITCH;+}++returnsleep_switch;+}++staticvoid_pwrdm_restore_clkdm_state(structpowerdomain*pwrdm,+u8sleep_switch,boolhwsup)+{+switch(sleep_switch){+caseFORCEWAKEUP_SWITCH:+if(hwsup)+clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);+else+clkdm_sleep(pwrdm->pwrdm_clkdms[0]);+break;+caseLOWPOWERSTATE_SWITCH:+if(pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE&&+arch_pwrdm->pwrdm_set_lowpwrstchange)+arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);+pwrdm_state_switch(pwrdm);+break;+}+}++/*+*Thissetspwrdmstate(otherthanmpu&core.CurrentlyonlyON&+*RETaresupported.+*/+intomap_set_pwrdm_state(structpowerdomain*pwrdm,u8pwrst)+{+u8next_pwrst,sleep_switch;+intret=0;+boolhwsup=false;++if(!pwrdm||IS_ERR(pwrdm))+return-EINVAL;++while(!(pwrdm->pwrsts&(1<<pwrst))){+if(pwrst==PWRDM_POWER_OFF)+returnret;+pwrst--;+}++next_pwrst=pwrdm_read_next_pwrst(pwrdm);+if(next_pwrst==pwrst)+returnret;++sleep_switch=_pwrdm_save_clkdm_state_and_activate(pwrdm,pwrst,+&hwsup);++ret=pwrdm_set_next_pwrst(pwrdm,pwrst);+if(ret)+pr_err("%s: unable to set power state of powerdomain: %s\n",+__func__,pwrdm->name);++_pwrdm_restore_clkdm_state(pwrdm,sleep_switch,hwsup);++returnret;+}+/***pwrdm_get_context_loss_count-getpowerdomain'scontextlosscount*@pwrdm:structpowerdomain*towaitfor
From: Russell King - ARM Linux <hidden> Date: 2013-01-09 17:43:32
On Wed, Dec 12, 2012 at 03:51:49PM +0530, Vaibhav Hiremath wrote:
quoted
-int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
-{
- u8 curr_pwrst, next_pwrst;
- int sleep_switch = -1, ret = 0, hwsup = 0;
-
- if (!pwrdm || IS_ERR(pwrdm))
You can use IS_ERR_OR_NULL here.
As this is removing code...
However, if you pay attention to linux-kernel or linux-arm-kernel, you will
notice that I've sent a patch deprecating IS_ERR_OR_NULL() and I'm starting
to remove its use. IS_ERR_OR_NULL() creates more problems than it solves
because people don't think about what the hell they're doing with it, or
even whether it's appropriate to use it.
From: Jean Pihet <hidden> Date: 2012-12-12 10:31:35
Hi Paul,
-resending in plain text only, sorry about that-
On Sun, Dec 9, 2012 at 2:23 AM, Paul Walmsley [off-list ref] wrote:
Move omap_set_pwrdm_state() from the PM code to the powerdomain code,
and refactor it to split it up into several functions. A subsequent patch
will rename it to conform with the existing powerdomain function names.
Glad to see this rather cryptic function getting a rewrite. It had
never been clear what the function is doing so I think it owes some
more comments.
More comments below.
@@ -76,10 +76,6 @@ static void __init omap2_init_processor_devices(void)}}-/* Types of sleep_switch used in omap_set_pwrdm_state */-#define FORCEWAKEUP_SWITCH 0-#define LOWPOWERSTATE_SWITCH 1-int__initomap_pm_clkdms_setup(structclockdomain*clkdm,void*unused){if((clkdm->flags&CLKDM_CAN_ENABLE_AUTO)&&
@@ -92,63 +88,6 @@ int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)}/*-*Thissetspwrdmstate(otherthanmpu&core.CurrentlyonlyON&-*RETaresupported.-*/-intomap_set_pwrdm_state(structpowerdomain*pwrdm,u32pwrst)-{-u8curr_pwrst,next_pwrst;-intsleep_switch=-1,ret=0,hwsup=0;--if(!pwrdm||IS_ERR(pwrdm))-return-EINVAL;--while(!(pwrdm->pwrsts&(1<<pwrst))){-if(pwrst==PWRDM_POWER_OFF)-returnret;-pwrst--;-}--next_pwrst=pwrdm_read_next_pwrst(pwrdm);-if(next_pwrst==pwrst)-returnret;--curr_pwrst=pwrdm_read_pwrst(pwrdm);-if(curr_pwrst<PWRDM_POWER_ON){-if((curr_pwrst>pwrst)&&-(pwrdm->flags&PWRDM_HAS_LOWPOWERSTATECHANGE)){-sleep_switch=LOWPOWERSTATE_SWITCH;-}else{-hwsup=clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);-clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);-sleep_switch=FORCEWAKEUP_SWITCH;-}-}--ret=pwrdm_set_next_pwrst(pwrdm,pwrst);-if(ret)-pr_err("%s: unable to set power state of powerdomain: %s\n",-__func__,pwrdm->name);--switch(sleep_switch){-caseFORCEWAKEUP_SWITCH:-if(hwsup)-clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);-else-clkdm_sleep(pwrdm->pwrdm_clkdms[0]);-break;-caseLOWPOWERSTATE_SWITCH:-pwrdm_set_lowpwrstchange(pwrdm);-pwrdm_state_switch(pwrdm);-break;-}--returnret;-}----/**ThisAPIistobecalledduringinittosetthevariousvoltage*domainstothevoltageaspertheopptable.Typicallywebootup*atthenominalvoltage.Sothisfunctionfindsouttherateof
+static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
+ u8 sleep_switch, bool hwsup)
+{
+ switch (sleep_switch) {
+ case FORCEWAKEUP_SWITCH:
+ if (hwsup)
+ clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ else
+ clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+ break;
+ case LOWPOWERSTATE_SWITCH:
+ if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
+ arch_pwrdm->pwrdm_set_lowpwrstchange)
+ arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
+ pwrdm_state_switch(pwrdm);
+ break;
+ }
+}
+
+/*
+ * This sets pwrdm state (other than mpu & core. Currently only ON &
+ * RET are supported.
+ */
Same here.
Is this one correct?
Regards,
Jean
+int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u8 next_pwrst, sleep_switch;
+ int ret = 0;
+ bool hwsup = false;
+
+ if (!pwrdm || IS_ERR(pwrdm))
+ return -EINVAL;
+
+ while (!(pwrdm->pwrsts & (1 << pwrst))) {
+ if (pwrst == PWRDM_POWER_OFF)
+ return ret;
+ pwrst--;
+ }
+
+ next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+ if (next_pwrst == pwrst)
+ return ret;
+
+ sleep_switch = _pwrdm_save_clkdm_state_and_
quoted hunk
activate(pwrdm, pwrst,
+ &hwsup);
+
+ ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+ if (ret)
+ pr_err("%s: unable to set power state of powerdomain: %s\n",
+ __func__, pwrdm->name);
+
+ _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
+
+ return ret;
+}
+
/**
* pwrdm_get_context_loss_count - get powerdomain's context loss count
* @pwrdm: struct powerdomain * to wait for
There's no need to preserve the autodep handling code in
mach-omap2/cm2xxx.c, since no autodeps are defined for these chips.
Hopefully they'll never be needed, but if in some future case they are,
this code can be added back in.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/cm2xxx.c | 33 ++++-----------------------------
1 file changed, 4 insertions(+), 29 deletions(-)
@@ -298,18 +292,8 @@ static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)hwsup=omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,clkdm->clktrctrl_mask);--if(hwsup){-/* Disable HW transitions when we are changing deps */-omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,-clkdm->clktrctrl_mask);-_clkdm_add_autodeps(clkdm);-omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,-clkdm->clktrctrl_mask);-}else{-if(clkdm->flags&CLKDM_CAN_FORCE_WAKEUP)-omap2xxx_clkdm_wakeup(clkdm);-}+if(!hwsup&&clkdm->flags&CLKDM_CAN_FORCE_WAKEUP)+omap2xxx_clkdm_wakeup(clkdm);return0;}
@@ -324,17 +308,8 @@ static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)hwsup=omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,clkdm->clktrctrl_mask);-if(hwsup){-/* Disable HW transitions when we are changing deps */-omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,-clkdm->clktrctrl_mask);-_clkdm_del_autodeps(clkdm);-omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,-clkdm->clktrctrl_mask);-}else{-if(clkdm->flags&CLKDM_CAN_FORCE_SLEEP)-omap2xxx_clkdm_sleep(clkdm);-}+if(!hwsup&&clkdm->flags&CLKDM_CAN_FORCE_SLEEP)+omap2xxx_clkdm_sleep(clkdm);return0;}
From: Jean Pihet <hidden> Date: 2012-12-12 09:41:07
Paul,
On Sun, Dec 9, 2012 at 2:23 AM, Paul Walmsley [off-list ref] wrote:
Add a per-powerdomain spinlock. Use that instead of the clockdomain
spinlock. Add pwrdm_lock()/pwrdm_unlock() functions to allow other
code to acquire or release the powerdomain spinlock without reaching
directly into the struct powerdomain.
Since clockdomains are part of powerdomains it seems weird for the
clockdomain code to take a powerdoamin lock.
Is there a reason why the powerdomain could not take the lock before
calling the clockdomain functions?
Also, are the lock and nolock version the clockdomain function needed?
Regards,
Jean
code
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_POWERDOMAIN_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_POWERDOMAIN_H
+
+#include "clockdomain.h"
+
+extern void clkdm_allow_idle_nolock(struct clockdomain *clkdm);
+extern void clkdm_deny_idle_nolock(struct clockdomain *clkdm);
+extern int clkdm_wakeup_nolock(struct clockdomain *clkdm);
+extern int clkdm_sleep_nolock(struct clockdomain *clkdm);
+
+#endif
diff --git a/arch/arm/mach-omap2/clockdomain.c
b/arch/arm/mach-omap2/clockdomain.c
index 18f65fd..2142dab 100644
@@ -733,18 +732,17 @@ int clkdm_clear_all_sleepdeps(struct clockdomain
*clkdm)
}
/**
- * clkdm_sleep - force clockdomain sleep transition
+ * clkdm_sleep_nolock - force clockdomain sleep transition (lockless)
* @clkdm: struct clockdomain *
*
* Instruct the CM to force a sleep transition on the specified
- * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if
- * clockdomain does not support software-initiated sleep; 0 upon
- * success.
+ * clockdomain @clkdm. Only for use by the powerdomain code. Returns
+ * -EINVAL if @clkdm is NULL or if clockdomain does not support
+ * software-initiated sleep; 0 upon success.
*/
-int clkdm_sleep(struct clockdomain *clkdm)
+int clkdm_sleep_nolock(struct clockdomain *clkdm)
{
int ret;
- unsigned long flags;
if (!clkdm)
return -EINVAL;
@@ -760,27 +758,45 @@ int clkdm_sleep(struct clockdomain *clkdm) pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);- spin_lock_irqsave(&clkdm->lock, flags); clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; ret = arch_clkdm->clkdm_sleep(clkdm);- ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);- spin_unlock_irqrestore(&clkdm->lock, flags);+ ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);+ return ret; } /**- * clkdm_wakeup - force clockdomain wakeup transition+ * clkdm_sleep - force clockdomain sleep transition * @clkdm: struct clockdomain * *- * Instruct the CM to force a wakeup transition on the specified- * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the- * clockdomain does not support software-controlled wakeup; 0 upon+ * Instruct the CM to force a sleep transition on the specified+ * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if+ * clockdomain does not support software-initiated sleep; 0 upon * success. */-int clkdm_wakeup(struct clockdomain *clkdm)+int clkdm_sleep(struct clockdomain *clkdm)+{+ int ret;++ pwrdm_lock(clkdm->pwrdm.ptr);+ ret = clkdm_sleep_nolock(clkdm);+ pwrdm_unlock(clkdm->pwrdm.ptr);++ return ret;+}++/**+ * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless)+ * @clkdm: struct clockdomain *+ *+ * Instruct the CM to force a wakeup transition on the specified+ * clockdomain @clkdm. Only for use by the powerdomain code. Returns+ * -EINVAL if @clkdm is NULL or if the clockdomain does not support+ * software-controlled wakeup; 0 upon success.+ */+int clkdm_wakeup_nolock(struct clockdomain *clkdm) { int ret;- unsigned long flags; if (!clkdm) return -EINVAL;
@@ -796,28 +812,46 @@ int clkdm_wakeup(struct clockdomain *clkdm) pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);- spin_lock_irqsave(&clkdm->lock, flags); clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; ret = arch_clkdm->clkdm_wakeup(clkdm);- ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);- spin_unlock_irqrestore(&clkdm->lock, flags);+ ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);+ return ret; } /**- * clkdm_allow_idle - enable hwsup idle transitions for clkdm+ * clkdm_wakeup - force clockdomain wakeup transition * @clkdm: struct clockdomain * *- * Allow the hardware to automatically switch the clockdomain @clkdm into- * active or idle states, as needed by downstream clocks. If the+ * Instruct the CM to force a wakeup transition on the specified+ * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the+ * clockdomain does not support software-controlled wakeup; 0 upon+ * success.+ */+int clkdm_wakeup(struct clockdomain *clkdm)+{+ int ret;++ pwrdm_lock(clkdm->pwrdm.ptr);+ ret = clkdm_wakeup_nolock(clkdm);+ pwrdm_unlock(clkdm->pwrdm.ptr);++ return ret;+}++/**+ * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm+ * @clkdm: struct clockdomain *+ *+ * Allow the hardware to automatically switch the clockdomain @clkdm+ * into active or idle states, as needed by downstream clocks. If the * clockdomain has any downstream clocks enabled in the clock * framework, wkdep/sleepdep autodependencies are added; this is so- * device drivers can read and write to the device. No return value.+ * device drivers can read and write to the device. Only for use by+ * the powerdomain code. No return value. */-void clkdm_allow_idle(struct clockdomain *clkdm)+void clkdm_allow_idle_nolock(struct clockdomain *clkdm) {- unsigned long flags;- if (!clkdm) return;
%s\n",
clkdm->name);
- spin_lock_irqsave(&clkdm->lock, flags);
clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED;
arch_clkdm->clkdm_allow_idle(clkdm);
- pwrdm_state_switch(clkdm->pwrdm.ptr);
- spin_unlock_irqrestore(&clkdm->lock, flags);
+ pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
+}
+
+/**
+ * clkdm_allow_idle - enable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Allow the hardware to automatically switch the clockdomain @clkdm into
+ * active or idle states, as needed by downstream clocks. If the
+ * clockdomain has any downstream clocks enabled in the clock
+ * framework, wkdep/sleepdep autodependencies are added; this is so
+ * device drivers can read and write to the device. No return value.
+ */
+void clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ pwrdm_lock(clkdm->pwrdm.ptr);
+ clkdm_allow_idle_nolock(clkdm);
+ pwrdm_unlock(clkdm->pwrdm.ptr);
}
/**
@@ -847,12 +896,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm) * Prevent the hardware from automatically switching the clockdomain * @clkdm into inactive or idle states. If the clockdomain has * downstream clocks enabled in the clock framework, wkdep/sleepdep- * autodependencies are removed. No return value.+ * autodependencies are removed. Only for use by the powerdomain+ * code. No return value. */-void clkdm_deny_idle(struct clockdomain *clkdm)+void clkdm_deny_idle_nolock(struct clockdomain *clkdm) {- unsigned long flags;- if (!clkdm) return;
On Sun, Dec 9, 2012 at 2:23 AM, Paul Walmsley [off-list ref] wrote:
quoted
Add a per-powerdomain spinlock. Use that instead of the clockdomain
spinlock. Add pwrdm_lock()/pwrdm_unlock() functions to allow other
code to acquire or release the powerdomain spinlock without reaching
directly into the struct powerdomain.
Since clockdomains are part of powerdomains it seems weird for the
clockdomain code to take a powerdoamin lock.
Why?
Is there a reason why the powerdomain could not take the lock before
calling the clockdomain functions?
Do you mean "is there a reason why the powerdomain _code_ could not take
the lock"? If so, the reason is that code other than the powerdomain code
calls the clkdm_* functions directly, without calling any powerdomain
functions first. So there's really no other place to take the lock unless
the callers are updated to take the powerdomain lock themselves. That
seems like something to avoid if the caller doesn't have any other
relationship to the powerdomain code.
Also, are the lock and nolock version the clockdomain function needed?
Did you have a different solution in mind? The two versions are used for
code that needs to be called from two contexts: the first with the
powerdomain's lock already held; the second needing to acquire the
powerdomain's lock to avoid racing against other PRCM code.
- Paul
From: Jean Pihet <hidden> Date: 2012-12-12 10:28:01
Paul,
-resending in plain text only, sorry about that-
On Sun, Dec 9, 2012 at 2:23 AM, Paul Walmsley [off-list ref] wrote:
Add a per-powerdomain spinlock. Use that instead of the clockdomain
spinlock. Add pwrdm_lock()/pwrdm_unlock() functions to allow other
code to acquire or release the powerdomain spinlock without reaching
directly into the struct powerdomain.
Since clockdomains are part of powerdomains it seems weird for the
clockdomain code to take a powerdoamin lock.
Is there a reason why the powerdomain could not take the lock before
calling the clockdomain functions?
Also, are the lock and nolock version the clockdomain function needed?
Regards,
Jean
Split the clkdm_(add|del)_(wk|sleep)dep() functions into lockless and
locking versions -- this will be needed in a subsequent patch. Also,
while here, remove the leading underscore, since these are not
currently static functions. And for functions that have
kerneldoc-style comment blocks, but which are missing the initial
'/**' tag, fix the tag to indicate that they are kerneldoc.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clockdomain.c | 394 ++++++++++++++++++++++---------------
arch/arm/mach-omap2/clockdomain.h | 5
arch/arm/mach-omap2/cm3xxx.c | 8 -
3 files changed, 240 insertions(+), 167 deletions(-)
@@ -152,88 +152,202 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)autodep->clkdm.ptr=clkdm;}-/*-*_clkdm_add_autodeps-addautosleepdeps/wkdepstoclkdmuponclockenable-*@clkdm:structclockdomain*+/**+*_resolve_clkdm_deps()-resolveclkdm_namesin@clkdm_depstoclkdms+*@clkdm:clockdomainthatweareresolvingdependenciesfor+*@clkdm_deps:ptrtoarrayofstructclkdm_depstoresolve*-*Addthe"autodep"sleep&wakeupdependenciestoclockdomain'clkdm'-*inhardware-supervisedmode.Meanttobecalledfromclockframework-*whenaclockinsideclockdomain'clkdm'isenabled.Noreturnvalue.+*Iteratesthrough@clkdm_deps,lookingupthestructclockdomainnamedby+*clkdm_nameandstoringtheclockdomainpointerinthestructclkdm_dep.+*Noreturnvalue.+*/+staticvoid_resolve_clkdm_deps(structclockdomain*clkdm,+structclkdm_dep*clkdm_deps)+{+structclkdm_dep*cd;++for(cd=clkdm_deps;cd&&cd->clkdm_name;cd++){+if(cd->clkdm)+continue;+cd->clkdm=_clkdm_lookup(cd->clkdm_name);++WARN(!cd->clkdm,"clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",+clkdm->name,cd->clkdm_name);+}+}++/**+*_clkdm_add_wkdep-addawakeupdependencyfromclkdm2toclkdm1(lockless)+*@clkdm1:wakethisstructclockdomain*up(dependent)+*@clkdm2:whenthisstructclockdomain*wakesup(source)*-*XXXautodepsaredeprecatedandshouldberemovedattheearliest-*opportunity+*Whentheclockdomainrepresentedby@clkdm2wakesup,wakeup+*@clkdm1.ImplementedinhardwareontheOMAP,thisfeatureis+*designedtoreducewakeuplatencyofthedependentclockdomain@clkdm1.+*Returns-EINVALifpresentedwithinvalidclockdomainpointers,+*-ENOENTif@clkdm2cannotwakeupclkdm1inhardware,or0upon+*success.*/-void_clkdm_add_autodeps(structclockdomain*clkdm)+staticint_clkdm_add_wkdep(structclockdomain*clkdm1,+structclockdomain*clkdm2){-structclkdm_autodep*autodep;+structclkdm_dep*cd;+intret=0;-if(!autodeps||clkdm->flags&CLKDM_NO_AUTODEPS)-return;+if(!clkdm1||!clkdm2)+return-EINVAL;-for(autodep=autodeps;autodep->clkdm.ptr;autodep++){-if(IS_ERR(autodep->clkdm.ptr))-continue;+cd=_clkdm_deps_lookup(clkdm2,clkdm1->wkdep_srcs);+if(IS_ERR(cd))+ret=PTR_ERR(cd);-pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n",-clkdm->name,autodep->clkdm.ptr->name);+if(!arch_clkdm||!arch_clkdm->clkdm_add_wkdep)+ret=-EINVAL;-clkdm_add_sleepdep(clkdm,autodep->clkdm.ptr);-clkdm_add_wkdep(clkdm,autodep->clkdm.ptr);+if(ret){+pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",+clkdm1->name,clkdm2->name);+returnret;+}++if(atomic_inc_return(&cd->wkdep_usecount)==1){+pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",+clkdm1->name,clkdm2->name);++ret=arch_clkdm->clkdm_add_wkdep(clkdm1,clkdm2);}++returnret;}-/*-*_clkdm_add_autodeps-removeautosleepdeps/wkdepsfromclkdm-*@clkdm:structclockdomain*+/**+*_clkdm_del_wkdep-removeawakeupdepfromclkdm2toclkdm1(lockless)+*@clkdm1:wakethisstructclockdomain*up(dependent)+*@clkdm2:whenthisstructclockdomain*wakesup(source)*-*Removethe"autodep"sleep&wakeupdependenciesfromclockdomain'clkdm'-*inhardware-supervisedmode.Meanttobecalledfromclockframework-*whenaclockinsideclockdomain'clkdm'isdisabled.Noreturnvalue.+*Removeawakeupdependencycausing@clkdm1towakeupwhen@clkdm2+*wakesup.Returns-EINVALifpresentedwithinvalidclockdomain+*pointers,-ENOENTif@clkdm2cannotwakeupclkdm1inhardware,or+*0uponsuccess.+*/+staticint_clkdm_del_wkdep(structclockdomain*clkdm1,+structclockdomain*clkdm2)+{+structclkdm_dep*cd;+intret=0;++if(!clkdm1||!clkdm2)+return-EINVAL;++cd=_clkdm_deps_lookup(clkdm2,clkdm1->wkdep_srcs);+if(IS_ERR(cd))+ret=PTR_ERR(cd);++if(!arch_clkdm||!arch_clkdm->clkdm_del_wkdep)+ret=-EINVAL;++if(ret){+pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",+clkdm1->name,clkdm2->name);+returnret;+}++if(atomic_dec_return(&cd->wkdep_usecount)==0){+pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n",+clkdm1->name,clkdm2->name);++ret=arch_clkdm->clkdm_del_wkdep(clkdm1,clkdm2);+}++returnret;+}++/**+*_clkdm_add_sleepdep-addasleepdependencyfromclkdm2toclkdm1(lockless)+*@clkdm1:preventthisstructclockdomain*fromsleeping(dependent)+*@clkdm2:whenthisstructclockdomain*isactive(source)*-*XXXautodepsaredeprecatedandshouldberemovedattheearliest-*opportunity+*Prevent@clkdm1fromautomaticallygoinginactive(andthento+*retentionoroff)if@clkdm2isactive.Returns-EINVALif+*presentedwithinvalidclockdomainpointersorcalledonamachine+*thatdoesnotsupportsoftware-configurablehardwaresleep+*dependencies,-ENOENTifthespecifieddependencycannotbesetin+*hardware,or0uponsuccess.*/-void_clkdm_del_autodeps(structclockdomain*clkdm)+staticint_clkdm_add_sleepdep(structclockdomain*clkdm1,+structclockdomain*clkdm2){-structclkdm_autodep*autodep;+structclkdm_dep*cd;+intret=0;-if(!autodeps||clkdm->flags&CLKDM_NO_AUTODEPS)-return;+if(!clkdm1||!clkdm2)+return-EINVAL;-for(autodep=autodeps;autodep->clkdm.ptr;autodep++){-if(IS_ERR(autodep->clkdm.ptr))-continue;+cd=_clkdm_deps_lookup(clkdm2,clkdm1->sleepdep_srcs);+if(IS_ERR(cd))+ret=PTR_ERR(cd);-pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n",-clkdm->name,autodep->clkdm.ptr->name);+if(!arch_clkdm||!arch_clkdm->clkdm_add_sleepdep)+ret=-EINVAL;-clkdm_del_sleepdep(clkdm,autodep->clkdm.ptr);-clkdm_del_wkdep(clkdm,autodep->clkdm.ptr);+if(ret){+pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",+clkdm1->name,clkdm2->name);+returnret;}++if(atomic_inc_return(&cd->sleepdep_usecount)==1){+pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",+clkdm1->name,clkdm2->name);++ret=arch_clkdm->clkdm_add_sleepdep(clkdm1,clkdm2);+}++returnret;}/**-*_resolve_clkdm_deps()-resolveclkdm_namesin@clkdm_depstoclkdms-*@clkdm:clockdomainthatweareresolvingdependenciesfor-*@clkdm_deps:ptrtoarrayofstructclkdm_depstoresolve+*_clkdm_del_sleepdep-removeasleepdepfromclkdm2toclkdm1(lockless)+*@clkdm1:preventthisstructclockdomain*fromsleeping(dependent)+*@clkdm2:whenthisstructclockdomain*isactive(source)*-*Iteratesthrough@clkdm_deps,lookingupthestructclockdomainnamedby-*clkdm_nameandstoringtheclockdomainpointerinthestructclkdm_dep.-*Noreturnvalue.+*Allow@clkdm1toautomaticallygoinactive(andthentoretentionor+*off),independentoftheactivitystateof@clkdm2.Returns-EINVAL+*ifpresentedwithinvalidclockdomainpointersorcalledonamachine+*thatdoesnotsupportsoftware-configurablehardwaresleepdependencies,+*-ENOENTifthespecifieddependencycannotbeclearedinhardware,or+*0uponsuccess.*/-staticvoid_resolve_clkdm_deps(structclockdomain*clkdm,-structclkdm_dep*clkdm_deps)+staticint_clkdm_del_sleepdep(structclockdomain*clkdm1,+structclockdomain*clkdm2){structclkdm_dep*cd;+intret=0;-for(cd=clkdm_deps;cd&&cd->clkdm_name;cd++){-if(cd->clkdm)-continue;-cd->clkdm=_clkdm_lookup(cd->clkdm_name);+if(!clkdm1||!clkdm2)+return-EINVAL;-WARN(!cd->clkdm,"clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",-clkdm->name,cd->clkdm_name);+cd=_clkdm_deps_lookup(clkdm2,clkdm1->sleepdep_srcs);+if(IS_ERR(cd))+ret=PTR_ERR(cd);++if(!arch_clkdm||!arch_clkdm->clkdm_del_sleepdep)+ret=-EINVAL;++if(ret){+pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",+clkdm1->name,clkdm2->name);+returnret;}++if(atomic_dec_return(&cd->sleepdep_usecount)==0){+pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n",+clkdm1->name,clkdm2->name);++ret=arch_clkdm->clkdm_del_sleepdep(clkdm1,clkdm2);+}++returnret;}/* Public functions */
@@ -453,33 +567,7 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)*/intclkdm_add_wkdep(structclockdomain*clkdm1,structclockdomain*clkdm2){-structclkdm_dep*cd;-intret=0;--if(!clkdm1||!clkdm2)-return-EINVAL;--cd=_clkdm_deps_lookup(clkdm2,clkdm1->wkdep_srcs);-if(IS_ERR(cd))-ret=PTR_ERR(cd);--if(!arch_clkdm||!arch_clkdm->clkdm_add_wkdep)-ret=-EINVAL;--if(ret){-pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",-clkdm1->name,clkdm2->name);-returnret;-}--if(atomic_inc_return(&cd->wkdep_usecount)==1){-pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",-clkdm1->name,clkdm2->name);--ret=arch_clkdm->clkdm_add_wkdep(clkdm1,clkdm2);-}--returnret;+return_clkdm_add_wkdep(clkdm1,clkdm2);}/**
@@ -494,33 +582,7 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/intclkdm_del_wkdep(structclockdomain*clkdm1,structclockdomain*clkdm2){-structclkdm_dep*cd;-intret=0;--if(!clkdm1||!clkdm2)-return-EINVAL;--cd=_clkdm_deps_lookup(clkdm2,clkdm1->wkdep_srcs);-if(IS_ERR(cd))-ret=PTR_ERR(cd);--if(!arch_clkdm||!arch_clkdm->clkdm_del_wkdep)-ret=-EINVAL;--if(ret){-pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",-clkdm1->name,clkdm2->name);-returnret;-}--if(atomic_dec_return(&cd->wkdep_usecount)==0){-pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n",-clkdm1->name,clkdm2->name);--ret=arch_clkdm->clkdm_del_wkdep(clkdm1,clkdm2);-}--returnret;+return_clkdm_del_wkdep(clkdm1,clkdm2);}/**
@@ -597,33 +659,7 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)*/intclkdm_add_sleepdep(structclockdomain*clkdm1,structclockdomain*clkdm2){-structclkdm_dep*cd;-intret=0;--if(!clkdm1||!clkdm2)-return-EINVAL;--cd=_clkdm_deps_lookup(clkdm2,clkdm1->sleepdep_srcs);-if(IS_ERR(cd))-ret=PTR_ERR(cd);--if(!arch_clkdm||!arch_clkdm->clkdm_add_sleepdep)-ret=-EINVAL;--if(ret){-pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",-clkdm1->name,clkdm2->name);-returnret;-}--if(atomic_inc_return(&cd->sleepdep_usecount)==1){-pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",-clkdm1->name,clkdm2->name);--ret=arch_clkdm->clkdm_add_sleepdep(clkdm1,clkdm2);-}--returnret;+return_clkdm_add_sleepdep(clkdm1,clkdm2);}/**
@@ -640,33 +676,7 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/intclkdm_del_sleepdep(structclockdomain*clkdm1,structclockdomain*clkdm2){-structclkdm_dep*cd;-intret=0;--if(!clkdm1||!clkdm2)-return-EINVAL;--cd=_clkdm_deps_lookup(clkdm2,clkdm1->sleepdep_srcs);-if(IS_ERR(cd))-ret=PTR_ERR(cd);--if(!arch_clkdm||!arch_clkdm->clkdm_del_sleepdep)-ret=-EINVAL;--if(ret){-pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",-clkdm1->name,clkdm2->name);-returnret;-}--if(atomic_dec_return(&cd->sleepdep_usecount)==0){-pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n",-clkdm1->name,clkdm2->name);--ret=arch_clkdm->clkdm_del_sleepdep(clkdm1,clkdm2);-}--returnret;+return_clkdm_del_sleepdep(clkdm1,clkdm2);}/**
@@ -250,7 +250,7 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)/* Disable HW transitions when we are changing deps */omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,clkdm->clktrctrl_mask);-_clkdm_add_autodeps(clkdm);+clkdm_add_autodeps(clkdm);omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,clkdm->clktrctrl_mask);}else{
@@ -287,7 +287,7 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)/* Disable HW transitions when we are changing deps */omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,clkdm->clktrctrl_mask);-_clkdm_del_autodeps(clkdm);+clkdm_del_autodeps(clkdm);omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,clkdm->clktrctrl_mask);}else{
The atomic usecounts seem to be confusing, and are no longer needed
since the operations that they are attached to really should take
place under lock. Replace the atomic counters with simple integers,
protected by the enclosing powerdomain spinlock.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/clockdomain.c | 88 +++++++++++++++++++++++++++++++-----
arch/arm/mach-omap2/clockdomain.h | 6 +-
arch/arm/mach-omap2/cm3xxx.c | 6 +-
arch/arm/mach-omap2/cminst44xx.c | 2 -
arch/arm/mach-omap2/pm-debug.c | 6 +-
arch/arm/mach-omap2/pm.c | 3 +
arch/arm/mach-omap2/prm2xxx_3xxx.c | 3 +
7 files changed, 88 insertions(+), 26 deletions(-)
@@ -210,7 +210,8 @@ static int _clkdm_add_wkdep(struct clockdomain *clkdm1,returnret;}-if(atomic_inc_return(&cd->wkdep_usecount)==1){+cd->wkdep_usecount++;+if(cd->wkdep_usecount==1){pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",clkdm1->name,clkdm2->name);
@@ -252,7 +253,8 @@ static int _clkdm_del_wkdep(struct clockdomain *clkdm1,returnret;}-if(atomic_dec_return(&cd->wkdep_usecount)==0){+cd->wkdep_usecount--;+if(cd->wkdep_usecount==0){pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n",clkdm1->name,clkdm2->name);
@@ -296,7 +298,8 @@ static int _clkdm_add_sleepdep(struct clockdomain *clkdm1,returnret;}-if(atomic_inc_return(&cd->sleepdep_usecount)==1){+cd->sleepdep_usecount++;+if(cd->sleepdep_usecount==1){pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",clkdm1->name,clkdm2->name);
@@ -340,7 +343,8 @@ static int _clkdm_del_sleepdep(struct clockdomain *clkdm1,returnret;}-if(atomic_dec_return(&cd->sleepdep_usecount)==0){+cd->sleepdep_usecount--;+if(cd->sleepdep_usecount==0){pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n",clkdm1->name,clkdm2->name);
@@ -186,7 +186,7 @@ static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)continue;/* only happens if data is erroneous */mask|=1<<cd->clkdm->dep_bit;-atomic_set(&cd->sleepdep_usecount,0);+cd->sleepdep_usecount=0;}omap2_cm_clear_mod_reg_bits(mask,clkdm->pwrdm.ptr->prcm_offs,OMAP3430_CM_SLEEPDEP);
@@ -209,7 +209,7 @@ static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)staticvoidomap3xxx_clkdm_allow_idle(structclockdomain*clkdm){-if(atomic_read(&clkdm->usecount)>0)+if(clkdm->usecount>0)clkdm_add_autodeps(clkdm);omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
@@ -393,7 +393,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)continue;/* only happens if data is erroneous */mask|=1<<cd->clkdm->dep_bit;-atomic_set(&cd->wkdep_usecount,0);+cd->wkdep_usecount=0;}omap4_cminst_clear_inst_reg_bits(mask,clkdm->prcm_partition,
@@ -78,11 +78,12 @@ static void __init omap2_init_processor_devices(void)int__initomap_pm_clkdms_setup(structclockdomain*clkdm,void*unused){+/* XXX The usecount test is racy */if((clkdm->flags&CLKDM_CAN_ENABLE_AUTO)&&!(clkdm->flags&CLKDM_MISSING_IDLE_REPORTING))clkdm_allow_idle(clkdm);elseif(clkdm->flags&CLKDM_CAN_FORCE_SLEEP&&-atomic_read(&clkdm->usecount)==0)+clkdm->usecount==0)clkdm_sleep(clkdm);return0;}
@@ -210,6 +210,7 @@ int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,PM_WKDEP,(1<<clkdm2->dep_bit));}+/* XXX Caller must hold the clkdm's powerdomain lock */intomap2_clkdm_clear_all_wkdeps(structclockdomain*clkdm){structclkdm_dep*cd;
@@ -221,7 +222,7 @@ int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)/* PRM accesses are slow, so minimize them */mask|=1<<cd->clkdm->dep_bit;-atomic_set(&cd->wkdep_usecount,0);+cd->wkdep_usecount=0;}omap2_prm_clear_mod_reg_bits(mask,clkdm->pwrdm.ptr->prcm_offs,
The atomic usecounts seem to be confusing, and are no longer needed
since the operations that they are attached to really should take
place under lock. Replace the atomic counters with simple integers,
protected by the enclosing powerdomain spinlock.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <redacted>
---
arch/arm/mach-omap2/clockdomain.c | 88 +++++++++++++++++++++++++++++++-----
arch/arm/mach-omap2/clockdomain.h | 6 +-
arch/arm/mach-omap2/cm3xxx.c | 6 +-
arch/arm/mach-omap2/cminst44xx.c | 2 -
arch/arm/mach-omap2/pm-debug.c | 6 +-
arch/arm/mach-omap2/pm.c | 3 +
arch/arm/mach-omap2/prm2xxx_3xxx.c | 3 +
7 files changed, 88 insertions(+), 26 deletions(-)
@@ -210,7 +210,8 @@ static int _clkdm_add_wkdep(struct clockdomain *clkdm1,returnret;}-if(atomic_inc_return(&cd->wkdep_usecount)==1){+cd->wkdep_usecount++;+if(cd->wkdep_usecount==1){pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",clkdm1->name,clkdm2->name);
@@ -252,7 +253,8 @@ static int _clkdm_del_wkdep(struct clockdomain *clkdm1,returnret;}-if(atomic_dec_return(&cd->wkdep_usecount)==0){+cd->wkdep_usecount--;+if(cd->wkdep_usecount==0){pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n",clkdm1->name,clkdm2->name);
@@ -296,7 +298,8 @@ static int _clkdm_add_sleepdep(struct clockdomain *clkdm1,returnret;}-if(atomic_inc_return(&cd->sleepdep_usecount)==1){+cd->sleepdep_usecount++;+if(cd->sleepdep_usecount==1){pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",clkdm1->name,clkdm2->name);
@@ -340,7 +343,8 @@ static int _clkdm_del_sleepdep(struct clockdomain *clkdm1,returnret;}-if(atomic_dec_return(&cd->sleepdep_usecount)==0){+cd->sleepdep_usecount--;+if(cd->sleepdep_usecount==0){pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n",clkdm1->name,clkdm2->name);
@@ -186,7 +186,7 @@ static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)continue;/* only happens if data is erroneous */mask|=1<<cd->clkdm->dep_bit;-atomic_set(&cd->sleepdep_usecount,0);+cd->sleepdep_usecount=0;}omap2_cm_clear_mod_reg_bits(mask,clkdm->pwrdm.ptr->prcm_offs,OMAP3430_CM_SLEEPDEP);
@@ -209,7 +209,7 @@ static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)staticvoidomap3xxx_clkdm_allow_idle(structclockdomain*clkdm){-if(atomic_read(&clkdm->usecount)>0)+if(clkdm->usecount>0)clkdm_add_autodeps(clkdm);omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
@@ -393,7 +393,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)continue;/* only happens if data is erroneous */mask|=1<<cd->clkdm->dep_bit;-atomic_set(&cd->wkdep_usecount,0);+cd->wkdep_usecount=0;}omap4_cminst_clear_inst_reg_bits(mask,clkdm->prcm_partition,
@@ -78,11 +78,12 @@ static void __init omap2_init_processor_devices(void)int__initomap_pm_clkdms_setup(structclockdomain*clkdm,void*unused){+/* XXX The usecount test is racy */if((clkdm->flags&CLKDM_CAN_ENABLE_AUTO)&&!(clkdm->flags&CLKDM_MISSING_IDLE_REPORTING))clkdm_allow_idle(clkdm);elseif(clkdm->flags&CLKDM_CAN_FORCE_SLEEP&&-atomic_read(&clkdm->usecount)==0)+clkdm->usecount==0)clkdm_sleep(clkdm);return0;}
@@ -210,6 +210,7 @@ int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,PM_WKDEP,(1<<clkdm2->dep_bit));}+/* XXX Caller must hold the clkdm's powerdomain lock */
Isn't this comment applicable for all the internal api's
omap2_clkdm_clear_all_wkdeps,
omap3xxx_clkdm_add_sleepdep,
omap3xxx_clkdm_del_sleepdep,
omap3xxx_clkdm_read_sleepdep,
omap3xxx_clkdm_clear_all_sleepdeps,
int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
Why this function is non-static? typo??? May be I am missing something.
It was static before, but api became public by below commit -
ARM: OMAP2/3: clockdomain/PRM/CM: move the low-level clockdomain
functions into PRM/CM
Thanks,
Vaibhav
quoted hunk
{
struct clkdm_dep *cd;
@@ -221,7 +222,7 @@ int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) /* PRM accesses are slow, so minimize them */ mask |= 1 << cd->clkdm->dep_bit;- atomic_set(&cd->wkdep_usecount, 0);+ cd->wkdep_usecount = 0; } omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
Hi Paul,
On Sun, Dec 09, 2012 at 06:53:43, Paul Walmsley wrote:
The atomic usecounts seem to be confusing, and are no longer needed
since the operations that they are attached to really should take
place under lock. Replace the atomic counters with simple integers,
protected by the enclosing powerdomain spinlock.
[...]
quoted hunk
@@ -1063,7 +1123,8 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) * should be called for every clock instance or hwmod that is * enabled, so the clkdm can be force woken up. */- if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) {+ clkdm->usecount++;+ if (clkdm->usecount > 1 && autodeps) { pwrdm_unlock(clkdm->pwrdm.ptr); return 0; }
This is not directly related to this patch but something I noticed when I enabled
the various debug prints.
if the clkdm->usecount is > 1, there is still a call to arch_clkdm->clkdm_clk_enable().
Won't the usecount >1 guarantee that the clkdm is in the right state and the PRCM
access can be skipped?
Regards,
Vaibhav
@@ -303,37 +303,37 @@ static struct powerdomain usbhost_pwrdm = {.pwrsts_mem_on={[0]=PWRSTS_ON,/* MEMONSTATE */},-.voltdm={.name="core"},+.voltdm={.name="core"},};staticstructpowerdomaindpll1_pwrdm={.name="dpll1_pwrdm",.prcm_offs=MPU_MOD,-.voltdm={.name="mpu_iva"},+.voltdm={.name="mpu_iva"},};staticstructpowerdomaindpll2_pwrdm={.name="dpll2_pwrdm",.prcm_offs=OMAP3430_IVA2_MOD,-.voltdm={.name="mpu_iva"},+.voltdm={.name="mpu_iva"},};staticstructpowerdomaindpll3_pwrdm={.name="dpll3_pwrdm",.prcm_offs=PLL_MOD,-.voltdm={.name="core"},+.voltdm={.name="core"},};staticstructpowerdomaindpll4_pwrdm={.name="dpll4_pwrdm",.prcm_offs=PLL_MOD,-.voltdm={.name="core"},+.voltdm={.name="core"},};staticstructpowerdomaindpll5_pwrdm={.name="dpll5_pwrdm",.prcm_offs=PLL_MOD,-.voltdm={.name="core"},+.voltdm={.name="core"},};/* As powerdomains are added or removed above, this list must also be changed */
From: Tero Kristo <hidden> Date: 2013-01-04 13:07:40
Hi Paul,
I just tested this + next two powerdomain series from you on omap3beagle
+ omap4panda boards. This set seems fine, for the code I don't have any
major complaints either, thus you can add my ack if you like. I'll send
comments for the next two sets soon also.
-Tero
On Sat, 2012-12-08 at 18:23 -0700, Paul Walmsley wrote:
Several more OMAP2+ power management fixes, optimizations, and
cleanup, intended for 3.9. This series is also a prerequisite for the
functional powerdomain conversion series.
I'll plan to bundle these patches together into a pull request with the first
set of 3.9 PM patches, sent earlier.
- Paul
---
vmlinux object size
(delta in bytes from TEST_pm_cleanup_fixes_a_3.9 (8f5e20850396fc60fd4ee01f586705033902bb53)):
text data bss total kernel
+460 -368 0 +92 am33xx_only
+200 -464 0 -264 n800_multi_omap2xxx
+192 -144 0 +48 n800_only_a
0 0 0 0 omap1_defconfig
0 0 0 0 omap1_defconfig_1510innovator_only
0 0 0 0 omap1_defconfig_5912osk_only
+296 -1816 0 -1520 omap2plus_defconfig
+272 -176 0 +96 omap2plus_defconfig_2430sdp_only
+232 -1816 0 -1584 omap2plus_defconfig_cpupm
+280 -1520 0 -1240 omap2plus_defconfig_no_pm
+4388 -1016 0 +3372 omap2plus_defconfig_omap2_4_only
+468 -952 0 -484 omap2plus_defconfig_omap3_4_only
+700 -584 -144 -28 rmk_omap3430_ldp_allnoconfig
+452 -648 0 -196 rmk_omap3430_ldp_oldconfig
+700 -584 -144 -28 rmk_omap4430_sdp_allnoconfig
+424 -328 0 +96 rmk_omap4430_sdp_oldconfig
Boot-time memory difference
(delta in bytes from TEST_pm_cleanup_fixes_a_3.9 (8f5e20850396fc60fd4ee01f586705033902bb53))
avail rsrvd high freed board kconfig
4k -4k . . 2430sdp omap2plus_defconfig
4k -4k . . 3517evm omap2plus_defconfig
4k -4k . . 3530es3beagle omap2plus_defconfig
4k -4k . . 3730beaglexm omap2plus_defconfig
4k -4k . . 37xxevm omap2plus_defconfig
4k -4k . . 4430es2panda omap2plus_defconfig
4k -4k . . cmt3517 omap2plus_defconfig
Paul Walmsley (10):
ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
ARM: OMAP2+: clockdomain: add pwrdm_state_switch() call to clkdm_sleep()
ARM: OMAP2xxx: PM: clean up some crufty powerstate programming code
ARM: OMAP2: PM/powerdomain: drop unnecessary pwrdm_wait_transition()
ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock
ARM: OMAP2xxx: CM: remove autodep handling
ARM: OMAP2+: clockdomain: work on wkdep/sleepdep functions
ARM: OMAP2+: clockdomain: convert existing atomic usecounts into spinlock-protected shorts/ints
ARM: OMAP2+: powerdomain: fix whitespace, improve flag comments
arch/arm/mach-omap2/clockdomain-powerdomain.h | 22 +
arch/arm/mach-omap2/clockdomain.c | 550 +++++++++++++++-------
arch/arm/mach-omap2/clockdomain.h | 17 -
arch/arm/mach-omap2/cm2xxx.c | 33 -
arch/arm/mach-omap2/cm3xxx.c | 14 -
arch/arm/mach-omap2/cminst44xx.c | 2
arch/arm/mach-omap2/cpuidle34xx.c | 14 -
arch/arm/mach-omap2/cpuidle44xx.c | 28 +
arch/arm/mach-omap2/pm-debug.c | 6
arch/arm/mach-omap2/pm.c | 65 ---
arch/arm/mach-omap2/pm.h | 1
arch/arm/mach-omap2/pm24xx.c | 30 -
arch/arm/mach-omap2/powerdomain-clockdomain.h | 27 +
arch/arm/mach-omap2/powerdomain.c | 176 +++++--
arch/arm/mach-omap2/powerdomain.h | 42 +-
arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c | 4
arch/arm/mach-omap2/powerdomains2xxx_data.c | 8
arch/arm/mach-omap2/powerdomains3xxx_data.c | 44 +-
arch/arm/mach-omap2/prm2xxx_3xxx.c | 3
19 files changed, 661 insertions(+), 425 deletions(-)
create mode 100644 arch/arm/mach-omap2/clockdomain-powerdomain.h
create mode 100644 arch/arm/mach-omap2/powerdomain-clockdomain.h
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel