Skip to content

Commit c20c8f7

Browse files
sumanannaPaul Walmsley
authored andcommitted
ARM: OMAP2+: hwmod: fix _idle() hwmod state sanity check sequence
The omap_hwmod _enable() function can return success without setting the hwmod state to _HWMOD_STATE_ENABLED for IPs with reset lines when all of the reset lines are asserted. The omap_hwmod _idle() function also performs a similar check, but after checking for the hwmod state first. This triggers the WARN when pm_runtime_get and pm_runtime_put are invoked on IPs with all reset lines asserted. Reverse the checks for hwmod state and reset lines status to fix this. Issue found during a unbind operation on a device with reset lines still asserted, example backtrace below ------------[ cut here ]------------ WARNING: CPU: 1 PID: 879 at arch/arm/mach-omap2/omap_hwmod.c:2207 _idle+0x1e4/0x240() omap_hwmod: mmu_dsp: idle state can only be entered from enabled state Modules linked in: CPU: 1 PID: 879 Comm: sh Not tainted 4.4.0-00008-ga989d951331a #3 Hardware name: Generic OMAP5 (Flattened Device Tree) [<c0018e60>] (unwind_backtrace) from [<c0014dc4>] (show_stack+0x10/0x14) [<c0014dc4>] (show_stack) from [<c037ac28>] (dump_stack+0x90/0xc0) [<c037ac28>] (dump_stack) from [<c003f420>] (warn_slowpath_common+0x78/0xb4) [<c003f420>] (warn_slowpath_common) from [<c003f48c>] (warn_slowpath_fmt+0x30/0x40) [<c003f48c>] (warn_slowpath_fmt) from [<c0028c20>] (_idle+0x1e4/0x240) [<c0028c20>] (_idle) from [<c0029080>] (omap_hwmod_idle+0x28/0x48) [<c0029080>] (omap_hwmod_idle) from [<c002a5a4>] (omap_device_idle+0x3c/0x90) [<c002a5a4>] (omap_device_idle) from [<c0427a90>] (__rpm_callback+0x2c/0x60) [<c0427a90>] (__rpm_callback) from [<c0427ae4>] (rpm_callback+0x20/0x80) [<c0427ae4>] (rpm_callback) from [<c0427f84>] (rpm_suspend+0x138/0x74c) [<c0427f84>] (rpm_suspend) from [<c0428b78>] (__pm_runtime_idle+0x78/0xa8) [<c0428b78>] (__pm_runtime_idle) from [<c041f514>] (__device_release_driver+0x64/0x100) [<c041f514>] (__device_release_driver) from [<c041f5d0>] (device_release_driver+0x20/0x2c) [<c041f5d0>] (device_release_driver) from [<c041d85c>] (unbind_store+0x78/0xf8) [<c041d85c>] (unbind_store) from [<c0206df8>] (kernfs_fop_write+0xc0/0x1c4) [<c0206df8>] (kernfs_fop_write) from [<c018a120>] (__vfs_write+0x20/0xdc) [<c018a120>] (__vfs_write) from [<c018a9cc>] (vfs_write+0x90/0x164) [<c018a9cc>] (vfs_write) from [<c018b1f0>] (SyS_write+0x44/0x9c) [<c018b1f0>] (SyS_write) from [<c0010420>] (ret_fast_syscall+0x0/0x1c) ---[ end trace a4182013c75a9f50 ]--- While at this, fix the sequence in _shutdown() as well, though there is no easy reproducible scenario. Fixes: 747834a ("ARM: OMAP2+: hwmod: revise hardreset behavior") Signed-off-by: Suman Anna <[email protected]> Signed-off-by: Paul Walmsley <[email protected]>
1 parent 22d20cb commit c20c8f7

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

arch/arm/mach-omap2/omap_hwmod.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,15 +2207,15 @@ static int _idle(struct omap_hwmod *oh)
22072207

22082208
pr_debug("omap_hwmod: %s: idling\n", oh->name);
22092209

2210+
if (_are_all_hardreset_lines_asserted(oh))
2211+
return 0;
2212+
22102213
if (oh->_state != _HWMOD_STATE_ENABLED) {
22112214
WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
22122215
oh->name);
22132216
return -EINVAL;
22142217
}
22152218

2216-
if (_are_all_hardreset_lines_asserted(oh))
2217-
return 0;
2218-
22192219
if (oh->class->sysc)
22202220
_idle_sysc(oh);
22212221
_del_initiator_dep(oh, mpu_oh);
@@ -2262,16 +2262,16 @@ static int _shutdown(struct omap_hwmod *oh)
22622262
int ret, i;
22632263
u8 prev_state;
22642264

2265+
if (_are_all_hardreset_lines_asserted(oh))
2266+
return 0;
2267+
22652268
if (oh->_state != _HWMOD_STATE_IDLE &&
22662269
oh->_state != _HWMOD_STATE_ENABLED) {
22672270
WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
22682271
oh->name);
22692272
return -EINVAL;
22702273
}
22712274

2272-
if (_are_all_hardreset_lines_asserted(oh))
2273-
return 0;
2274-
22752275
pr_debug("omap_hwmod: %s: disabling\n", oh->name);
22762276

22772277
if (oh->class->pre_shutdown) {

0 commit comments

Comments
 (0)