1 /* 2 * Copyright (C) 2014 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/cpuidle.h> 10 #include <linux/module.h> 11 #include <asm/cpuidle.h> 12 13 #include "common.h" 14 #include "cpuidle.h" 15 16 static int imx6sl_enter_wait(struct cpuidle_device *dev, 17 struct cpuidle_driver *drv, int index) 18 { 19 imx6_set_lpm(WAIT_UNCLOCKED); 20 /* 21 * Software workaround for ERR005311, see function 22 * description for details. 23 */ 24 imx6sl_set_wait_clk(true); 25 cpu_do_idle(); 26 imx6sl_set_wait_clk(false); 27 imx6_set_lpm(WAIT_CLOCKED); 28 29 return index; 30 } 31 32 static struct cpuidle_driver imx6sl_cpuidle_driver = { 33 .name = "imx6sl_cpuidle", 34 .owner = THIS_MODULE, 35 .states = { 36 /* WFI */ 37 ARM_CPUIDLE_WFI_STATE, 38 /* WAIT */ 39 { 40 .exit_latency = 50, 41 .target_residency = 75, 42 .flags = CPUIDLE_FLAG_TIMER_STOP, 43 .enter = imx6sl_enter_wait, 44 .name = "WAIT", 45 .desc = "Clock off", 46 }, 47 }, 48 .state_count = 2, 49 .safe_state_index = 0, 50 }; 51 52 int __init imx6sl_cpuidle_init(void) 53 { 54 return cpuidle_register(&imx6sl_cpuidle_driver, NULL); 55 } 56