1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2014 Freescale Semiconductor, Inc. |
4 | */ |
5 | |
6 | #include <linux/clk/imx.h> |
7 | #include <linux/cpuidle.h> |
8 | #include <linux/module.h> |
9 | #include <asm/cpuidle.h> |
10 | |
11 | #include "common.h" |
12 | #include "cpuidle.h" |
13 | |
14 | static __cpuidle int imx6sl_enter_wait(struct cpuidle_device *dev, |
15 | struct cpuidle_driver *drv, int index) |
16 | { |
17 | imx6_set_lpm(mode: WAIT_UNCLOCKED); |
18 | /* |
19 | * Software workaround for ERR005311, see function |
20 | * description for details. |
21 | */ |
22 | imx6sl_set_wait_clk(enter: true); |
23 | cpu_do_idle(); |
24 | imx6sl_set_wait_clk(enter: false); |
25 | imx6_set_lpm(mode: WAIT_CLOCKED); |
26 | |
27 | return index; |
28 | } |
29 | |
30 | static struct cpuidle_driver imx6sl_cpuidle_driver = { |
31 | .name = "imx6sl_cpuidle" , |
32 | .owner = THIS_MODULE, |
33 | .states = { |
34 | /* WFI */ |
35 | ARM_CPUIDLE_WFI_STATE, |
36 | /* WAIT */ |
37 | { |
38 | .exit_latency = 50, |
39 | .target_residency = 75, |
40 | .flags = CPUIDLE_FLAG_TIMER_STOP, |
41 | .enter = imx6sl_enter_wait, |
42 | .name = "WAIT" , |
43 | .desc = "Clock off" , |
44 | }, |
45 | }, |
46 | .state_count = 2, |
47 | .safe_state_index = 0, |
48 | }; |
49 | |
50 | int __init imx6sl_cpuidle_init(void) |
51 | { |
52 | return cpuidle_register(drv: &imx6sl_cpuidle_driver, NULL); |
53 | } |
54 | |