1 /* linux/arch/arm/mach-exynos4/cpuidle.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/cpuidle.h>
16 #include <asm/proc-fns.h>
18 static int exynos4_enter_idle(struct cpuidle_device
*dev
,
19 struct cpuidle_driver
*drv
,
22 static struct cpuidle_state exynos4_cpuidle_set
[] = {
24 .enter
= exynos4_enter_idle
,
26 .target_residency
= 100000,
27 .flags
= CPUIDLE_FLAG_TIME_VALID
,
29 .desc
= "ARM clock gating(WFI)",
33 static DEFINE_PER_CPU(struct cpuidle_device
, exynos4_cpuidle_device
);
35 static struct cpuidle_driver exynos4_idle_driver
= {
36 .name
= "exynos4_idle",
40 static int exynos4_enter_idle(struct cpuidle_device
*dev
,
41 struct cpuidle_driver
*drv
,
44 struct timeval before
, after
;
48 do_gettimeofday(&before
);
52 do_gettimeofday(&after
);
54 idle_time
= (after
.tv_sec
- before
.tv_sec
) * USEC_PER_SEC
+
55 (after
.tv_usec
- before
.tv_usec
);
57 dev
->last_residency
= idle_time
;
61 static int __init
exynos4_init_cpuidle(void)
63 int i
, max_cpuidle_state
, cpu_id
;
64 struct cpuidle_device
*device
;
65 struct cpuidle_driver
*drv
= &exynos4_idle_driver
;
67 /* Setup cpuidle driver */
68 drv
->state_count
= (sizeof(exynos4_cpuidle_set
) /
69 sizeof(struct cpuidle_state
));
70 max_cpuidle_state
= drv
->state_count
;
71 for (i
= 0; i
< max_cpuidle_state
; i
++) {
72 memcpy(&drv
->states
[i
], &exynos4_cpuidle_set
[i
],
73 sizeof(struct cpuidle_state
));
75 cpuidle_register_driver(&exynos4_idle_driver
);
77 for_each_cpu(cpu_id
, cpu_online_mask
) {
78 device
= &per_cpu(exynos4_cpuidle_device
, cpu_id
);
81 device
->state_count
= drv
->state_count
;
83 if (cpuidle_register_device(device
)) {
84 printk(KERN_ERR
"CPUidle register device failed\n,");
90 device_initcall(exynos4_init_cpuidle
);