~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/arm/mach-shmobile/cpuidle.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * CPUIdle support code for SH-Mobile ARM
 
3
 *
 
4
 *  Copyright (C) 2011 Magnus Damm
 
5
 *
 
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
 
8
 * for more details.
 
9
 */
 
10
 
 
11
#include <linux/pm.h>
 
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>
 
17
#include <asm/io.h>
 
18
 
 
19
static void shmobile_enter_wfi(void)
 
20
{
 
21
        cpu_do_idle();
 
22
}
 
23
 
 
24
void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
 
25
        shmobile_enter_wfi, /* regular sleep mode */
 
26
};
 
27
 
 
28
static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
 
29
                                  struct cpuidle_state *state)
 
30
{
 
31
        ktime_t before, after;
 
32
        int requested_state = state - &dev->states[0];
 
33
 
 
34
        dev->last_state = &dev->states[requested_state];
 
35
        before = ktime_get();
 
36
 
 
37
        local_irq_disable();
 
38
        local_fiq_disable();
 
39
 
 
40
        shmobile_cpuidle_modes[requested_state]();
 
41
 
 
42
        local_irq_enable();
 
43
        local_fiq_enable();
 
44
 
 
45
        after = ktime_get();
 
46
        return ktime_to_ns(ktime_sub(after, before)) >> 10;
 
47
}
 
48
 
 
49
static struct cpuidle_device shmobile_cpuidle_dev;
 
50
static struct cpuidle_driver shmobile_cpuidle_driver = {
 
51
        .name =         "shmobile_cpuidle",
 
52
        .owner =        THIS_MODULE,
 
53
};
 
54
 
 
55
void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
 
56
 
 
57
static int shmobile_cpuidle_init(void)
 
58
{
 
59
        struct cpuidle_device *dev = &shmobile_cpuidle_dev;
 
60
        struct cpuidle_state *state;
 
61
        int i;
 
62
 
 
63
        cpuidle_register_driver(&shmobile_cpuidle_driver);
 
64
 
 
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;
 
69
        }
 
70
 
 
71
        i = CPUIDLE_DRIVER_STATE_START;
 
72
 
 
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;
 
79
        state->flags = 0;
 
80
        state->flags |= CPUIDLE_FLAG_TIME_VALID;
 
81
 
 
82
        dev->safe_state = state;
 
83
        dev->state_count = i;
 
84
 
 
85
        if (shmobile_cpuidle_setup)
 
86
                shmobile_cpuidle_setup(dev);
 
87
 
 
88
        cpuidle_register_device(dev);
 
89
 
 
90
        return 0;
 
91
}
 
92
late_initcall(shmobile_cpuidle_init);