ARM: OMAP2+: second set of PM fixes and cleanup for 3.9
Subsystems (6)
Paul Walmsley
maintainercover ARM: OMAP2+: second set of PM fixes and cleanup for 3.9
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_oldconfigBoot-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_defconfigPaul 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
Paul Walmsley
maintainerPATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
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 */$
--- arch/arm/mach-omap2/cpuidle34xx.c | 14 +++++++++----- arch/arm/mach-omap2/cpuidle44xx.c | 28 ++++++++++++++++------------ 2 files changed, 25 insertions(+), 17 deletions(-)
arch/arm/mach-omap2/cpuidle34xx.c +9 -5
@@ -53,6 +53,8 @@ struct omap3_idle_statedata {*/ #define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE BIT(0) +static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; +/* * Prevent PER OFF if CORE is not in RETention or OFF as this would * disable PER wakeups completely.
@@ -97,7 +99,7 @@ static struct omap3_idle_statedata omap3_idle_data[] = { }, }; -static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; +/* Private functions */ static int __omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv,
@@ -269,11 +271,11 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,return ret; } -DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); +static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); -struct cpuidle_driver omap3_idle_driver = { - .name ="omap3_idle" , - .owner =THIS_MODULE , +static struct cpuidle_driver omap3_idle_driver = { + .name ="omap3_idle" , + .owner =THIS_MODULE , .states = { { .enter = omap3_enter_idle_bm,
@@ -336,6 +338,8 @@ struct cpuidle_driver omap3_idle_driver = { .safe_state_index = 0, }; +/* Public functions */ +/** * omap3_idle_init - Init routine for OMAP3 idle *
arch/arm/mach-omap2/cpuidle44xx.c +16 -12
@@ -54,6 +54,8 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];static atomic_t abort_barrier;static bool cpu_done[NR_CPUS ]; +/* Private functions */ +/** * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions * @dev: cpuidle device
@@ -161,9 +163,19 @@ fail:return index; } -DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); +/* +* For each cpu, setup the broadcast timer because local timers +* stops for the states above C1. +*/ +static void omap_setup_broadcast_timer (void *arg) +{ +int cpu =smp_processor_id (); +clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ON , &cpu); +} + +static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); -struct cpuidle_driver omap4_idle_driver = { +static struct cpuidle_driver omap4_idle_driver = { .name ="omap4_idle" , .owner =THIS_MODULE , .en_core_tk_irqen =1 ,
@@ -178,7 +190,7 @@ struct cpuidle_driver omap4_idle_driver = { .desc = "MPUSS ON" }, { -/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ +/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ .exit_latency = 328 + 440, .target_residency = 960, .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
@@ -200,15 +212,7 @@ struct cpuidle_driver omap4_idle_driver = { .safe_state_index = 0, }; -/* -* For each cpu, setup the broadcast timer because local timers -* stops for the states above C1. -*/ -static void omap_setup_broadcast_timer (void *arg) -{ -int cpu =smp_processor_id (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ON , &cpu); -} +/* Public functions */ /** * omap4_idle_init - Init routine for OMAP4 idle
PATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
Quoted 13 lines · Paul Walmsley
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",$
Quoted 9 lines
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.carch/arm/mach-omap2/powerdomain.c:811:2: warning: context imbalance in 'pwrdm_lock': unexpected unlockarch/arm/mach-omap2/powerdomain.c:811:2: default context: wanted 1, got 0include/linux/spinlock.h:340:2: warning: context problem in 'pwrdm_unlock': '_raw_spin_unlock_irqrestore' expected different contextinclude/linux/spinlock.h:340:2: context 'lock': wanted >= 1, got 0arch/arm/mach-omap2/powerdomain.c:1130:14: warning: context problem in 'pwrdm_state_switch': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1130:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1295:14: warning: context problem in 'pwrdm_set_next_fpwrst': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1295:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1317:14: warning: context problem in 'pwrdm_read_next_fpwrst': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1317:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1382:14: warning: context problem in 'pwrdm_set_fpwrst': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1382:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1407:14: warning: context problem in 'pwrdm_read_fpwrst': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1407:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1432:14: warning: context problem in 'pwrdm_read_prev_fpwrst': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1432:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1505:14: warning: context problem in 'pwrdm_dbg_show_counter': 'pwrdm_unlock' expected different contextarch/arm/mach-omap2/powerdomain.c:1505:14: default context: wanted >=
1, got 0arch/arm/mach-omap2/powerdomain.c:1542:14: warning: context problem in 'pwrdm_dbg_show_timer': 'pwrdm_unlock' expected different contextarch/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
Paul Walmsley
maintainerPATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
Quoted 3 lines · Vaibhav Hiremath
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
PATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
Quoted 10 lines · Paul Walmsley
Quoted 3 lines · Vaibhav Hiremath
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 <[email protected]>
Date: Sun Dec 9 13:06:51 2012 -0700
build fixes
Does this also fix sparse warnings?
Thanks,
Vaibhav
Quoted 3 lines
- Paul
Paul Walmsley
maintainerPATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
Quoted 14 lines · Vaibhav
Quoted 4 lines · Paul Walmsley
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 <[email protected]>
Date: Sun Dec 9 13:06:51 2012 -0700
Quoted 5 lines
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 <[email protected]>
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$
PATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
Quoted 20 lines · Paul Walmsley
Quoted 18 lines · Vaibhav
Quoted 4 lines · Paul Walmsley
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 <[email protected]>
Date: Sun Dec 9 13:06:51 2012 -0700build fixes
Quoted 7 lines
Quoted 1 line
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
PATCH 1/10 ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
In reply to Paul WalmsleyQuoted 17 lines · Paul Walmsley
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,$
Quoted 8 lines
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 <[email protected]>Cc Kevin Hilman <[email protected]>---
Paul Walmsley
maintainerPATCH 2/10 ARM: OMAP2+: clockdomain: add pwrdm_state_switch() call to clkdm_sleep()
In reply to Paul WalmsleyIn 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.
--- arch/arm/mach-omap2/clockdomain.c | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-omap2/clockdomain.c +1 -0
@@ -763,6 +763,7 @@ int clkdm_sleep(struct clockdomain *clkdm)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);return ret; }
Paul Walmsley
maintainerPATCH 3/10 ARM: OMAP2xxx: PM: clean up some crufty powerstate programming code
In reply to Paul WalmsleyDon'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.
--- arch/arm/mach-omap2/pm24xx.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-)
arch/arm/mach-omap2/pm24xx.c +10 -20
@@ -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 ); -/* -* Set MPU powerdomain's next power state to RETENTION; -* preserve logic state during retention -*/ -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 */
@@ -136,6 +132,9 @@ no_sleep:/* Mask future PRCM-to-MPU interrupts */ omap2_prm_write_mod_reg (0x0 ,OCP_MOD ,OMAP2_PRCM_IRQSTATUS_MPU_OFFSET ); +pwrdm_set_next_pwrst (mpu_pwrdm,PWRDM_POWER_ON ); +pwrdm_set_next_pwrst (core_pwrdm,PWRDM_POWER_ON ); +return 0 ; }
@@ -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 ); }static int omap2_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 ); -/* -* Set MPU powerdomain's next power state to RETENTION; -* preserve logic state during retention -*/ 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 );
Paul Walmsley
maintainerPATCH 4/10 ARM: OMAP2: PM/powerdomain: drop unnecessary pwrdm_wait_transition()
In reply to Paul WalmsleyDrop 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.
--- 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(-)
arch/arm/mach-omap2/pm.c +0 -1
@@ -139,7 +139,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)break ;case LOWPOWERSTATE_SWITCH :pwrdm_set_lowpwrstchange (pwrdm); -pwrdm_wait_transition (pwrdm);pwrdm_state_switch (pwrdm);break ; }
arch/arm/mach-omap2/powerdomain.c +5 -25
@@ -112,7 +112,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)for (i =0 ; i < pwrdm->banks; i++) pwrdm->ret_mem_off_counter[i] =0 ; -pwrdm_wait_transition (pwrdm); + arch_pwrdm->pwrdm_wait_transition (pwrdm); pwrdm->state =pwrdm_read_pwrst (pwrdm); pwrdm->state_counter[pwrdm->state] =1 ;
@@ -950,34 +950,14 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)return ret; } -/** -* pwrdm_wait_transition - wait for powerdomain power transition to finish -* @pwrdm: struct powerdomain * to wait for -* -* If the powerdomain @pwrdm is in the process of a state transition, -* spin until it completes the power transition, or until an iteration -* bailout value is reached. Returns -EINVAL if the powerdomain -* pointer is null, -EAGAIN if the bailout value was reached, or -* returns 0 upon success. -*/ -int pwrdm_wait_transition (struct powerdomain *pwrdm) -{ -int ret = -EINVAL ; - -if (!pwrdm) -return -EINVAL ; - -if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) - ret = arch_pwrdm->pwrdm_wait_transition (pwrdm); - -return ret; -} -int pwrdm_state_switch (struct powerdomain *pwrdm) {int ret; - ret =pwrdm_wait_transition (pwrdm); +if (!pwrdm || !arch_pwrdm) +return -EINVAL ; + + ret = arch_pwrdm->pwrdm_wait_transition (pwrdm);if (!ret) ret =_pwrdm_state_switch (pwrdm,PWRDM_STATE_NOW );
arch/arm/mach-omap2/powerdomain.h +0 -2
@@ -225,8 +225,6 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_disable_hdwr_sar (struct powerdomain *pwrdm);bool pwrdm_has_hdwr_sar (struct powerdomain *pwrdm); -int pwrdm_wait_transition (struct powerdomain *pwrdm); -int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm);
Paul Walmsley
maintainerPATCH 5/10 ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
In reply to Paul WalmsleyMove 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.
--- 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(-)
arch/arm/mach-omap2/pm.c +0 -61
@@ -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 __init omap_pm_clkdms_setup (struct clockdomain *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
arch/arm/mach-omap2/pm.h +0 -1
@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap_sram_idle (void ); -extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void );
arch/arm/mach-omap2/powerdomain.c +83 -29
124 lines not on this page · raw message
arch/arm/mach-omap2/powerdomain.h +2 -1
@@ -228,10 +228,11 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm); -int pwrdm_set_lowpwrstchange (struct powerdomain *pwrdm);int pwrdm_get_context_loss_count (struct powerdomain *pwrdm);bool pwrdm_can_ever_lose_context (struct powerdomain *pwrdm); +extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u8 state); +extern void omap242x_powerdomains_init (void );extern void omap243x_powerdomains_init (void );extern void omap3xxx_powerdomains_init (void );
PATCH 5/10 ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
Hi Paul,
Quoted 4 lines · Paul Walmsley
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.
Quoted 115 lines
Signed-off-by Paul Walmsley <[email protected]>Cc Jean Pihet <[email protected]>Cc Kevin Hilman <[email protected]>--- 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(-)arch/arm/mach-omap2/pm.c +0
-61@@ -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 __init omap_pm_clkdms_setup (struct clockdomain *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 ofarch/arm/mach-omap2/pm.h +0
-1@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap_sram_idle (void ); -extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void );arch/arm/mach-omap2/powerdomain.c +0
-1@@ -921,35 +921,6 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)return (pwrdm && pwrdm->flags &PWRDM_HAS_HDWR_SAR ) ?1 :0 ; } -/**
arch/arm/mach-omap2/powerdomain.c bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) · line 924
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c +0
-9-* 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?
-int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
Quoted 22 lines
arch/arm/mach-omap2/powerdomain.c +0
-18-{ -int ret = -EINVAL ; - -if (!pwrdm) -return -EINVAL ; - -if (!(pwrdm->flags &PWRDM_HAS_LOWPOWERSTATECHANGE )) -return -EINVAL ; - -pr_debug ("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n" , - pwrdm->name); - -if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange) - ret = arch_pwrdm->pwrdm_set_lowpwrstchange (pwrdm); - -return ret; -} -int pwrdm_state_switch (struct powerdomain *pwrdm) {int ret;
arch/arm/mach-omap2/powerdomain.c int pwrdm_post_transition(struct powerdomain *pwrdm) · line 962
Quoted 8 lines
arch/arm/mach-omap2/powerdomain.c +4
-0@@ -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. ?
arch/arm/mach-omap2/powerdomain.c int pwrdm_post_transition(struct powerdomain *pwrdm) · line 964
Quoted 3 lines
arch/arm/mach-omap2/powerdomain.c +3
-0+ +static u8 _pwrdm_save_clkdm_state_and_activate (struct powerdomain *pwrdm, +u8 pwrst,bool *hwsup)
+{
Quoted 11 lines
arch/arm/mach-omap2/powerdomain.c +11
-0+u8 curr_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 ]);
arch/arm/mach-omap2/powerdomain.c int pwrdm_post_transition(struct powerdomain *pwrdm)
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c +9
-0+ sleep_switch =FORCEWAKEUP_SWITCH ; + } + }else { + sleep_switch =ALREADYACTIVE_SWITCH ; + } + +return sleep_switch; +} +
Same here
Quoted 14 lines
arch/arm/mach-omap2/powerdomain.c +14
-0+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);
arch/arm/mach-omap2/powerdomain.c int pwrdm_post_transition(struct powerdomain *pwrdm)
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c +9
-0+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
Quoted 47 lines
arch/arm/mach-omap2/powerdomain.c +25
-0+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_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",
arch/arm/mach-omap2/powerdomain.c +7
-0+ __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 arch/arm/mach-omap2/powerdomain.h +0
-0@@ -228,10 +228,11 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);
arch/arm/mach-omap2/powerdomain.h bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); · line 238
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.h +2
-1int pwrdm_post_transition (struct powerdomain *pwrdm); -int pwrdm_set_lowpwrstchange (struct powerdomain *pwrdm);int pwrdm_get_context_loss_count (struct powerdomain *pwrdm);bool pwrdm_can_ever_lose_context (struct powerdomain *pwrdm); +extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u8 state); +extern void omap242x_powerdomains_init (void );extern void omap243x_powerdomains_init (void );extern void omap3xxx_powerdomains_init (void );
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121212/3e4e3a15/attachment-0001.html>
Paul Walmsley
maintainerPATCH 5/10 ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
Hi,
(redacted irrelevant code sections)
Quoted 14 lines · Jean Pihet
Quoted 11 lines · Paul Walmsley
-/**
- *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-EINVALif the powerdomain pointer is null or if the
- * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
- * upon success.
- */
Quoted 1 line
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 4 lines
Quoted 4 lines
(quoted diff) +0
-0@@ -984,6 +955,89 @@ int pwrdm_post_transition(struct powerdomain *pwrdm) return 0; }
Quoted 8 lines
Review int pwrdm_post_transition(struct powerdomain *pwrdm) · line 962
Quoted 5 lines
(quoted diff) +4
-0+/* Types of sleep_switch used in omap_set_pwrdm_state */ +#define ALREADYACTIVE_SWITCH 0 +#define FORCEWAKEUP_SWITCH 1 +#define LOWPOWERSTATE_SWITCH 2Could 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().
Quoted 10 lines
Review int pwrdm_post_transition(struct powerdomain *pwrdm) · line 965
Quoted 3 lines
(quoted diff) +3
-0+ +static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, + u8 pwrst, bool *hwsup)Same here
Review int pwrdm_post_transition(struct powerdomain *pwrdm) · line 967
Quoted 2 lines
(quoted diff) +2
-0+static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, + u8 sleep_switch, bool hwsup)Same here.
I've added kerneldoc for both of these functions.
Quoted 6 lines
Review int pwrdm_post_transition(struct powerdomain *pwrdm) · line 972
Quoted 5 lines
(quoted diff) +4
-0+/* + * 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 <[email protected]>
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.)
--- 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(-)
arch/arm/mach-omap2/pm.c +0 -61
@@ -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 __init omap_pm_clkdms_setup (struct clockdomain *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) }/* -* 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
arch/arm/mach-omap2/pm.h +0 -1
@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap_sram_idle (void ); -extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void );
arch/arm/mach-omap2/powerdomain.c +132 -29
185 lines not on this page · raw message
arch/arm/mach-omap2/powerdomain.h +12 -1
@@ -162,6 +162,16 @@ struct powerdomain {* @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep * @pwrdm_wait_transition: Wait for a pd state transition to complete +* +* Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family +* chips, a powerdomain's power state is not allowed to directly +* transition from one low-power state (e.g., CSWR) to another +* low-power state (e.g., OFF) without first waking up the +* powerdomain. This wastes energy. So OMAP4 chips support the +* ability to transition a powerdomain power state directly from one +* low-power state to another. The function pointed to by +* @pwrdm_set_lowpwrstchange is intended to configure the OMAP4 +* hardware powerdomain state machine to enable this feature. */ struct pwrdm_ops {int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm,u8 pwrst);
@@ -228,10 +238,11 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm); -int pwrdm_set_lowpwrstchange (struct powerdomain *pwrdm);int pwrdm_get_context_loss_count (struct powerdomain *pwrdm);bool pwrdm_can_ever_lose_context (struct powerdomain *pwrdm); +extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u8 state); +extern void omap242x_powerdomains_init (void );extern void omap243x_powerdomains_init (void );extern void omap3xxx_powerdomains_init (void );
Signature · 1 line
1.7.10.4
PATCH 5/10 ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
In reply to Paul WalmsleyMinor comment below,
Quoted 32 lines · Paul Walmsley
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 <[email protected]>Cc Jean Pihet <[email protected]>Cc Kevin Hilman <[email protected]>--- 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(-)arch/arm/mach-omap2/pm.c +0
-4@@ -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 __init omap_pm_clkdms_setup (struct clockdomain *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) }
arch/arm/mach-omap2/pm.c int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) · line 103
Quoted 10 lines
arch/arm/mach-omap2/pm.c +0
-9/* -* 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))
You can use IS_ERR_OR_NULL here.
Thanks,
Vaibhav
Quoted 218 lines
arch/arm/mach-omap2/pm.c +0
-48-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 arch/arm/mach-omap2/pm.h +0
-1@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap_sram_idle (void ); -extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void );arch/arm/mach-omap2/powerdomain.c +83
-29@@ -921,35 +921,6 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)return (pwrdm && pwrdm->flags &PWRDM_HAS_HDWR_SAR ) ?1 :0 ; } -/** -* 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. -*/ -int pwrdm_set_lowpwrstchange (struct powerdomain *pwrdm) -{ -int ret = -EINVAL ; - -if (!pwrdm) -return -EINVAL ; - -if (!(pwrdm->flags &PWRDM_HAS_LOWPOWERSTATECHANGE )) -return -EINVAL ; - -pr_debug ("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n" , - pwrdm->name); - -if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange) - ret = arch_pwrdm->pwrdm_set_lowpwrstchange (pwrdm); - -return ret; -} -int pwrdm_state_switch (struct powerdomain *pwrdm) {int ret;@@ -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 + +static u8 _pwrdm_save_clkdm_state_and_activate (struct powerdomain *pwrdm, +u8 pwrst,bool *hwsup) +{ +u8 curr_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 ; + } + +return sleep_switch; +} + +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. +*/ +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_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 arch/arm/mach-omap2/powerdomain.h +2
-1@@ -228,10 +228,11 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm); -int pwrdm_set_lowpwrstchange (struct powerdomain *pwrdm);int pwrdm_get_context_loss_count (struct powerdomain *pwrdm);bool pwrdm_can_ever_lose_context (struct powerdomain *pwrdm); +extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u8 state); +extern void omap242x_powerdomains_init (void );extern void omap243x_powerdomains_init (void );extern void omap3xxx_powerdomains_init (void );_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 5/10 ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
Quoted 8 lines · Vaibhav Hiremath
arch/arm/mach-omap2/pm.c int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) · line 103
Quoted 6 lines
arch/arm/mach-omap2/pm.c +0
-6-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_NULLhere.
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.
PATCH 5/10 ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code
In reply to Paul WalmsleyHi Paul,
-resending in plain text only, sorry about that-
Quoted 4 lines · Paul Walmsley
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.
Quoted 111 lines
Signed-off-by Paul Walmsley <[email protected]>Cc Jean Pihet <[email protected]>Cc Kevin Hilman <[email protected]>--- 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(-)arch/arm/mach-omap2/pm.c +0
-61@@ -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 __init omap_pm_clkdms_setup (struct clockdomain *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 arch/arm/mach-omap2/pm.h +0
-1@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap_sram_idle (void ); -extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void );arch/arm/mach-omap2/powerdomain.c +0
-0@@ -921,35 +921,6 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)return (pwrdm && pwrdm->flags &PWRDM_HAS_HDWR_SAR ) ?1 :0 ; }
arch/arm/mach-omap2/powerdomain.c bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) · line 933
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c +0
-10-/** -* 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?
Could you add some more documentation here?
What is the goal of the function, what does it return etc. ?
Quoted 16 lines
arch/arm/mach-omap2/powerdomain.c +14
-0+ +static u8 _pwrdm_save_clkdm_state_and_activate (struct powerdomain *pwrdm, +u8 pwrst,bool *hwsup) +{ +u8 curr_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 ]);
arch/arm/mach-omap2/powerdomain.c int pwrdm_post_transition(struct powerdomain *pwrdm) · line 985
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c +10
-0+clkdm_wakeup (pwrdm->pwrdm_clkdms[0 ]); + sleep_switch =FORCEWAKEUP_SWITCH ; + } + }else { + sleep_switch =ALREADYACTIVE_SWITCH ; + } + +return sleep_switch; +} +
Same here
Quoted 14 lines
arch/arm/mach-omap2/powerdomain.c +13
-0+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/arm/mach-omap2/powerdomain.c int pwrdm_post_transition(struct powerdomain *pwrdm) · line 1008
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c +10
-0+ 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 34 lines
activate(pwrdm, pwrst,
arch/arm/mach-omap2/powerdomain.c +12
-0+ &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 arch/arm/mach-omap2/powerdomain.h +2
-1@@ -228,10 +228,11 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm); -int pwrdm_set_lowpwrstchange (struct powerdomain *pwrdm);int pwrdm_get_context_loss_count (struct powerdomain *pwrdm);bool pwrdm_can_ever_lose_context (struct powerdomain *pwrdm); +extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u8 state); +extern void omap242x_powerdomains_init (void );extern void omap243x_powerdomains_init (void );extern void omap3xxx_powerdomains_init (void );
Paul Walmsley
maintainerPATCH 6/10 ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock
In reply to Paul WalmsleyAdd 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.
--- arch/arm/mach-omap2/clockdomain-powerdomain.h | 22 +++ arch/arm/mach-omap2/clockdomain.c | 161 +++++++++++++++++-------- arch/arm/mach-omap2/clockdomain.h | 6 + arch/arm/mach-omap2/powerdomain-clockdomain.h | 27 ++++ arch/arm/mach-omap2/powerdomain.c | 56 ++++++++- arch/arm/mach-omap2/powerdomain.h | 11 +- 6 files changed, 219 insertions(+), 64 deletions(-) create mode 100644 arch/arm/mach-omap2/clockdomain-powerdomain.h create mode 100644 arch/arm/mach-omap2/powerdomain-clockdomain.h
arch/arm/mach-omap2/clockdomain-powerdomain.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +* OMAP clockdomain framework functions for use only by the powerdomain 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
arch/arm/mach-omap2/clockdomain.c +108 -53
295 lines not on this page · raw message
arch/arm/mach-omap2/clockdomain.h +4 -2
@@ -15,7 +15,6 @@#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H#include <linux/init.h> -#include <linux/spinlock.h> #include "powerdomain.h" #include "clock.h"
@@ -139,7 +138,6 @@ struct clockdomain {struct clkdm_dep *sleepdep_srcs;atomic_t usecount;struct list_head node; -spinlock_t lock; };/**
@@ -196,12 +194,16 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);int clkdm_read_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2);int clkdm_clear_all_sleepdeps (struct clockdomain *clkdm); +void clkdm_allow_idle_nolock (struct clockdomain *clkdm);void clkdm_allow_idle (struct clockdomain *clkdm); +void clkdm_deny_idle_nolock (struct clockdomain *clkdm);void clkdm_deny_idle (struct clockdomain *clkdm);bool clkdm_in_hwsup (struct clockdomain *clkdm);bool clkdm_missing_idle_reporting (struct clockdomain *clkdm); +int clkdm_wakeup_nolock (struct clockdomain *clkdm);int clkdm_wakeup (struct clockdomain *clkdm); +int clkdm_sleep_nolock (struct clockdomain *clkdm);int clkdm_sleep (struct clockdomain *clkdm);int clkdm_clk_enable (struct clockdomain *clkdm,struct clk *clk);
arch/arm/mach-omap2/powerdomain-clockdomain.h new file +27 -0
@@ -0,0 +1,27 @@ +/* +* OMAP powerdomain functions only for use by the OMAP clockdomain 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. +* +* The point of this file is to try to prevent other code outside of +* clockdomain.c from calling the functions listed herein. Yes, this +* means you. +*/ + +#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_CLOCKDOMAIN_H +#define __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_CLOCKDOMAIN_H + +#include <linux/types.h> + +#include "powerdomain.h" + +extern void pwrdm_lock (struct powerdomain *pwrdm); +extern void pwrdm_unlock (struct powerdomain *pwrdm); +extern int pwrdm_state_switch_nolock (struct powerdomain *pwrdm); + +#endif
arch/arm/mach-omap2/powerdomain.c +50 -6
124 lines not on this page · raw message
arch/arm/mach-omap2/powerdomain.h +8 -3
@@ -19,8 +19,7 @@#include <linux/types.h> #include <linux/list.h> - -#include <linux/atomic.h> +#include <linux/spinlock.h> #include "voltage.h"
@@ -103,6 +102,8 @@ struct powerdomain;* @state_counter: * @timer: * @state_timer: +* @_lock: spinlock used to serialize powerdomain and some clockdomain ops +* @_lock_flags: stored flags when @_lock is taken * * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h. */
@@ -127,7 +128,8 @@ struct powerdomain {unsigned state_counter[PWRDM_MAX_PWRSTS ];unsigned ret_logic_off_counter;unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS ]; - +spinlock_t _lock; +unsigned long _lock_flags;const u8 pwrstctrl_offs;const u8 pwrstst_offs;const u32 logicretstate_mask;
@@ -225,6 +227,7 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_disable_hdwr_sar (struct powerdomain *pwrdm);bool pwrdm_has_hdwr_sar (struct powerdomain *pwrdm); +int pwrdm_state_switch_nolock (struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm);
@@ -252,5 +255,7 @@ extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);extern struct powerdomain wkup_omap2_pwrdm;extern struct powerdomain gfx_omap2_pwrdm; +extern void pwrdm_lock (struct powerdomain *pwrdm); +extern void pwrdm_unlock (struct powerdomain *pwrdm);#endif
PATCH 6/10 ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock
Paul,
Quoted 5 lines · Paul Walmsley
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
Quoted 626 lines
Signed-off-by Paul Walmsley <[email protected]>Cc Jean Pihet <[email protected]>--- arch/arm/mach-omap2/clockdomain-powerdomain.h | 22 +++ arch/arm/mach-omap2/clockdomain.c | 161 +++++++++++++++++-------- arch/arm/mach-omap2/clockdomain.h | 6 + arch/arm/mach-omap2/powerdomain-clockdomain.h | 27 ++++ arch/arm/mach-omap2/powerdomain.c | 56 ++++++++- arch/arm/mach-omap2/powerdomain.h | 11 +- 6 files changed, 219 insertions(+), 64 deletions(-) create mode 100644 arch/arm/mach-omap2/clockdomain-powerdomain.h create mode 100644 arch/arm/mach-omap2/powerdomain-clockdomain.harch/arm/mach-omap2/clockdomain-powerdomain.h new file +2
-0@@ -0,0 +1,22 @@ +/* +* OMAP clockdomain framework functions for use only by the powerdomain 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.
+ */arch/arm/mach-omap2/clockdomain-powerdomain.h new file +12
-0+ +#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 arch/arm/mach-omap2/clockdomain.c +6
-8@@ -30,6 +30,7 @@#include "soc.h" #include "clock.h" #include "clockdomain.h" +#include "powerdomain-clockdomain.h" /* clkdm_list contains all registered struct clockdomains */ static LIST_HEAD (clkdm_list);@@ -91,8 +92,6 @@ static int _clkdm_register(struct clockdomain *clkdm)pwrdm_add_clkdm (pwrdm, clkdm); -spin_lock_init (&clkdm->lock); -pr_debug ("clockdomain: registered %s\n" , clkdm->name);return 0 ;@@ -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;arch/arm/mach-omap2/clockdomain.c +73
-22@@ -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 ;@@ -833,11 +867,26 @@ void clkdm_allow_idle(struct clockdomain *clkdm) pr_debug("clockdomain: enabling automatic idle transitions for %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); }/**
arch/arm/mach-omap2/clockdomain.c +20
-7@@ -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 ;@@ -868,11 +916,25 @@ void clkdm_deny_idle(struct clockdomain *clkdm) pr_debug("clockdomain: disabling automatic idle transitions for %s\n", clkdm->name); -spin_lock_irqsave (&clkdm->lock, flags); clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; arch_clkdm->clkdm_deny_idle (clkdm); -pwrdm_state_switch (clkdm->pwrdm.ptr); -spin_unlock_irqrestore (&clkdm->lock, flags); +pwrdm_state_switch_nolock (clkdm->pwrdm.ptr); +} + +/** +* clkdm_deny_idle - disable hwsup idle transitions for clkdm +* @clkdm: struct clockdomain * +* +* 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. +*/ +void clkdm_deny_idle (struct clockdomain *clkdm) +{ +pwrdm_lock (clkdm->pwrdm.ptr); +clkdm_deny_idle_nolock (clkdm); +pwrdm_unlock (clkdm->pwrdm.ptr); }/**
arch/arm/mach-omap2/clockdomain.c +1
-6@@ -889,14 +951,11 @@ void clkdm_deny_idle(struct clockdomain *clkdm)bool clkdm_in_hwsup (struct clockdomain *clkdm) {bool ret; -unsigned long flags;if (!clkdm)return false; -spin_lock_irqsave (&clkdm->lock, flags); ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; -spin_unlock_irqrestore (&clkdm->lock, flags);return ret; }@@ -922,12 +981,10 @@ bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)static int _clkdm_clk_hwmod_enable (struct clockdomain *clkdm) { -unsigned long flags; -if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)return -EINVAL ; -spin_lock_irqsave (&clkdm->lock, flags); +pwrdm_lock (clkdm->pwrdm.ptr);/* * For arch's with no autodeps,
clkcm_clk_enablearch/arm/mach-omap2/clockdomain.c +8
-10@@ -935,13 +992,13 @@ static int _clkdm_clk_hwmod_enable(structclockdomain *clkdm) * enabled, so the clkdm can be force woken up. */ if ((atomic_inc_return (&clkdm->usecount) >1 ) && autodeps) { -spin_unlock_irqrestore (&clkdm->lock, flags); +pwrdm_unlock (clkdm->pwrdm.ptr);return 0 ; } arch_clkdm->clkdm_clk_enable (clkdm); -pwrdm_state_switch (clkdm->pwrdm.ptr); -spin_unlock_irqrestore (&clkdm->lock, flags); +pwrdm_state_switch_nolock (clkdm->pwrdm.ptr); +pwrdm_unlock (clkdm->pwrdm.ptr);pr_debug ("clockdomain: %s: enabled\n" , clkdm->name);@@ -950,27 +1007,25 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)static int _clkdm_clk_hwmod_disable (struct clockdomain *clkdm) { -unsigned long flags; -if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)return -EINVAL ; -spin_lock_irqsave (&clkdm->lock, flags); +pwrdm_lock (clkdm->pwrdm.ptr);if (atomic_read (&clkdm->usecount) ==0 ) { -spin_unlock_irqrestore (&clkdm->lock, flags); +pwrdm_unlock (clkdm->pwrdm.ptr);WARN_ON (1 );/* underflow */ return -ERANGE ; }if (atomic_dec_return (&clkdm->usecount) >0 ) { -spin_unlock_irqrestore (&clkdm->lock, flags); +pwrdm_unlock (clkdm->pwrdm.ptr);return 0 ; } arch_clkdm->clkdm_clk_disable (clkdm); -pwrdm_state_switch (clkdm->pwrdm.ptr); -spin_unlock_irqrestore (&clkdm->lock, flags); +pwrdm_state_switch_nolock (clkdm->pwrdm.ptr); +pwrdm_unlock (clkdm->pwrdm.ptr);pr_debug ("clockdomain: %s: disabled\n" , clkdm->name);arch/arm/mach-omap2/clockdomain.h +4
-2@@ -15,7 +15,6 @@#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H#include <linux/init.h> -#include <linux/spinlock.h> #include "powerdomain.h" #include "clock.h" @@ -139,7 +138,6 @@ struct clockdomain {struct clkdm_dep *sleepdep_srcs;atomic_t usecount;struct list_head node; -spinlock_t lock; };/** @@ -196,12 +194,16 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);int clkdm_read_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2);int clkdm_clear_all_sleepdeps (struct clockdomain *clkdm); +void clkdm_allow_idle_nolock (struct clockdomain *clkdm);void clkdm_allow_idle (struct clockdomain *clkdm); +void clkdm_deny_idle_nolock (struct clockdomain *clkdm);void clkdm_deny_idle (struct clockdomain *clkdm);bool clkdm_in_hwsup (struct clockdomain *clkdm);bool clkdm_missing_idle_reporting (struct clockdomain *clkdm); +int clkdm_wakeup_nolock (struct clockdomain *clkdm);int clkdm_wakeup (struct clockdomain *clkdm); +int clkdm_sleep_nolock (struct clockdomain *clkdm);int clkdm_sleep (struct clockdomain *clkdm);int
clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);arch/arm/mach-omap2/powerdomain-clockdomain.h new file +27
-0@@ -0,0 +1,27 @@ +/* +* OMAP powerdomain functions only for use by the OMAP clockdomain 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. +* +* The point of this file is to try to prevent other code outside of +* clockdomain.c from calling the functions listed herein. Yes, this +* means you. +*/ + +#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_CLOCKDOMAIN_H +#define __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_CLOCKDOMAIN_H + +#include <linux/types.h> + +#include "powerdomain.h" + +extern void pwrdm_lock (struct powerdomain *pwrdm); +extern void pwrdm_unlock (struct powerdomain *pwrdm); +extern int pwrdm_state_switch_nolock (struct powerdomain *pwrdm); + +#endif arch/arm/mach-omap2/powerdomain.c +40
-2@@ -19,6 +19,7 @@#include <linux/list.h> #include <linux/errno.h> #include <linux/string.h> +#include <linux/spinlock.h> #include <trace/events/power.h> #include "cm2xxx_3xxx.h" @@ -31,6 +32,7 @@#include "powerdomain.h" #include "clockdomain.h" +#include "clockdomain-powerdomain.h" #include "soc.h" #include "pm.h" @@ -101,6 +103,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm) pwrdm->voltdm.ptr = voltdm;INIT_LIST_HEAD (&pwrdm->voltdm_node);voltdm_add_pwrdm (voltdm, pwrdm); +spin_lock_init (&pwrdm->_lock);list_add (&pwrdm->node, &pwrdm_list);@@ -276,6 +279,30 @@ int pwrdm_complete_init(void) }/** +* pwrdm_lock - acquire a Linux spinlock on a powerdomain +* @pwrdm: struct powerdomain * to lock +* +* Acquire the powerdomain spinlock on @pwrdm. No return value. +*/ +void pwrdm_lock (struct powerdomain *pwrdm) + __acquires(&pwrdm->_lock) +{ +spin_lock_irqsave (&pwrdm->_lock, pwrdm->_lock_flags); +} + +/** +* pwrdm_unlock - release a Linux spinlock on a powerdomain +* @pwrdm: struct powerdomain * to unlock +* +* Release the powerdomain spinlock on @pwrdm. No return value. +*/ +void pwrdm_unlock (struct powerdomain *pwrdm) + __releases(&pwrdm->_lock) +{ +spin_unlock_irqrestore (&pwrdm->_lock, pwrdm->_lock_flags); +} + +/** * pwrdm_lookup - look up a powerdomain by name, return a pointer * @name: name of powerdomain * @@ -921,7 +948,7 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)return (pwrdm && pwrdm->flags &PWRDM_HAS_HDWR_SAR ) ?1 :0 ; } -int pwrdm_state_switch (struct powerdomain *pwrdm) +int pwrdm_state_switch_nolock (struct powerdomain *pwrdm) {int ret;@@ -935,6 +962,17 @@ int pwrdm_state_switch(struct powerdomain *pwrdm)return ret; } +int __deprecated pwrdm_state_switch (struct powerdomain *pwrdm) +{ +int ret; + +pwrdm_lock (pwrdm); + ret =pwrdm_state_switch_nolock (pwrdm); +pwrdm_unlock (pwrdm); + +return ret; +} +int pwrdm_pre_transition (struct powerdomain *pwrdm) {if (pwrdm)@@ -973,7 +1011,7 @@ static u8 _pwrdm_save_clkdm_state_and_activate(structpowerdomain *pwrdm, sleep_switch =LOWPOWERSTATE_SWITCH ; }else { *hwsup =clkdm_in_hwsup (pwrdm->pwrdm_clkdms[0 ]); -clkdm_wakeup (pwrdm->pwrdm_clkdms[0 ]); +clkdm_wakeup_nolock (pwrdm->pwrdm_clkdms[0 ]); sleep_switch =FORCEWAKEUP_SWITCH ; }} else {arch/arm/mach-omap2/powerdomain.c +3
-3@@ -989,15 +1027,15 @@ static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, switch (sleep_switch) {case FORCEWAKEUP_SWITCH :if (hwsup) -clkdm_allow_idle (pwrdm->pwrdm_clkdms[0 ]); +clkdm_allow_idle_nolock (pwrdm->pwrdm_clkdms[0 ]);else -clkdm_sleep (pwrdm->pwrdm_clkdms[0 ]); +clkdm_sleep_nolock (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); +pwrdm_state_switch_nolock (pwrdm);break ; }}
arch/arm/mach-omap2/powerdomain.c +5
-1@@ -1021,9 +1059,13 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) pwrst--; } +pwrdm_lock (pwrdm); + next_pwrst =pwrdm_read_next_pwrst (pwrdm); -if (next_pwrst == pwrst) +if (next_pwrst == pwrst) { +pwrdm_unlock (pwrdm);return ret; + } sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, pwrst,&hwsup);arch/arm/mach-omap2/powerdomain.c +2
-0@@ -1035,6 +1077,8 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)_pwrdm_restore_clkdm_state (pwrdm ,sleep_switch ,hwsup ); +pwrdm_unlock (pwrdm); +return ret; }arch/arm/mach-omap2/powerdomain.h +6
-3@@ -19,8 +19,7 @@#include <linux/types.h> #include <linux/list.h> - -#include <linux/atomic.h> +#include <linux/spinlock.h> #include "voltage.h" @@ -103,6 +102,8 @@ struct powerdomain;* @state_counter: * @timer: * @state_timer: +* @_lock: spinlock used to serialize powerdomain and some clockdomain ops +* @_lock_flags: stored flags when @_lock is taken * * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h. */ @@ -127,7 +128,8 @@ struct powerdomain {unsigned state_counter[PWRDM_MAX_PWRSTS ];unsigned ret_logic_off_counter;unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS ]; - +spinlock_t _lock; +unsigned long _lock_flags;const u8 pwrstctrl_offs;const u8 pwrstst_offs;const u32 logicretstate_mask;@@ -225,6 +227,7 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);int pwrdm_disable_hdwr_sar (struct powerdomain *pwrdm);bool pwrdm_has_hdwr_sar (struct powerdomain *pwrdm); +int pwrdm_state_switch_nolock (struct powerdomain *pwrdm);int pwrdm_state_switch (struct powerdomain *pwrdm);int pwrdm_pre_transition (struct powerdomain *pwrdm);int pwrdm_post_transition (struct powerdomain *pwrdm);
arch/arm/mach-omap2/powerdomain.h extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank); · line 261
Quoted 7 lines
arch/arm/mach-omap2/powerdomain.h +2
-0@@ -252,5 +255,7 @@ extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);extern struct powerdomain wkup_omap2_pwrdm;extern struct powerdomain gfx_omap2_pwrdm; +extern void pwrdm_lock (struct powerdomain *pwrdm); +extern void pwrdm_unlock (struct powerdomain *pwrdm);#endif
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121212/174fb6f6/attachment-0001.html>
Paul Walmsley
maintainerPATCH 6/10 ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock
Hi
Quoted 9 lines · Jean Pihet
Quoted 5 lines · Paul Walmsley
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?
Quoted 2 lines
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.
Quoted 1 line
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
PATCH 6/10 ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock
In reply to Paul WalmsleyPaul,
-resending in plain text only, sorry about that-
Quoted 5 lines · Paul Walmsley
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
Paul Walmsley
maintainerPATCH 7/10 ARM: OMAP2xxx: CM: remove autodep handling
In reply to Paul WalmsleyThere'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.
--- arch/arm/mach-omap2/cm2xxx.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-)
arch/arm/mach-omap2/cm2xxx.c +4 -29
@@ -273,9 +273,6 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)static void omap2xxx_clkdm_allow_idle (struct clockdomain *clkdm) { -if (atomic_read (&clkdm->usecount) >0 ) -_clkdm_add_autodeps (clkdm); -omap2xxx_cm_clkdm_enable_hwsup (clkdm->pwrdm.ptr->prcm_offs, clkdm->clktrctrl_mask); }
@@ -284,9 +281,6 @@ static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm) {omap2xxx_cm_clkdm_disable_hwsup (clkdm->pwrdm.ptr->prcm_offs, clkdm->clktrctrl_mask); - -if (atomic_read (&clkdm->usecount) >0 ) -_clkdm_del_autodeps (clkdm); }static int omap2xxx_clkdm_clk_enable (struct clockdomain *clkdm)
@@ -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);return 0 ; }
@@ -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);return 0 ; }
Paul Walmsley
maintainerPATCH 8/10 ARM: OMAP2+: clockdomain: work on wkdep/sleepdep functions
In reply to Paul WalmsleySplit 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.
--- 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(-)
arch/arm/mach-omap2/clockdomain.c +233 -161
@@ -120,7 +120,7 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,return cd; } -/* +/** * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store * @autodep: struct clkdm_autodep * to resolve *
@@ -152,88 +152,202 @@ static void _autodep_lookup(struct clkdm_autodep *autodep) autodep->clkdm.ptr = clkdm; } -/* -* _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable -* @clkdm: struct clockdomain * +/** +* _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms +* @clkdm: clockdomain that we are resolving dependencies for +* @clkdm_deps: ptr to array of struct clkdm_deps to resolve * -* Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' -* in hardware-supervised mode. Meant to be called from clock framework -* when a clock inside clockdomain 'clkdm' is enabled. No return value. +* Iterates through @clkdm_deps, looking up the struct clockdomain named by +* clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. +* No return value. +*/ +static void _resolve_clkdm_deps (struct clockdomain *clkdm, +struct clkdm_dep *clkdm_deps) +{ +struct clkdm_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 - add a wakeup dependency from clkdm2 to clkdm1 (lockless) +* @clkdm1: wake this struct clockdomain * up (dependent) +* @clkdm2: when this struct clockdomain * wakes up (source) * -* XXX autodeps are deprecated and should be removed at the earliest -* opportunity +* When the clockdomain represented by @clkdm2 wakes up, wake up +* @clkdm1. Implemented in hardware on the OMAP, this feature is +* designed to reduce wakeup latency of the dependent clockdomain @clkdm1. +* Returns -EINVAL if presented with invalid clockdomain pointers, +* -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon +* success. */ -void _clkdm_add_autodeps (struct clockdomain *clkdm) +static int _clkdm_add_wkdep (struct clockdomain *clkdm1, +struct clockdomain *clkdm2) { -struct clkdm_autodep *autodep; +struct clkdm_dep *cd; +int ret =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); +return ret; + } + +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); } + +return ret; } -/* -* _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm -* @clkdm: struct clockdomain * +/** +* _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless) +* @clkdm1: wake this struct clockdomain * up (dependent) +* @clkdm2: when this struct clockdomain * wakes up (source) * -* Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' -* in hardware-supervised mode. Meant to be called from clock framework -* when a clock inside clockdomain 'clkdm' is disabled. No return value. +* Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2 +* wakes up. Returns -EINVAL if presented with invalid clockdomain +* pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or +* 0 upon success. +*/ +static int _clkdm_del_wkdep (struct clockdomain *clkdm1, +struct clockdomain *clkdm2) +{ +struct clkdm_dep *cd; +int ret =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); +return ret; + } + +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); + } + +return ret; +} + +/** +* _clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless) +* @clkdm1: prevent this struct clockdomain * from sleeping (dependent) +* @clkdm2: when this struct clockdomain * is active (source) * -* XXX autodeps are deprecated and should be removed at the earliest -* opportunity +* Prevent @clkdm1 from automatically going inactive (and then to +* retention or off) if @clkdm2 is active. Returns -EINVAL if +* presented with invalid clockdomain pointers or called on a machine +* that does not support software-configurable hardware sleep +* dependencies, -ENOENT if the specified dependency cannot be set in +* hardware, or 0 upon success. */ -void _clkdm_del_autodeps (struct clockdomain *clkdm) +static int _clkdm_add_sleepdep (struct clockdomain *clkdm1, +struct clockdomain *clkdm2) { -struct clkdm_autodep *autodep; +struct clkdm_dep *cd; +int ret =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); +return ret; } + +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); + } + +return ret; }/** -* _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms -* @clkdm: clockdomain that we are resolving dependencies for -* @clkdm_deps: ptr to array of struct clkdm_deps to resolve +* _clkdm_del_sleepdep - remove a sleep dep from clkdm2 to clkdm1 (lockless) +* @clkdm1: prevent this struct clockdomain * from sleeping (dependent) +* @clkdm2: when this struct clockdomain * is active (source) * -* Iterates through @clkdm_deps, looking up the struct clockdomain named by -* clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. -* No return value. +* Allow @clkdm1 to automatically go inactive (and then to retention or +* off), independent of the activity state of @clkdm2. Returns -EINVAL +* if presented with invalid clockdomain pointers or called on a machine +* that does not support software-configurable hardware sleep dependencies, +* -ENOENT if the specified dependency cannot be cleared in hardware, or +* 0 upon success. */ -static void _resolve_clkdm_deps (struct clockdomain *clkdm, -struct clkdm_dep *clkdm_deps) +static int _clkdm_del_sleepdep (struct clockdomain *clkdm1, +struct clockdomain *clkdm2) {struct clkdm_dep *cd; +int ret =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); +return ret; } + +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); + } + +return ret; }/* Public functions */
@@ -453,33 +567,7 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)*/ int clkdm_add_wkdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -struct clkdm_dep *cd; -int ret =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); -return ret; - } - -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); - } - -return ret; +return _clkdm_add_wkdep (clkdm1, clkdm2); }/**
@@ -494,33 +582,7 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/ int clkdm_del_wkdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -struct clkdm_dep *cd; -int ret =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); -return ret; - } - -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); - } - -return ret; +return _clkdm_del_wkdep (clkdm1, clkdm2); }/**
@@ -597,33 +659,7 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)*/ int clkdm_add_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -struct clkdm_dep *cd; -int ret =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); -return ret; - } - -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); - } - -return ret; +return _clkdm_add_sleepdep (clkdm1, clkdm2); }/**
@@ -640,33 +676,7 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/ int clkdm_del_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -struct clkdm_dep *cd; -int ret =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); -return ret; - } - -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); - } - -return ret; +return _clkdm_del_sleepdep (clkdm1, clkdm2); }/**
@@ -977,6 +987,68 @@ bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)return (clkdm->flags &CLKDM_MISSING_IDLE_REPORTING ) ? true : false; } +/* Public autodep handling functions (deprecated) */ + +/** +* clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable +* @clkdm: struct clockdomain * +* +* Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' +* in hardware-supervised mode. Meant to be called from clock framework +* when a clock inside clockdomain 'clkdm' is enabled. No return value. +* +* XXX autodeps are deprecated and should be removed at the earliest +* opportunity +*/ +void clkdm_add_autodeps (struct clockdomain *clkdm) +{ +struct clkdm_autodep *autodep; + +if (!autodeps || clkdm->flags &CLKDM_NO_AUTODEPS ) +return ; + +for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { +if (IS_ERR (autodep->clkdm.ptr)) +continue ; + +pr_debug ("clockdomain: %s: adding %s sleepdep/wkdep\n" , + clkdm->name, autodep->clkdm.ptr->name); + +_clkdm_add_sleepdep (clkdm, autodep->clkdm.ptr); +_clkdm_add_wkdep (clkdm, autodep->clkdm.ptr); + } +} + +/** +* clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm +* @clkdm: struct clockdomain * +* +* Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' +* in hardware-supervised mode. Meant to be called from clock framework +* when a clock inside clockdomain 'clkdm' is disabled. No return value. +* +* XXX autodeps are deprecated and should be removed at the earliest +* opportunity +*/ +void clkdm_del_autodeps (struct clockdomain *clkdm) +{ +struct clkdm_autodep *autodep; + +if (!autodeps || clkdm->flags &CLKDM_NO_AUTODEPS ) +return ; + +for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { +if (IS_ERR (autodep->clkdm.ptr)) +continue ; + +pr_debug ("clockdomain: %s: removing %s sleepdep/wkdep\n" , + clkdm->name, autodep->clkdm.ptr->name); + +_clkdm_del_sleepdep (clkdm, autodep->clkdm.ptr); +_clkdm_del_wkdep (clkdm, autodep->clkdm.ptr); + } +} +/* Clockdomain-to-clock/hwmod framework interface code */ static int _clkdm_clk_hwmod_enable (struct clockdomain *clkdm)
arch/arm/mach-omap2/clockdomain.h +3 -2
@@ -216,8 +216,9 @@ extern void __init omap243x_clockdomains_init(void);extern void __init omap3xxx_clockdomains_init (void );extern void __init am33xx_clockdomains_init (void );extern void __init omap44xx_clockdomains_init (void ); -extern void _clkdm_add_autodeps (struct clockdomain *clkdm); -extern void _clkdm_del_autodeps (struct clockdomain *clkdm); + +extern void clkdm_add_autodeps (struct clockdomain *clkdm); +extern void clkdm_del_autodeps (struct clockdomain *clkdm);extern struct clkdm_ops omap2_clkdm_operations;extern struct clkdm_ops omap3_clkdm_operations;
arch/arm/mach-omap2/cm3xxx.c +4 -4
@@ -210,7 +210,7 @@ static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)static void omap3xxx_clkdm_allow_idle (struct clockdomain *clkdm) {if (atomic_read (&clkdm->usecount) >0 ) -_clkdm_add_autodeps (clkdm); +clkdm_add_autodeps (clkdm);omap3xxx_cm_clkdm_enable_hwsup (clkdm->pwrdm.ptr->prcm_offs, clkdm->clktrctrl_mask);
@@ -222,7 +222,7 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm) clkdm->clktrctrl_mask);if (atomic_read (&clkdm->usecount) >0 ) -_clkdm_del_autodeps (clkdm); +clkdm_del_autodeps (clkdm); }static int omap3xxx_clkdm_clk_enable (struct clockdomain *clkdm)
@@ -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 {
Paul Walmsley
maintainerPATCH 9/10 ARM: OMAP2+: clockdomain: convert existing atomic usecounts into spinlock-protected shorts/ints
In reply to Paul WalmsleyThe 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.
--- 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(-)
arch/arm/mach-omap2/clockdomain.c +75 -13
@@ -210,7 +210,8 @@ static int _clkdm_add_wkdep(struct clockdomain *clkdm1,return ret; } -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,return ret; } -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,return ret; } -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,return ret; } -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);
@@ -567,7 +571,21 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)*/ int clkdm_add_wkdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_add_wkdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_add_wkdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/**
@@ -582,7 +600,21 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/ int clkdm_del_wkdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_del_wkdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_del_wkdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/**
@@ -620,7 +652,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)return ret; } -/* XXX It's faster to return the atomic wkdep_usecount */ +/* XXX It's faster to return the wkdep_usecount */ return arch_clkdm->clkdm_read_wkdep (clkdm1, clkdm2); }
@@ -659,7 +691,21 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)*/ int clkdm_add_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_add_sleepdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_add_sleepdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/**
@@ -676,7 +722,21 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/ int clkdm_del_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_del_sleepdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_del_sleepdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/**
@@ -716,7 +776,7 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)return ret; } -/* XXX It's faster to return the atomic sleepdep_usecount */ +/* XXX It's faster to return the sleepdep_usecount */ return arch_clkdm->clkdm_read_sleepdep (clkdm1, clkdm2); }
@@ -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 ; }
@@ -1084,13 +1145,14 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)pwrdm_lock (clkdm->pwrdm.ptr); -if (atomic_read (&clkdm->usecount) ==0 ) { +if (clkdm->usecount ==0 ) {pwrdm_unlock (clkdm->pwrdm.ptr);WARN_ON (1 );/* underflow */ return -ERANGE ; } -if (atomic_dec_return (&clkdm->usecount) >0 ) { + clkdm->usecount--; +if (clkdm->usecount >0 ) {pwrdm_unlock (clkdm->pwrdm.ptr);return 0 ; }
arch/arm/mach-omap2/clockdomain.h +3 -3
@@ -91,8 +91,8 @@ struct clkdm_autodep {struct clkdm_dep {const char *clkdm_name;struct clockdomain *clkdm; -atomic_t wkdep_usecount; -atomic_t sleepdep_usecount; +s16 wkdep_usecount; +s16 sleepdep_usecount; };/* Possible flags for struct clockdomain._flags */
@@ -136,7 +136,7 @@ struct clockdomain {const u16 clkdm_offs;struct clkdm_dep *wkdep_srcs;struct clkdm_dep *sleepdep_srcs; -atomic_t usecount; +int usecount;struct list_head node; };
arch/arm/mach-omap2/cm3xxx.c +3 -3
@@ -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)static void omap3xxx_clkdm_allow_idle (struct clockdomain *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,
@@ -221,7 +221,7 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)omap3xxx_cm_clkdm_disable_hwsup (clkdm->pwrdm.ptr->prcm_offs, clkdm->clktrctrl_mask); -if (atomic_read (&clkdm->usecount) >0 ) +if (clkdm->usecount >0 )clkdm_del_autodeps (clkdm); }
arch/arm/mach-omap2/cminst44xx.c +1 -1
@@ -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,
arch/arm/mach-omap2/pm-debug.c +2 -4
@@ -84,10 +84,8 @@ static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) strncmp(clkdm->name, "dpll", 4) == 0)return 0 ; -seq_printf (s,"%s->%s (%d)" , clkdm->name, - clkdm->pwrdm.ptr->name, -atomic_read (&clkdm->usecount)); -seq_printf (s,"\n" ); +seq_printf (s,"%s->%s (%d)\n" , clkdm->name, clkdm->pwrdm.ptr->name, + clkdm->usecount);return 0 ; }
arch/arm/mach-omap2/pm.c +2 -1
@@ -78,11 +78,12 @@ static void __init omap2_init_processor_devices(void)int __init omap_pm_clkdms_setup (struct clockdomain *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);else if (clkdm->flags &CLKDM_CAN_FORCE_SLEEP && -atomic_read (&clkdm->usecount) ==0 ) + clkdm->usecount ==0 )clkdm_sleep (clkdm);return 0 ; }
arch/arm/mach-omap2/prm2xxx_3xxx.c +2 -1
@@ -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 */ int omap2_clkdm_clear_all_wkdeps (struct clockdomain *clkdm) {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,
PATCH 9/10 ARM: OMAP2+: clockdomain: convert existing atomic usecounts into spinlock-protected shorts/ints
Quoted 306 lines · Paul Walmsley
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 <[email protected]>Cc Kevin Hilman <[email protected]>--- 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(-)arch/arm/mach-omap2/clockdomain.c +75
-13@@ -210,7 +210,8 @@ static int _clkdm_add_wkdep(struct clockdomain *clkdm1,return ret; } -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,return ret; } -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,return ret; } -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,return ret; } -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);@@ -567,7 +571,21 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)*/ int clkdm_add_wkdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_add_wkdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_add_wkdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/** @@ -582,7 +600,21 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/ int clkdm_del_wkdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_del_wkdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_del_wkdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/** @@ -620,7 +652,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)return ret; } -/* XXX It's faster to return the atomic wkdep_usecount */ +/* XXX It's faster to return the wkdep_usecount */ return arch_clkdm->clkdm_read_wkdep (clkdm1, clkdm2); }@@ -659,7 +691,21 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)*/ int clkdm_add_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_add_sleepdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_add_sleepdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/** @@ -676,7 +722,21 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)*/ int clkdm_del_sleepdep (struct clockdomain *clkdm1,struct clockdomain *clkdm2) { -return _clkdm_del_sleepdep (clkdm1, clkdm2); +struct clkdm_dep *cd; +int ret; + +if (!clkdm1 || !clkdm2) +return -EINVAL ; + + cd =_clkdm_deps_lookup (clkdm2, clkdm1->wkdep_srcs); +if (IS_ERR (cd)) +return PTR_ERR (cd); + +pwrdm_lock (cd->clkdm->pwrdm.ptr); + ret =_clkdm_del_sleepdep (clkdm1, clkdm2); +pwrdm_unlock (cd->clkdm->pwrdm.ptr); + +return ret; }/** @@ -716,7 +776,7 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)return ret; } -/* XXX It's faster to return the atomic sleepdep_usecount */ +/* XXX It's faster to return the sleepdep_usecount */ return arch_clkdm->clkdm_read_sleepdep (clkdm1, clkdm2); }@@ -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 ; }@@ -1084,13 +1145,14 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)pwrdm_lock (clkdm->pwrdm.ptr); -if (atomic_read (&clkdm->usecount) ==0 ) { +if (clkdm->usecount ==0 ) {pwrdm_unlock (clkdm->pwrdm.ptr);WARN_ON (1 );/* underflow */ return -ERANGE ; } -if (atomic_dec_return (&clkdm->usecount) >0 ) { + clkdm->usecount--; +if (clkdm->usecount >0 ) {pwrdm_unlock (clkdm->pwrdm.ptr);return 0 ; }arch/arm/mach-omap2/clockdomain.h +3
-3@@ -91,8 +91,8 @@ struct clkdm_autodep {struct clkdm_dep {const char *clkdm_name;struct clockdomain *clkdm; -atomic_t wkdep_usecount; -atomic_t sleepdep_usecount; +s16 wkdep_usecount; +s16 sleepdep_usecount; };/* Possible flags for struct clockdomain._flags */ @@ -136,7 +136,7 @@ struct clockdomain {const u16 clkdm_offs;struct clkdm_dep *wkdep_srcs;struct clkdm_dep *sleepdep_srcs; -atomic_t usecount; +int usecount;struct list_head node; };arch/arm/mach-omap2/cm3xxx.c +3
-3@@ -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)static void omap3xxx_clkdm_allow_idle (struct clockdomain *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,@@ -221,7 +221,7 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)omap3xxx_cm_clkdm_disable_hwsup (clkdm->pwrdm.ptr->prcm_offs, clkdm->clktrctrl_mask); -if (atomic_read (&clkdm->usecount) >0 ) +if (clkdm->usecount >0 )clkdm_del_autodeps (clkdm); }arch/arm/mach-omap2/cminst44xx.c +1
-1@@ -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,arch/arm/mach-omap2/pm-debug.c +2
-4@@ -84,10 +84,8 @@ static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) strncmp(clkdm->name, "dpll", 4) == 0)return 0 ; -seq_printf (s,"%s->%s (%d)" , clkdm->name, - clkdm->pwrdm.ptr->name, -atomic_read (&clkdm->usecount)); -seq_printf (s,"\n" ); +seq_printf (s,"%s->%s (%d)\n" , clkdm->name, clkdm->pwrdm.ptr->name, + clkdm->usecount);return 0 ; }arch/arm/mach-omap2/pm.c +2
-1@@ -78,11 +78,12 @@ static void __init omap2_init_processor_devices(void)int __init omap_pm_clkdms_setup (struct clockdomain *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);else if (clkdm->flags &CLKDM_CAN_FORCE_SLEEP && -atomic_read (&clkdm->usecount) ==0 ) + clkdm->usecount ==0 )clkdm_sleep (clkdm);return 0 ; }arch/arm/mach-omap2/prm2xxx_3xxx.c +0
-0
arch/arm/mach-omap2/prm2xxx_3xxx.c int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, · line 213
Quoted 4 lines
arch/arm/mach-omap2/prm2xxx_3xxx.c +1
-0@@ -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,
arch/arm/mach-omap2/prm2xxx_3xxx.c int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, · line 214
Quoted 1 line
arch/arm/mach-omap2/prm2xxx_3xxx.c +0
-0int 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 19 lines
arch/arm/mach-omap2/prm2xxx_3xxx.c +1
-1{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,_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 9/10 ARM: OMAP2+: clockdomain: convert existing atomic usecounts into spinlock-protected shorts/ints
In reply to Paul WalmsleyHi Paul,
Quoted 4 lines · Paul Walmsley
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.
[...]
arch/arm/mach-omap2/clockdomain.c static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) · line 1130
Quoted 11 lines
arch/arm/mach-omap2/clockdomain.c +2
-1@@ -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
Paul Walmsley
maintainerPATCH 10/10 ARM: OMAP2+: powerdomain: fix whitespace, improve flag comments
In reply to Paul WalmsleyFix some whitespace problems introduced by commit da03ce65b5431245b9cd20db3edaaa6b9f5c8dc1 ("OMAP3: powerdomain data:
add voltage domains"). Also, improve the documentation for the struct powerdomain.flags field.
--- arch/arm/mach-omap2/powerdomain.h | 26 +++++++------ 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 +++++++++++----------- 4 files changed, 42 insertions(+), 40 deletions(-)
arch/arm/mach-omap2/powerdomain.h +14 -12
@@ -43,18 +43,20 @@#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) -/* Powerdomain flags */ -#define PWRDM_HAS_HDWR_SAR (1 << 0)/* hardware save-and-restore support */ -#define PWRDM_HAS_MPU_QUIRK (1 << 1)/* MPU pwr domain has MEM bank 0 bits -* in MEM bank 1 position. This is -* true for OMAP3430 -*/ -#define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2)/* -* support to transition from a -* sleep state to a lower sleep -* state without waking up the -* powerdomain -*/ +/* +* Powerdomain flags (struct powerdomain.flags) +* +* PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support +* +* PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM +* bank 1 position. This is true for OMAP3430 +* +* PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state +* to a lower sleep state without waking up the powerdomain +*/ +#define PWRDM_HAS_HDWR_SAR BIT(0) +#define PWRDM_HAS_MPU_QUIRK BIT(1) +#define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2)/* * Number of memory banks that are power-controllable. On OMAP4430, the
arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c +2 -2
@@ -54,12 +54,12 @@ struct powerdomain gfx_omap2_pwrdm = { .pwrsts_mem_on = { [0 ] =PWRSTS_ON ,/* MEMONSTATE */ }, - .voltdm = { .name = "core" }, + .voltdm = { .name = "core" }, };struct powerdomain wkup_omap2_pwrdm = { .name ="wkup_pwrdm" , .prcm_offs =WKUP_MOD , .pwrsts =PWRSTS_ON , - .voltdm = { .name ="wakeup" }, + .voltdm = { .name ="wakeup" }, };
arch/arm/mach-omap2/powerdomains2xxx_data.c +4 -4
@@ -38,7 +38,7 @@ static struct powerdomain dsp_pwrdm = { .pwrsts_mem_on = { [0] = PWRSTS_ON, }, - .voltdm = { .name = "core" }, + .voltdm = { .name = "core" }, };static struct powerdomain mpu_24xx_pwrdm = {
@@ -53,7 +53,7 @@ static struct powerdomain mpu_24xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRSTS_ON, }, - .voltdm = { .name = "core" }, + .voltdm = { .name = "core" }, };static struct powerdomain core_24xx_pwrdm = {
@@ -72,7 +72,7 @@ static struct powerdomain core_24xx_pwrdm = { [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ }, - .voltdm = { .name = "core" }, + .voltdm = { .name = "core" }, };
@@ -94,7 +94,7 @@ static struct powerdomain mdm_pwrdm = { .pwrsts_mem_on = { [0 ] =PWRSTS_ON ,/* MEMONSTATE */ }, - .voltdm = { .name = "core" }, + .voltdm = { .name = "core" }, };/*
arch/arm/mach-omap2/powerdomains3xxx_data.c +22 -22
170 lines not on this page · raw message
cover ARM: OMAP2+: second set of PM fixes and cleanup for 3.9
In reply to Paul WalmsleyHi 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
Quoted 83 lines · Paul Walmsley
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_oldconfigBoot-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_defconfigPaul Walmsley (10):
ARM: OMAP3/4: cpuidle: fix sparse and checkpatch warnings
ARM: OMAP2+: clockdomain: addpwrdm_state_switch()call toclkdm_sleep()
ARM: OMAP2xxx: PM: clean up some crufty powerstate programming code
ARM: OMAP2: PM/powerdomain: drop unnecessarypwrdm_wait_transition()
ARM: OMAP2+: PM/powerdomain: moveomap_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 commentsarch/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