Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cpuidle.c
Go to the documentation of this file.
1 /*
2  * arch/arm/mach-tegra/cpuidle.c
3  *
4  * CPU idle driver for Tegra CPUs
5  *
6  * Copyright (c) 2010-2012, NVIDIA Corporation.
7  * Copyright (c) 2011 Google, Inc.
8  * Author: Colin Cross <[email protected]>
9  * Gary King <[email protected]>
10  *
11  * Rework for 3.3 by Peter De Schrijver <[email protected]>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21  * more details.
22  */
23 
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/cpu.h>
27 #include <linux/cpuidle.h>
28 #include <linux/hrtimer.h>
29 
30 #include <asm/proc-fns.h>
31 
32 #include <mach/iomap.h>
33 
34 static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
35  struct cpuidle_driver *drv, int index);
36 
38  .name = "tegra_idle",
39  .owner = THIS_MODULE,
40  .state_count = 1,
41  .states = {
42  [0] = {
43  .enter = tegra_idle_enter_lp3,
44  .exit_latency = 10,
45  .target_residency = 10,
46  .power_usage = 600,
47  .flags = CPUIDLE_FLAG_TIME_VALID,
48  .name = "LP3",
49  .desc = "CPU flow-controlled",
50  },
51  },
52 };
53 
54 static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
55 
56 static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
57  struct cpuidle_driver *drv, int index)
58 {
60  s64 us;
61 
63  local_fiq_disable();
64 
65  enter = ktime_get();
66 
67  cpu_do_idle();
68 
69  exit = ktime_sub(ktime_get(), enter);
70  us = ktime_to_us(exit);
71 
72  local_fiq_enable();
74 
75  dev->last_residency = us;
76 
77  return index;
78 }
79 
80 static int __init tegra_cpuidle_init(void)
81 {
82  int ret;
83  unsigned int cpu;
84  struct cpuidle_device *dev;
85  struct cpuidle_driver *drv = &tegra_idle_driver;
86 
87  ret = cpuidle_register_driver(&tegra_idle_driver);
88  if (ret) {
89  pr_err("CPUidle driver registration failed\n");
90  return ret;
91  }
92 
94  dev = &per_cpu(tegra_idle_device, cpu);
95  dev->cpu = cpu;
96 
97  dev->state_count = drv->state_count;
98  ret = cpuidle_register_device(dev);
99  if (ret) {
100  pr_err("CPU%u: CPUidle device registration failed\n",
101  cpu);
102  return ret;
103  }
104  }
105  return 0;
106 }
107 device_initcall(tegra_cpuidle_init);