mirror of
https://github.com/torvalds/linux.git
synced 2024-11-08 05:01:48 +00:00
4c4cbce68f
While suspending, we're enabling a clock in ->suspend() but we're in atomic context, leading to this : [30803.667305] PM: late suspend of devices complete after 1.237 msecs [30803.667449] BUG: sleeping function called from invalid context at kernel/mutex.c:271 [30803.667464] in_atomic(): 0, irqs_disabled(): 128, pid: 4941, name: pm-suspend [30803.667474] INFO: lockdep is turned off. [30803.667483] irq event stamp: 0 [30803.667489] hardirqs last enabled at (0): [< (null)>] (null) [30803.667503] hardirqs last disabled at (0): [<c001e4a8>] copy_process.part.48+0x1e0/0xa7c [30803.667543] softirqs last enabled at (0): [<c001e4a8>] copy_process.part.48+0x1e0/0xa7c [30803.667562] softirqs last disabled at (0): [< (null)>] (null) [30803.667574] Backtrace: [30803.667611] [<c0010e00>] (dump_backtrace+0x0/0x110) from [<c0424c00>] (dump_stack+0x18/0x1c) [30803.667624] r6:00000000 r5:00000000 r4:d9648000 r3:d9648000 [30803.667652] [<c0424be8>] (dump_stack+0x0/0x1c) from [<c0424eec>] (__might_sleep.part.101+0x90/0xa8) [30803.667673] [<c0424e5c>] (__might_sleep.part.101+0x0/0xa8) from [<c001a5c4>] (__might_sleep+0x80/0x94) [30803.667686] r4:c05d58c0 [30803.667705] [<c001a544>] (__might_sleep+0x0/0x94) from [<c043230c>] (mutex_lock_nested+0x2c/0x30c) [30803.667735] [<c04322e0>] (mutex_lock_nested+0x0/0x30c) from [<c0017834>] (clk_enable+0x28/0x50) [30803.667747] r8:c0438464 r7:00000003 r6:00000000 r5:00000000 r4:c05d2e98 [30803.667780] [<c001780c>] (clk_enable+0x0/0x50) from [<c0017260>] (mx5_suspend_enter+0x1c/0x98) [30803.667792] r4:00000003 r3:c060dfe0 [30803.667821] [<c0017244>] (mx5_suspend_enter+0x0/0x98) from [<c0059b48>] (suspend_enter+0xec/0x15c) [30803.667833] r4:00000003 r3:c0017244 [30803.667856] [<c0059a5c>] (suspend_enter+0x0/0x15c) from [<c0059c4c>] (suspend_devices_and_enter+0x94/0x130) [30803.667868] r6:00000000 r5:00000003 r4:c0c0af00 r3:00002710 [30803.667897] [<c0059bb8>] (suspend_devices_and_enter+0x0/0x130) from [<c0059db0>] (enter_state+0xc8/0x130) [30803.667909] r6:00000000 r5:00000003 r4:c05286e4 [30803.667934] [<c0059ce8>] (enter_state+0x0/0x130) from [<c00592d4>] (state_store+0xac/0xc0) [30803.667945] r6:00000003 r5:00000003 r4:df39d000 r3:00000003 [30803.667978] [<c0059228>] (state_store+0x0/0xc0) from [<c01b0100>] (kobj_attr_store+0x1c/0x28) [30803.668009] [<c01b00e4>] (kobj_attr_store+0x0/0x28) from [<c00e435c>] (sysfs_write_file+0x88/0xbc) [30803.668032] [<c00e42d4>] (sysfs_write_file+0x0/0xbc) from [<c0091fa0>] (vfs_write+0xbc/0x138) [30803.668051] [<c0091ee4>] (vfs_write+0x0/0x138) from [<c0092204>] (sys_write+0x44/0x70) [30803.668062] r8:00000000 r7:00000004 r6:00000003 r5:002694d0 r4:d966acc0 [30803.668094] [<c00921c0>] (sys_write+0x0/0x70) from [<c000db00>] (ret_fast_syscall+0x0/0x3c) [30803.668106] r9:d9648000 r8:c000dcc4 r6:00000001 r5:002694d0 r4:00000003 [30803.669927] PM: early resume of devices complete after 0.972 msecs Just move the clk_enable/disable in ->prepare() and ->finish() Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
75 lines
1.6 KiB
C
75 lines
1.6 KiB
C
/*
|
|
* Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
*
|
|
* The code contained herein is licensed under the GNU General Public
|
|
* License. You may obtain a copy of the GNU General Public License
|
|
* Version 2 or later at the following locations:
|
|
*
|
|
* http://www.opensource.org/licenses/gpl-license.html
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*/
|
|
#include <linux/suspend.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/io.h>
|
|
#include <linux/err.h>
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/tlbflush.h>
|
|
#include <mach/common.h>
|
|
#include <mach/hardware.h>
|
|
#include "crm_regs.h"
|
|
|
|
static struct clk *gpc_dvfs_clk;
|
|
|
|
static int mx5_suspend_enter(suspend_state_t state)
|
|
{
|
|
clk_enable(gpc_dvfs_clk);
|
|
switch (state) {
|
|
case PM_SUSPEND_MEM:
|
|
mx5_cpu_lp_set(STOP_POWER_OFF);
|
|
break;
|
|
case PM_SUSPEND_STANDBY:
|
|
mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (state == PM_SUSPEND_MEM) {
|
|
local_flush_tlb_all();
|
|
flush_cache_all();
|
|
|
|
/*clear the EMPGC0/1 bits */
|
|
__raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
|
|
__raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
|
|
}
|
|
cpu_do_idle();
|
|
clk_disable(gpc_dvfs_clk);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mx5_pm_valid(suspend_state_t state)
|
|
{
|
|
return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
|
|
}
|
|
|
|
static const struct platform_suspend_ops mx5_suspend_ops = {
|
|
.valid = mx5_pm_valid,
|
|
.enter = mx5_suspend_enter,
|
|
};
|
|
|
|
static int __init mx5_pm_init(void)
|
|
{
|
|
if (gpc_dvfs_clk == NULL)
|
|
gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
|
|
|
|
if (!IS_ERR(gpc_dvfs_clk)) {
|
|
if (cpu_is_mx51())
|
|
suspend_set_ops(&mx5_suspend_ops);
|
|
} else
|
|
return -EPERM;
|
|
|
|
return 0;
|
|
}
|
|
device_initcall(mx5_pm_init);
|