2 * CPUIdle support code for SH-Mobile ARM
4 * Copyright (C) 2011 Magnus Damm
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/cpuidle.h>
13 #include <linux/suspend.h>
14 #include <linux/module.h>
15 #include <linux/err.h>
16 #include <asm/system.h>
19 static void shmobile_enter_wfi(void)
24 void (*shmobile_cpuidle_modes
[CPUIDLE_STATE_MAX
])(void) = {
25 shmobile_enter_wfi
, /* regular sleep mode */
28 static int shmobile_cpuidle_enter(struct cpuidle_device
*dev
,
29 struct cpuidle_state
*state
)
31 ktime_t before
, after
;
32 int requested_state
= state
- &dev
->states
[0];
34 dev
->last_state
= &dev
->states
[requested_state
];
40 shmobile_cpuidle_modes
[requested_state
]();
46 return ktime_to_ns(ktime_sub(after
, before
)) >> 10;
49 static struct cpuidle_device shmobile_cpuidle_dev
;
50 static struct cpuidle_driver shmobile_cpuidle_driver
= {
51 .name
= "shmobile_cpuidle",
55 void (*shmobile_cpuidle_setup
)(struct cpuidle_device
*dev
);
57 static int shmobile_cpuidle_init(void)
59 struct cpuidle_device
*dev
= &shmobile_cpuidle_dev
;
60 struct cpuidle_state
*state
;
63 cpuidle_register_driver(&shmobile_cpuidle_driver
);
65 for (i
= 0; i
< CPUIDLE_STATE_MAX
; i
++) {
66 dev
->states
[i
].name
[0] = '\0';
67 dev
->states
[i
].desc
[0] = '\0';
68 dev
->states
[i
].enter
= shmobile_cpuidle_enter
;
71 i
= CPUIDLE_DRIVER_STATE_START
;
73 state
= &dev
->states
[i
++];
74 snprintf(state
->name
, CPUIDLE_NAME_LEN
, "C1");
75 strncpy(state
->desc
, "WFI", CPUIDLE_DESC_LEN
);
76 state
->exit_latency
= 1;
77 state
->target_residency
= 1 * 2;
78 state
->power_usage
= 3;
80 state
->flags
|= CPUIDLE_FLAG_TIME_VALID
;
82 dev
->safe_state
= state
;
85 if (shmobile_cpuidle_setup
)
86 shmobile_cpuidle_setup(dev
);
88 cpuidle_register_device(dev
);
92 late_initcall(shmobile_cpuidle_init
);