arm: tegra: power: ignore duplicate reg_override values
[linux-3.10.git] / arch / arm / mach-tegra / edp.c
1 /*
2  * arch/arm/mach-tegra/edp.c
3  *
4  * Copyright (C) 2011-2012, NVIDIA CORPORATION. All Rights Reserved.
5  *
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.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  * 02111-1307, USA
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/init.h>
23 #include <linux/seq_file.h>
24 #include <linux/slab.h>
25 #include <linux/module.h>
26 #include <linux/uaccess.h>
27 #include <mach/edp.h>
28
29 #include "fuse.h"
30 #include "dvfs.h"
31 #include "clock.h"
32 #include "cpu-tegra.h"
33
34 #define FREQ_STEP 12750000
35 #define OVERRIDE_DEFAULT 6000
36
37 static struct tegra_edp_limits *edp_limits;
38 static int edp_limits_size;
39 static unsigned int regulator_cur;
40 /* Value to subtract from regulator current limit */
41 static unsigned int edp_reg_override_mA = OVERRIDE_DEFAULT;
42
43 static const unsigned int *system_edp_limits;
44
45 /*
46  * Temperature step size cannot be less than 4C because of hysteresis
47  * delta
48  * Code assumes different temperatures for the same speedo_id /
49  * regulator_cur are adjacent in the table, and higest regulator_cur
50  * comes first
51  */
52 static char __initdata tegra_edp_map[] = {
53         0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
54         0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
55         0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
56         0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
57         0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
58         0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
59         0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
60         0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
61         0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
62         0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
63         0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
64         0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
65         0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
66         0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
67         0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
68         0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
69         0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
70         0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
71         0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
72         0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
73         0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
74         0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
75         0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
76         0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
77         0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
78         0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
79         0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
80         0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
81         0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
82         0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
83         0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
84         0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
85         0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
86         0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
87         0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
88         0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
89         0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
90         0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
91         0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
92         0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
93         0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
94         0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
95         0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
96         0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
97         0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
98         0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
99         0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
100         0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
101         0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
102         0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
103         0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
104         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
105         0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
106         0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
107         0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
108         0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
109         0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
110         0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
111         0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
112         0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
113         0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
114         0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
115         0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
116         0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
117         0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
118         0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
119         0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
120         0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
121         0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
122         0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
123         0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
124         0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
125         0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
126         0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
127         0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
128         0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
129         0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
130         0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
131         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
132         0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
133         0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
134         0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
135         0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
136         0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
137         0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
138         0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
139         0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
140         0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
141         0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
142         0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
143         0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
144         0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
145         0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
146         0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
147         0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
148         0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
149         0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
150         0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
151         0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
152         0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
153         0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
154         0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
155         0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
156         0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
157         0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
158         0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
159         0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
160         0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
161         0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
162         0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
163         0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
164         0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
165         0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
166         0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
167         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
168         0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
169         0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
170         0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
171         0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
172         0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
173         0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
174         0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
175         0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
176         0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
177         0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
178         0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
179         0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
180         0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
181         0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
182         0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
183         0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
184         0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
185         0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
186         0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
187         0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
188         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
189         0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
190         0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
191         0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
192         0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
193         0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
194         0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
195         0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
196         0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
197         0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
198         0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
199         0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
200         0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
201         0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
202         0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
203         0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
204         0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
205         0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
206         0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
207         0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
208         0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
209         0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
210         0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
211         0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
212         0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
213         0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
214         0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
215         0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
216         0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
217         0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
218         0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
219         0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
220         0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
221         0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
222         0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
223         0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
224         0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
225         0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
226         0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
227         0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
228         0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
229         0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
230         0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
231         0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
232         0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
233         0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
234         0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
235         0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
236         0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
237         0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
238         0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
239         0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
240         0x5a, 0x46, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
241         0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
242         0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
243         0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
244         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
245         0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
246         0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
247         0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
248         0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
249         0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
250         0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
251         0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
252         0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
253         0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
254         0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
255         0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
256         0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
257         0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
258         0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
259         0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
260         0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
261         0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
262         0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
263         0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
264         0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
265         0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
266         0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
267         0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
268         0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
269         0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
270         0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
271         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
272         0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
273         0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
274         0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
275         0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
276         0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
277         0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
278         0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
279         0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
280         0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
281         0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
282         0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
283         0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
284         0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
285         0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
286         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
287         0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
288         0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
289         0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
290         0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
291         0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
292         0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
293 };
294
295
296 static struct system_edp_entry __initdata tegra_system_edp_map[] = {
297
298 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
299
300         {  1,  49, {130, 120, 120, 120} },
301         {  1,  44, {130, 120, 120, 110} },
302         {  1,  37, {130, 120, 110, 100} },
303         {  1,  35, {130, 120, 110,  90} },
304         {  1,  29, {130, 120, 100,  80} },
305         {  1,  27, {130, 120,  90,  80} },
306         {  1,  25, {130, 110,  80,  60} },
307         {  1,  21, {130, 100,  80,  40} },
308
309         {  4,  49, {130, 120, 120, 120} },
310         {  4,  44, {130, 120, 120, 110} },
311         {  4,  37, {130, 120, 110, 100} },
312         {  4,  35, {130, 120, 110,  90} },
313         {  4,  29, {130, 120, 100,  80} },
314         {  4,  27, {130, 120,  90,  80} },
315         {  4,  25, {130, 110,  80,  60} },
316         {  4,  21, {130, 100,  80,  40} },
317 };
318
319 /*
320  * "Safe entry" to be used when no match for speedo_id /
321  * regulator_cur is found; must be the last one
322  */
323 static struct tegra_edp_limits edp_default_limits[] = {
324         {85, {1000000, 1000000, 1000000, 1000000} },
325 };
326
327 /*
328  * Constants for EDP calculations
329  */
330 int temps_lut[] = { 23, 40, 50, 60, 70, 75, 80, 85, 90, 95 };
331
332 /* TODO: This struct will get large for 13 speedo IDs... relocate. */
333 struct edp_constants_lut_t {
334         int cpu_speedo_id;
335         /* All constants are pre-multiplied by 1,000,000 */
336         int leakage_consts_ijk[64];
337         int leakage_consts_n[NR_CPUS];
338         int dyn_consts_n[NR_CPUS];
339 } edp_constants_lut[] = {
340         {
341                 .cpu_speedo_id = -1,
342                 .leakage_consts_n = {
343                         641026,
344                         757576,
345                         878500,
346                         1000000
347                 },
348                 /* Constants order: C(i,j,k), i,j,k = {0,1,2,3}, with k
349                  * being the least significant index and i being the most
350                  * significant index */
351                 .leakage_consts_ijk =  {
352                         0,
353                         -21481846,
354                         519650,
355                         -3254,
356                         0,
357                         65678948,
358                         -1572498,
359                         9850,
360                         0,
361                         -65988168,
362                         1565063,
363                         -9808,
364                         0,
365                         22109316,
366                         -522158,
367                         3281,
368                         0,
369                         24840561,
370                         -565618,
371                         5196,
372                         0,
373                         -65603470,
374                         1592186,
375                         -13823,
376                         0,
377                         56585242,
378                         -1488977,
379                         12944,
380                         0,
381                         -14740016,
382                         470284,
383                         -3670,
384                         0,
385                         -7050232,
386                         244771,
387                         -1779,
388                         0,
389                         20985919,
390                         -701848,
391                         5008,
392                         0,
393                         -20478304,
394                         677782,
395                         -4766,
396                         0,
397                         7093793,
398                         -218579,
399                         1454,
400                         0,
401                         942881,
402                         -29599,
403                         203,
404                         0,
405                         -2750253,
406                         84116,
407                         -569,
408                         0,
409                         2643026,
410                         -80080,
411                         536,
412                         0,
413                         -868855,
414                         25062,
415                         -161,
416                 }, /* consts_ijk */
417                 .dyn_consts_n = {
418                         1560207,
419                         2378136,
420                         3196066,
421                         4013995
422                 }
423         }
424 };
425
426 struct freq_voltage_lut_t {
427         unsigned int freq;
428         int voltage_mV;
429 } *freq_voltage_lut = 0;
430 unsigned int freq_voltage_lut_size;
431
432 static inline s64 edp_pow(s64 val, int pwr)
433 {
434         s64 retval = 1;
435
436         while (pwr) {
437                 if (pwr & 1)
438                         retval *= val;
439                 pwr >>= 1;
440                 if (pwr)
441                         val *= val;
442         }
443
444         return retval;
445 }
446
447 /*
448  * Find the maximum frequency that results in dynamic and leakage current that
449  * is less than the regulator current limit.
450  */
451 unsigned int edp_calculate_maxf(struct edp_constants_lut_t  *edp_constants,
452                                 int temp_C,
453                                 int iddq_mA,
454                                 int n_cores_idx)
455 {
456         unsigned int voltage_mV, freq_MHz;
457         unsigned int regulator_cur_effective;
458         int f_v_pair, i, j, k, leakage_const_n, dyn_const_n;
459         int *leakage_consts_ijk;
460         s64 leakage_mA, dyn_mA, leakage_calc_step;
461         /* WAR for GCC 4.4.3 bug 43949 - compiler throws an array bounds warning
462          * if these arrays are dereferenced in the calling function*/
463         leakage_consts_ijk = edp_constants->leakage_consts_ijk;
464         dyn_const_n = edp_constants->dyn_consts_n[n_cores_idx];
465         leakage_const_n = edp_constants->leakage_consts_n[n_cores_idx];
466         regulator_cur_effective = regulator_cur - edp_reg_override_mA;
467
468         for (f_v_pair = freq_voltage_lut_size - 1; f_v_pair  >= 0; f_v_pair--) {
469                 freq_MHz = freq_voltage_lut[f_v_pair].freq / 1000000;
470                 voltage_mV = freq_voltage_lut[f_v_pair].voltage_mV;
471
472                 /*
473                  * Calculate leakage current
474                  */
475                 leakage_mA = 0;
476                 for (i = 0; i <= 3; i++)
477                         for (j = 0; j <= 3; j++)
478                                 for (k = 0; k <= 3; k++) {
479                                         leakage_calc_step =
480                                              leakage_consts_ijk[i*16 + j*4 + k]
481                                                 * edp_pow(iddq_mA, i);
482                                         /* Convert (mA)^i to (A)^i */
483                                         leakage_calc_step =
484                                                 div64_s64(leakage_calc_step,
485                                                           edp_pow(1000, i));
486                                         leakage_calc_step *=
487                                                 edp_pow(voltage_mV, j);
488                                         /* Convert (mV)^i to (V)^i */
489                                         leakage_calc_step =
490                                                 div64_s64(leakage_calc_step,
491                                                           edp_pow(1000, j));
492                                         leakage_calc_step *=
493                                                 edp_pow(temp_C, k);
494                                         /* const_ijk was X 1,000,000 */
495                                         leakage_calc_step =
496                                                 div64_s64(leakage_calc_step,
497                                                           1000000);
498                                         leakage_mA += leakage_calc_step;
499                                 }
500
501                 leakage_mA *= leakage_const_n;
502                 /* leakage_const_n was pre-multiplied by 1,000,000 */
503                 leakage_mA = div64_s64(leakage_mA, 1000000);
504
505                 /*
506                  * Calculate dynamic current
507                  */
508                 dyn_mA = voltage_mV * freq_MHz;
509                 /* Convert mV to V */
510                 dyn_mA = div64_s64(dyn_mA, 1000);
511                 dyn_mA *= dyn_const_n;
512                 /* dyn_const_n was pre-multiplied by 1,000,000 */
513                 dyn_mA = div64_s64(dyn_mA, 1000000);
514
515                 if ((leakage_mA + dyn_mA) <= regulator_cur_effective)
516                         return freq_MHz * 1000;
517         }
518         return 0;
519 }
520
521 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
522                                 unsigned int cpu_speedo_idx)
523 {
524         unsigned int i, j, freq;
525         int voltage_mV;
526
527         for (i = 0, j = 0, freq = 0;
528                  i < freq_voltage_lut_size;
529                  i++, freq += FREQ_STEP) {
530
531                 /* Predict voltages */
532                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
533                 if (voltage_mV < 0) {
534                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
535                                __func__, freq, voltage_mV);
536                         return -EINVAL;
537                 }
538
539                 /* Cache frequency / voltage / voltage constant relationship */
540                 freq_voltage_lut[i].freq = freq;
541                 freq_voltage_lut[i].voltage_mV = voltage_mV;
542         }
543         return 0;
544 }
545
546 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
547 {
548         int i;
549
550         for (i = 0; i < ARRAY_SIZE(edp_constants_lut); i++)
551                 if (cpu_speedo_id == edp_constants_lut[i].cpu_speedo_id) {
552                         *cpu_speedo_idx = i;
553                         return 0;
554                 }
555
556         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
557                __func__, cpu_speedo_id);
558         return -EINVAL;
559 }
560
561 int init_cpu_edp_limits_calculated(int cpu_speedo_id)
562 {
563         unsigned int temp_idx, n_cores_idx;
564         unsigned int cpu_g_minf, cpu_g_maxf;
565         unsigned int iddq_mA;
566         unsigned int cpu_speedo_idx;
567         struct tegra_edp_limits *edp_calculated_limits;
568         struct edp_constants_lut_t *edp_constants;
569         int ret;
570         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
571
572         /* Determine all inputs to EDP formula */
573         iddq_mA = tegra_get_cpu_iddq_value();
574         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
575         if (ret)
576                 return ret;
577
578         edp_constants = &edp_constants_lut[cpu_speedo_idx];
579
580         edp_calculated_limits =
581                 kmalloc(sizeof(struct tegra_edp_limits) * ARRAY_SIZE(temps_lut),
582                                 GFP_KERNEL);
583         BUG_ON(!edp_calculated_limits);
584
585         cpu_g_minf = 0;
586         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
587         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
588         freq_voltage_lut =
589                 kmalloc(sizeof(struct freq_voltage_lut_t)*freq_voltage_lut_size,
590                                 GFP_KERNEL);
591         if (!freq_voltage_lut) {
592                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
593                 return -ENOMEM;
594         }
595
596         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
597         if (ret) {
598                 kfree(freq_voltage_lut);
599                 return ret;
600         }
601
602         /* Calculate EDP table */
603         for (temp_idx = 0; temp_idx < ARRAY_SIZE(temps_lut); temp_idx++) {
604                 edp_calculated_limits[temp_idx].temperature =
605                         temps_lut[temp_idx];
606
607                 for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++)
608                         edp_calculated_limits[temp_idx].
609                                 freq_limits[n_cores_idx] =
610                                 edp_calculate_maxf(edp_constants,
611                                                 temps_lut[temp_idx],
612                                                 iddq_mA,
613                                                 n_cores_idx);
614         }
615
616         /*
617          * If this is an EDP table update, need to overwrite old table.
618          * The old table's address must remain valid.
619          */
620         if (edp_limits != edp_default_limits) {
621                 memcpy(edp_limits, edp_calculated_limits,
622                        sizeof(struct tegra_edp_limits) * ARRAY_SIZE(temps_lut));
623                 kfree(edp_calculated_limits);
624         }
625         else {
626                 edp_limits = edp_calculated_limits;
627                 edp_limits_size = ARRAY_SIZE(temps_lut);
628         }
629
630         kfree(freq_voltage_lut);
631         return 0;
632 }
633
634 int __init init_cpu_edp_limits_lookup(int cpu_speedo_id)
635 {
636         int i, j;
637         struct tegra_edp_limits *e;
638         struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
639         int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
640
641         for (i = 0; i < tsize; i++) {
642                 if (t[i].speedo_id == cpu_speedo_id &&
643                     t[i].regulator_100mA <= regulator_cur / 100)
644                         break;
645         }
646
647         /* No entry found in tegra_edp_map */
648         if (i >= tsize)
649                 return -EINVAL;
650
651         /* Find all rows for this entry */
652         for (j = i + 1; j < tsize; j++) {
653                 if (t[i].speedo_id != t[j].speedo_id ||
654                     t[i].regulator_100mA != t[j].regulator_100mA)
655                         break;
656         }
657
658         edp_limits_size = j - i;
659         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
660                     GFP_KERNEL);
661         BUG_ON(!e);
662
663         for (j = 0; j < edp_limits_size; j++) {
664                 e[j].temperature = (int)t[i+j].temperature;
665                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
666                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
667                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
668                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
669         }
670
671         if (edp_limits != edp_default_limits)
672                 kfree(edp_limits);
673
674         edp_limits = e;
675         return 0;
676 }
677
678 /*
679  * Specify regulator current in mA, e.g. 5000mA
680  * Use 0 for default
681  */
682 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
683 {
684         int cpu_speedo_id = tegra_cpu_speedo_id();
685
686         if (!regulator_mA) {
687                 edp_limits = edp_default_limits;
688                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
689                 return;
690         }
691         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
692
693         switch (tegra_chip_id) {
694         case TEGRA30:
695                 if (init_cpu_edp_limits_lookup(cpu_speedo_id) == 0)
696                         return;
697                 break;
698         case TEGRA11X:
699                 if (init_cpu_edp_limits_calculated(cpu_speedo_id) == 0)
700                         return;
701                 break;
702         case TEGRA20:
703         default:
704                 BUG();
705                 break;
706         }
707
708         edp_limits = edp_default_limits;
709         edp_limits_size = ARRAY_SIZE(edp_default_limits);
710 }
711
712 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
713 {
714         int cpu_speedo_id = tegra_cpu_speedo_id();
715         int i;
716         unsigned int *e;
717         struct system_edp_entry *t =
718                 (struct system_edp_entry *)tegra_system_edp_map;
719         int tsize = sizeof(tegra_system_edp_map) /
720                 sizeof(struct system_edp_entry);
721
722         if (!power_limit_mW) {
723                 e = NULL;
724                 goto out;
725         }
726
727         for (i = 0; i < tsize; i++)
728                 if (t[i].speedo_id == cpu_speedo_id)
729                         break;
730
731         if (i >= tsize) {
732                 e = NULL;
733                 goto out;
734         }
735
736         do {
737                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
738                         break;
739                 i++;
740         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
741
742         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
743                 i--; /* No low enough entry in the table, use best possible */
744
745         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
746         BUG_ON(!e);
747
748         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
749         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
750         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
751         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
752
753 out:
754         kfree(system_edp_limits);
755
756         system_edp_limits = e;
757 }
758
759
760 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
761 {
762         *limits = edp_limits;
763         *size = edp_limits_size;
764 }
765
766 void tegra_get_system_edp_limits(const unsigned int **limits)
767 {
768         *limits = system_edp_limits;
769 }
770
771 #ifdef CONFIG_EDP_FRAMEWORK
772
773 static struct edp_manager battery_edp_manager = {
774         .name = "battery"
775 };
776
777 void __init tegra_battery_edp_init(unsigned int cap)
778 {
779         struct edp_governor *g;
780         int r;
781
782         battery_edp_manager.imax = cap;
783         r = edp_register_manager(&battery_edp_manager);
784         if (r)
785                 goto err_ret;
786
787         /* start with priority governor */
788         g = edp_get_governor("priority");
789         if (!g) {
790                 r = -EFAULT;
791                 goto err_ret;
792         }
793
794         r = edp_set_governor(&battery_edp_manager, g);
795         if (r)
796                 goto err_ret;
797
798         return;
799
800 err_ret:
801         pr_err("Battery EDP init failed with error %d\n", r);
802         WARN_ON(1);
803 }
804
805 #endif
806
807 #ifdef CONFIG_DEBUG_FS
808
809 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
810 {
811         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
812         return 0;
813 }
814
815 static int edp_debugfs_show(struct seq_file *s, void *data)
816 {
817         int i, th_idx;
818
819         tegra_get_edp_limit(&th_idx);
820         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
821                    edp_limits == edp_default_limits ? "default " : "",
822                    regulator_cur - edp_reg_override_mA,
823                    regulator_cur, edp_reg_override_mA);
824         seq_printf(s, "%6s %10s %10s %10s %10s\n",
825                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
826         for (i = 0; i < edp_limits_size; i++) {
827                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
828                            i == th_idx ? '>' : ' ',
829                            edp_limits[i].temperature,
830                            edp_limits[i].freq_limits[0],
831                            edp_limits[i].freq_limits[1],
832                            edp_limits[i].freq_limits[2],
833                            edp_limits[i].freq_limits[3]);
834         }
835
836         if (system_edp_limits) {
837                 seq_printf(s, "\n-- System EDP table --\n");
838                 seq_printf(s, "%10u %10u %10u %10u\n",
839                            system_edp_limits[0],
840                            system_edp_limits[1],
841                            system_edp_limits[2],
842                            system_edp_limits[3]);
843         }
844
845         return 0;
846 }
847
848 static int edp_reg_override_show(struct seq_file *s, void *data)
849 {
850         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
851                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
852         return 0;
853 }
854
855 static int edp_reg_override_write(struct file *file,
856         const char __user *userbuf, size_t count, loff_t *ppos)
857 {
858         char buf[32], *end;
859         unsigned int edp_reg_override_mA_temp;
860         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
861         int cpu_speedo_id;
862
863         if (sizeof(buf) <= count)
864                 goto override_err;
865
866         if (copy_from_user(buf, userbuf, count))
867                 goto override_err;
868
869         /* terminate buffer and trim - white spaces may be appended
870          *  at the end when invoked from shell command line */
871         buf[count]='\0';
872         strim(buf);
873
874         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
875         if (*end != '\0')
876                 goto override_err;
877
878         if (edp_reg_override_mA_temp >= regulator_cur)
879                 goto override_err;
880
881         if (edp_reg_override_mA == edp_reg_override_mA_temp)
882                 return count;
883
884         edp_reg_override_mA = edp_reg_override_mA_temp;
885         cpu_speedo_id = tegra_cpu_speedo_id();
886         if (init_cpu_edp_limits_calculated(cpu_speedo_id)) {
887                 /* Revert to previous override value if new value fails */
888                 edp_reg_override_mA = edp_reg_override_mA_prev;
889                 goto override_err;
890         }
891
892         if (tegra_cpu_set_speed_cap(NULL)) {
893                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
894                 goto override_out;
895         }
896
897         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
898                         " %u mA\n", regulator_cur - edp_reg_override_mA);
899
900         return count;
901
902 override_err:
903         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
904                buf);
905 override_out:
906         return -EINVAL;
907 }
908
909 static int edp_debugfs_open(struct inode *inode, struct file *file)
910 {
911         return single_open(file, edp_debugfs_show, inode->i_private);
912 }
913
914 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
915 {
916         return single_open(file, edp_limit_debugfs_show, inode->i_private);
917 }
918
919 static int edp_reg_override_open(struct inode *inode, struct file *file)
920 {
921         return single_open(file, edp_reg_override_show, inode->i_private);
922 }
923
924 static const struct file_operations edp_debugfs_fops = {
925         .open           = edp_debugfs_open,
926         .read           = seq_read,
927         .llseek         = seq_lseek,
928         .release        = single_release,
929 };
930
931 static const struct file_operations edp_limit_debugfs_fops = {
932         .open           = edp_limit_debugfs_open,
933         .read           = seq_read,
934         .llseek         = seq_lseek,
935         .release        = single_release,
936 };
937
938 static const struct file_operations edp_reg_override_debugfs_fops = {
939         .open           = edp_reg_override_open,
940         .read           = seq_read,
941         .write          = edp_reg_override_write,
942         .llseek         = seq_lseek,
943         .release        = single_release,
944 };
945
946 static int __init tegra_edp_debugfs_init(void)
947 {
948         struct dentry *d_edp;
949         struct dentry *d_edp_limit;
950         struct dentry *d_edp_reg_override;
951         struct dentry *edp_dir;
952         struct dentry *vdd_cpu_dir;
953
954         edp_dir = debugfs_create_dir("edp", NULL);
955
956         if (!edp_dir)
957                 goto edp_dir_err;
958
959         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
960
961         if (!vdd_cpu_dir)
962                 goto vdd_cpu_dir_err;
963
964         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
965                                 &edp_debugfs_fops);
966
967         if (!d_edp)
968                 goto edp_err;
969
970         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
971                                 NULL, &edp_limit_debugfs_fops);
972
973         if (!d_edp_limit)
974                 goto edp_limit_err;
975
976         d_edp_reg_override = debugfs_create_file("edp_reg_override",
977                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
978                                 &edp_reg_override_debugfs_fops);
979
980         if (!d_edp_reg_override)
981                 goto edp_reg_override_err;
982
983         return 0;
984
985 edp_reg_override_err:
986         debugfs_remove(d_edp_limit);
987 edp_limit_err:
988         debugfs_remove(d_edp);
989 edp_err:
990         debugfs_remove(vdd_cpu_dir);
991 vdd_cpu_dir_err:
992         debugfs_remove(edp_dir);
993 edp_dir_err:
994         return -ENOMEM;
995 }
996
997 late_initcall(tegra_edp_debugfs_init);
998 #endif /* CONFIG_DEBUG_FS */