3e845076cf9c10561a3b62e14346dde24c2efa42
[linux-3.10.git] / arch / arm / mach-tegra / edp.c
1 /*
2  * arch/arm/mach-tegra/edp.c
3  *
4  * Copyright (C) 2011 NVIDIA, Inc.
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 10000000
35 #define A_TEMP_LUT_MAX 7
36 #define A_VOLTAGE_LUT_MAX 49
37
38 static struct tegra_edp_limits *edp_limits;
39 static int edp_limits_size;
40 static unsigned int regulator_cur;
41 /* Value to subtract from regulator current limit */
42 static unsigned int edp_reg_override_mA = 0;
43
44 static const unsigned int *system_edp_limits;
45
46 /*
47  * Temperature step size cannot be less than 4C because of hysteresis
48  * delta
49  * Code assumes different temperatures for the same speedo_id /
50  * regulator_cur are adjacent in the table, and higest regulator_cur
51  * comes first
52  */
53 static char __initdata tegra_edp_map[] = {
54         0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
55         0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
56         0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
57         0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
58         0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
59         0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
60         0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
61         0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
62         0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
63         0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
64         0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
65         0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
66         0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
67         0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
68         0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
69         0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
70         0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
71         0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
72         0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
73         0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
74         0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
75         0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
76         0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
77         0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
78         0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
79         0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
80         0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
81         0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
82         0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
83         0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
84         0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
85         0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
86         0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
87         0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
88         0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
89         0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
90         0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
91         0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
92         0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
93         0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
94         0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
95         0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
96         0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
97         0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
98         0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
99         0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
100         0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
101         0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
102         0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
103         0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
104         0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
105         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
106         0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
107         0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
108         0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
109         0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
110         0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
111         0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
112         0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
113         0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
114         0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
115         0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
116         0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
117         0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
118         0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
119         0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
120         0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
121         0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
122         0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
123         0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
124         0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
125         0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
126         0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
127         0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
128         0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
129         0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
130         0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
131         0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
132         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
133         0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
134         0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
135         0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
136         0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
137         0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
138         0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
139         0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
140         0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
141         0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
142         0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
143         0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
144         0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
145         0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
146         0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
147         0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
148         0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
149         0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
150         0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
151         0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
152         0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
153         0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
154         0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
155         0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
156         0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
157         0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
158         0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
159         0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
160         0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
161         0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
162         0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
163         0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
164         0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
165         0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
166         0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
167         0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
168         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
169         0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
170         0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
171         0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
172         0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
173         0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
174         0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
175         0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
176         0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
177         0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
178         0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
179         0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
180         0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
181         0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
182         0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
183         0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
184         0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
185         0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
186         0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
187         0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
188         0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
189         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
190         0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
191         0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
192         0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
193         0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
194         0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
195         0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
196         0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
197         0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
198         0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
199         0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
200         0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
201         0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
202         0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
203         0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
204         0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
205         0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
206         0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
207         0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
208         0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
209         0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
210         0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
211         0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
212         0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
213         0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
214         0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
215         0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
216         0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
217         0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
218         0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
219         0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
220         0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
221         0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
222         0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
223         0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
224         0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
225         0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
226         0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
227         0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
228         0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
229         0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
230         0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
231         0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
232         0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
233         0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
234         0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
235         0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
236         0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
237         0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
238         0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
239         0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
240         0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
241         0x5a, 0x46, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
242         0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
243         0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
244         0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
245         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
246         0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
247         0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
248         0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
249         0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
250         0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
251         0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
252         0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
253         0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
254         0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
255         0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
256         0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
257         0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
258         0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
259         0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
260         0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
261         0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
262         0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
263         0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
264         0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
265         0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
266         0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
267         0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
268         0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
269         0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
270         0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
271         0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
272         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
273         0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
274         0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
275         0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
276         0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
277         0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
278         0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
279         0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
280         0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
281         0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
282         0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
283         0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
284         0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
285         0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
286         0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
287         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
288         0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
289         0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
290         0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
291         0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
292         0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
293         0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
294 };
295
296
297 static struct system_edp_entry __initdata tegra_system_edp_map[] = {
298
299 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
300
301         {  1,  49, {130, 120, 120, 120} },
302         {  1,  44, {130, 120, 120, 110} },
303         {  1,  37, {130, 120, 110, 100} },
304         {  1,  35, {130, 120, 110,  90} },
305         {  1,  29, {130, 120, 100,  80} },
306         {  1,  27, {130, 120,  90,  80} },
307         {  1,  25, {130, 110,  80,  60} },
308         {  1,  21, {130, 100,  80,  40} },
309
310         {  4,  49, {130, 120, 120, 120} },
311         {  4,  44, {130, 120, 120, 110} },
312         {  4,  37, {130, 120, 110, 100} },
313         {  4,  35, {130, 120, 110,  90} },
314         {  4,  29, {130, 120, 100,  80} },
315         {  4,  27, {130, 120,  90,  80} },
316         {  4,  25, {130, 110,  80,  60} },
317         {  4,  21, {130, 100,  80,  40} },
318 };
319
320 /*
321  * "Safe entry" to be used when no match for speedo_id /
322  * regulator_cur is found; must be the last one
323  */
324 static struct tegra_edp_limits edp_default_limits[] = {
325         {85, {1000000, 1000000, 1000000, 1000000} },
326 };
327
328 /*
329  * Constants for EDP calculations
330  */
331
332 struct a_voltage_lut_t {
333         unsigned int voltage;
334         unsigned int a_voltage;
335 };
336
337 struct a_temp_lut_t {
338         unsigned int temp;
339         unsigned int a_temp;
340 };
341
342 /* TODO: This struct will get large for 13 speedo IDs... relocate. */
343 struct edp_constants_lut_t {
344         int cpu_speedo_id;
345
346         struct a_temp_lut_t a_temp_lut [A_TEMP_LUT_MAX];
347         unsigned int a_temp_lut_size;
348
349         struct a_voltage_lut_t a_voltage_lut [A_VOLTAGE_LUT_MAX];
350         unsigned int a_voltage_lut_size;
351
352         unsigned int a_cores_lut[NR_CPUS];
353 } edp_constants_lut[] = {
354         {
355                 .cpu_speedo_id = -1,
356                 .a_temp_lut = {
357                         {23, 23270},
358                         {45, 37559},
359                         {60, 52056},
360                         {70, 64712},
361                         {75, 72150},
362                         {85, 89690},
363                         {90, 100000}
364                 },
365                 .a_temp_lut_size = 7,
366                 .a_voltage_lut = {
367                         {700, 321},
368                         {713, 336},
369                         {725, 352},
370                         {738, 369},
371                         {750, 386},
372                         {763, 405},
373                         {775, 423},
374                         {788, 444},
375                         {800, 464},
376                         {813, 487},
377                         {825, 509},
378                         {838, 534},
379                         {850, 558},
380                         {863, 585},
381                         {875, 612},
382                         {888, 642},
383                         {900, 671},
384                         {913, 704},
385                         {925, 736},
386                         {938, 772},
387                         {950, 807},
388                         {963, 847},
389                         {975, 885},
390                         {988, 929},
391                         {1000, 971},
392                         {1013, 1019},
393                         {1025, 1066},
394                         {1038, 1119},
395                         {1050, 1170},
396                         {1063, 1228},
397                         {1075, 1284},
398                         {1088, 1348},
399                         {1100, 1410},
400                         {1113, 1480},
401                         {1125, 1548},
402                         {1138, 1625},
403                         {1150, 1699},
404                         {1163, 1784},
405                         {1175, 1865},
406                         {1188, 1958},
407                         {1200, 2048},
408                         {1213, 2150},
409                         {1225, 2248},
410                         {1238, 2360},
411                         {1250, 2468},
412                         {1263, 2591},
413                         {1275, 2709},
414                         {1288, 2844},
415                         {1300, 2974}
416                 },
417                 .a_voltage_lut_size = 49,
418                 .a_cores_lut = {
419                         3565,
420                         5710,
421                         7855,
422                         10000
423                 },
424         }
425 };
426
427 struct freq_voltage_lut_t {
428         unsigned int freq;
429         struct a_voltage_lut_t *a_voltage_lut;
430 } *freq_voltage_lut = 0;
431 unsigned int freq_voltage_lut_size;
432
433 /*
434  * Find the maximum frequency that results in dynamic and leakage current that
435  * is less than the regulator current limit.
436  */
437 unsigned int edp_calculate_maxf(unsigned int a_temp,
438                                 unsigned int a_cores,
439                                 unsigned int n_cores,
440                                 unsigned int iddq_mA)
441 {
442         unsigned int voltage_mV, a_voltage, leakage_mA, op_mA, freq_MHz;
443         unsigned int regulator_cur_effective = regulator_cur - edp_reg_override_mA;
444         int i;
445
446         for (i = freq_voltage_lut_size - 1; i  >= 0; i--) {
447                 freq_MHz = freq_voltage_lut[i].freq / 1000000;
448                 voltage_mV = freq_voltage_lut[i].a_voltage_lut->voltage;
449                 a_voltage = freq_voltage_lut[i].a_voltage_lut->a_voltage;
450
451                 leakage_mA = a_temp * a_voltage;
452                 /* a_voltage was pre-multiplied by 1000 */
453                 leakage_mA /= 1000;
454                 leakage_mA *= a_cores;
455                 /* a_temp was pre-multiplied by 100,000 */
456                 leakage_mA /= 100000;
457                 leakage_mA *= iddq_mA;
458                 /* a_cores was pre-multiplied by 10,000 */
459                 leakage_mA /= 10000;
460
461                 op_mA = 55 * voltage_mV * freq_MHz * n_cores;
462                 /* 55 was pre-multiplied by 100000 */
463                 op_mA /= 100000;
464
465                 /* TODO: Apply additional margin to total current calculated? */
466                 if ((leakage_mA + op_mA) <= regulator_cur_effective)
467                         return freq_MHz * 1000;
468         }
469         return 0;
470 }
471
472 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
473                                 unsigned int cpu_speedo_idx)
474 {
475         unsigned int i, j, freq, voltage_mV, a_voltage_lut_size;
476         struct a_voltage_lut_t *a_voltage_lut;
477
478         a_voltage_lut = edp_constants_lut[cpu_speedo_idx].a_voltage_lut;
479         a_voltage_lut_size = edp_constants_lut[cpu_speedo_idx].a_voltage_lut_size;
480
481         for (i = 0, j = 0, freq = clk_get_min_rate(clk_cpu_g);
482                  i < freq_voltage_lut_size;
483                  i++, freq += FREQ_STEP) {
484
485                 /* Predict voltages */
486                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
487                 if (voltage_mV < 0) {
488                         pr_err("%s: could not predict voltage for freqency %u, err %d\n",
489                                 __func__, freq, voltage_mV);
490                         return -EINVAL;
491                 }
492
493                 /* Look up voltage constant */
494                 for (;j < a_voltage_lut_size; j++) {
495                         if (voltage_mV <= a_voltage_lut[j].voltage) {
496                                 break;
497                         }
498                 }
499                 if (j == a_voltage_lut_size) {
500                         pr_err("%s: couldn't find voltage const for predicted voltage %d\n",
501                                 __func__, voltage_mV);
502                         return -EINVAL;
503                 }
504
505                 /* Cache frequency / voltage / voltage constant relationship */
506                 freq_voltage_lut[i].freq = freq;
507                 freq_voltage_lut[i].a_voltage_lut = &a_voltage_lut[j];
508         }
509
510         return 0;
511 }
512
513 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
514 {
515         int i;
516
517         for (i = 0; i < ARRAY_SIZE(edp_constants_lut); i++)
518                 if (cpu_speedo_id == edp_constants_lut[i].cpu_speedo_id) {
519                         *cpu_speedo_idx = i;
520                         return 0;
521                 }
522
523         pr_err("%s: couldn't find cpu speedo id in freq/voltage LUT\n", __func__);
524         return -EINVAL;
525 }
526
527 int init_cpu_edp_limits_calculated(int cpu_speedo_id)
528 {
529         unsigned int temp_idx, n_cores_idx, cpu_speedo_idx;
530         unsigned int cpu_g_minf, cpu_g_maxf;
531         unsigned int *a_cores_lut, a_temp_lut_size, iddq_mA;
532         struct a_temp_lut_t *a_temp_lut;
533         struct tegra_edp_limits *edp_calculated_limits;
534         int ret, edp_calculated_limits_size;
535         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
536
537         /* Determine all inputs to EDP formula */
538         tegra_fuse_get_cpu_iddq_mA(&iddq_mA);
539
540         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
541         if (ret)
542                 return ret;
543
544         a_temp_lut = edp_constants_lut[cpu_speedo_idx].a_temp_lut;
545         a_temp_lut_size = edp_constants_lut[cpu_speedo_idx].a_temp_lut_size;
546
547         a_cores_lut = edp_constants_lut[cpu_speedo_idx].a_cores_lut;
548
549         edp_calculated_limits =
550                 kmalloc(sizeof(struct tegra_edp_limits) * a_temp_lut_size, GFP_KERNEL);
551         BUG_ON(!edp_calculated_limits);
552         edp_calculated_limits_size = a_temp_lut_size;
553
554         cpu_g_minf = clk_get_min_rate(clk_cpu_g);
555         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
556         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
557         freq_voltage_lut =
558                 kmalloc(sizeof(struct freq_voltage_lut_t) * freq_voltage_lut_size,
559                 GFP_KERNEL);
560         if (!freq_voltage_lut) {
561                 pr_err("%s: failed to allocate mem for freq/voltage LUT\n", __func__);
562                 return -ENOMEM;
563         }
564
565         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
566         if (ret) {
567                 kfree(freq_voltage_lut);
568                 return ret;
569         }
570
571         /* Calculate EDP table */
572         for (temp_idx = 0; temp_idx < a_temp_lut_size; temp_idx++) {
573                 edp_calculated_limits[temp_idx].temperature = a_temp_lut[temp_idx].temp;
574
575                 for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++)
576                         edp_calculated_limits[temp_idx].freq_limits[n_cores_idx] =
577                                 edp_calculate_maxf(a_temp_lut[temp_idx].a_temp,
578                                                 a_cores_lut[n_cores_idx],
579                                                 n_cores_idx + 1,
580                                                 iddq_mA);
581         }
582
583         /*
584          * If this is an EDP table update, need to overwrite old table.
585          * The old table's address must remain valid.
586          */
587         if (edp_limits != edp_default_limits) {
588                 memcpy(edp_limits, edp_calculated_limits,
589                         sizeof(struct tegra_edp_limits) * edp_calculated_limits_size);
590                 kfree(edp_calculated_limits);
591         }
592         else {
593                 edp_limits = edp_calculated_limits;
594                 edp_limits_size = edp_calculated_limits_size;
595         }
596
597         kfree(freq_voltage_lut);
598         return 0;
599 }
600
601 int init_cpu_edp_limits_lookup(int cpu_speedo_id)
602 {
603         int i, j;
604         struct tegra_edp_limits *e;
605         struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
606         int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
607
608         for (i = 0; i < tsize; i++) {
609                 if (t[i].speedo_id == cpu_speedo_id &&
610                     t[i].regulator_100mA <= regulator_cur / 100)
611                         break;
612         }
613
614         /* No entry found in tegra_edp_map */
615         if (i >= tsize)
616                 return -EINVAL;
617
618         /* Find all rows for this entry */
619         for (j = i + 1; j < tsize; j++) {
620                 if (t[i].speedo_id != t[j].speedo_id ||
621                     t[i].regulator_100mA != t[j].regulator_100mA)
622                         break;
623         }
624
625         edp_limits_size = j - i;
626         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
627                     GFP_KERNEL);
628         BUG_ON(!e);
629
630         for (j = 0; j < edp_limits_size; j++) {
631                 e[j].temperature = (int)t[i+j].temperature;
632                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0] * 10000;
633                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1] * 10000;
634                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2] * 10000;
635                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3] * 10000;
636         }
637
638         if (edp_limits != edp_default_limits)
639                 kfree(edp_limits);
640
641         edp_limits = e;
642         return 0;
643 }
644
645 /*
646  * Specify regulator current in mA, e.g. 5000mA
647  * Use 0 for default
648  */
649 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
650 {
651         int cpu_speedo_id = tegra_cpu_speedo_id();
652         if (!regulator_mA) {
653                 edp_limits = edp_default_limits;
654                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
655                 return;
656         }
657         regulator_cur = regulator_mA;
658
659         if (!init_cpu_edp_limits_lookup(cpu_speedo_id))
660                 return;
661
662         if (!init_cpu_edp_limits_calculated(cpu_speedo_id))
663                 return;
664
665         edp_limits = edp_default_limits;
666         edp_limits_size = ARRAY_SIZE(edp_default_limits);
667 }
668
669 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
670 {
671         int cpu_speedo_id = tegra_cpu_speedo_id();
672         int i;
673         unsigned int *e;
674         struct system_edp_entry *t =
675                 (struct system_edp_entry *)tegra_system_edp_map;
676         int tsize = sizeof(tegra_system_edp_map) /
677                 sizeof(struct system_edp_entry);
678
679         if (!power_limit_mW) {
680                 e = NULL;
681                 goto out;
682         }
683
684         for (i = 0; i < tsize; i++)
685                 if (t[i].speedo_id == cpu_speedo_id)
686                         break;
687
688         if (i >= tsize) {
689                 e = NULL;
690                 goto out;
691         }
692
693         do {
694                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
695                         break;
696                 i++;
697         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
698
699         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
700                 i--; /* No low enough entry in the table, use best possible */
701
702         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
703         BUG_ON(!e);
704
705         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
706         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
707         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
708         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
709
710 out:
711         kfree(system_edp_limits);
712
713         system_edp_limits = e;
714 }
715
716
717 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
718 {
719         *limits = edp_limits;
720         *size = edp_limits_size;
721 }
722
723 void tegra_get_system_edp_limits(const unsigned int **limits)
724 {
725         *limits = system_edp_limits;
726 }
727
728 #ifdef CONFIG_EDP_FRAMEWORK
729
730 static struct edp_manager battery_edp_manager = {
731         .name = "battery"
732 };
733
734 void __init tegra_battery_edp_init(unsigned int cap)
735 {
736         struct edp_governor *g;
737         int r;
738
739         battery_edp_manager.imax = cap;
740         r = edp_register_manager(&battery_edp_manager);
741         if (r)
742                 goto err_ret;
743
744         /* start with priority governor */
745         g = edp_get_governor("priority");
746         if (!g) {
747                 r = -EFAULT;
748                 goto err_ret;
749         }
750
751         r = edp_set_governor(&battery_edp_manager, g);
752         if (r)
753                 goto err_ret;
754
755         return;
756
757 err_ret:
758         pr_err("Battery EDP init failed with error %d\n", r);
759         WARN_ON(1);
760 }
761
762 #endif
763
764 #ifdef CONFIG_DEBUG_FS
765
766 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
767 {
768         seq_printf(s, "%u\n", tegra_get_edp_limit());
769         return 0;
770 }
771
772 static int edp_debugfs_show(struct seq_file *s, void *data)
773 {
774         int i;
775
776         seq_printf(s, "-- CPU %sEDP table (%umA) --\n",
777                    edp_limits == edp_default_limits ? "default " : "",
778                    regulator_cur);
779         for (i = 0; i < edp_limits_size; i++) {
780                 seq_printf(s, "%4dC: %10u %10u %10u %10u\n",
781                            edp_limits[i].temperature,
782                            edp_limits[i].freq_limits[0],
783                            edp_limits[i].freq_limits[1],
784                            edp_limits[i].freq_limits[2],
785                            edp_limits[i].freq_limits[3]);
786         }
787
788         if (system_edp_limits) {
789                 seq_printf(s, "\n-- System EDP table --\n");
790                 seq_printf(s, "%10u %10u %10u %10u\n",
791                            system_edp_limits[0],
792                            system_edp_limits[1],
793                            system_edp_limits[2],
794                            system_edp_limits[3]);
795         }
796
797         return 0;
798 }
799
800 static int edp_reg_override_show(struct seq_file *s, void *data)
801 {
802         seq_printf(s,
803                 "Regulator limit override: %u mA. Effective regulator limit: %u mA\n",
804                 edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
805         return 0;
806 }
807
808 static int edp_reg_override_write(struct file *file,
809         const char __user *userbuf, size_t count, loff_t *ppos)
810 {
811         char buf[32], *end;
812         unsigned int edp_reg_override_mA_temp;
813         int cpu_speedo_id;
814
815         if (sizeof(buf) <= count)
816                 goto override_err;
817
818         if (copy_from_user(buf, userbuf, count))
819                 goto override_err;
820
821         /* terminate buffer and trim - white spaces may be appended
822          *  at the end when invoked from shell command line */
823         buf[count]='\0';
824         strim(buf);
825
826         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
827         if (*end != '\0')
828                 goto override_err;
829
830         if (edp_reg_override_mA_temp >= regulator_cur)
831                 goto override_err;
832
833         edp_reg_override_mA = edp_reg_override_mA_temp;
834         cpu_speedo_id = tegra_cpu_speedo_id();
835         if(init_cpu_edp_limits_calculated(cpu_speedo_id))
836                 goto override_err;
837
838         if (tegra_cpu_set_speed_cap(NULL))
839                 goto override_err;
840
841         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
842                         " %u mA\n", regulator_cur - edp_reg_override_mA);
843
844         return count;
845
846 override_err:
847         pr_err("Failed to reinitialized VDD_CPU EDP table with override \"%s\"\n"
848                 ,buf);
849
850         return -EINVAL;
851
852 }
853
854 static int edp_debugfs_open(struct inode *inode, struct file *file)
855 {
856         return single_open(file, edp_debugfs_show, inode->i_private);
857 }
858
859 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
860 {
861         return single_open(file, edp_limit_debugfs_show, inode->i_private);
862 }
863
864 static int edp_reg_override_open(struct inode *inode, struct file *file)
865 {
866         return single_open(file, edp_reg_override_show, inode->i_private);
867 }
868
869 static const struct file_operations edp_debugfs_fops = {
870         .open           = edp_debugfs_open,
871         .read           = seq_read,
872         .llseek         = seq_lseek,
873         .release        = single_release,
874 };
875
876 static const struct file_operations edp_limit_debugfs_fops = {
877         .open           = edp_limit_debugfs_open,
878         .read           = seq_read,
879         .llseek         = seq_lseek,
880         .release        = single_release,
881 };
882
883 static const struct file_operations edp_reg_override_debugfs_fops = {
884         .open           = edp_reg_override_open,
885         .read           = seq_read,
886         .write          = edp_reg_override_write,
887         .llseek         = seq_lseek,
888         .release        = single_release,
889 };
890
891 static int __init tegra_edp_debugfs_init(void)
892 {
893         struct dentry *d_edp;
894         struct dentry *d_edp_limit;
895         struct dentry *d_edp_reg_override;
896         struct dentry *edp_dir;
897         struct dentry *vdd_cpu_dir;
898
899         edp_dir = debugfs_create_dir("edp", NULL);
900
901         if (!edp_dir)
902                 goto edp_dir_err;
903
904         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
905
906         if (!vdd_cpu_dir)
907                 goto vdd_cpu_dir_err;
908
909         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
910                                 &edp_debugfs_fops);
911
912         if (!d_edp)
913                 goto edp_err;
914
915         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
916                                 NULL, &edp_limit_debugfs_fops);
917
918         if (!d_edp_limit)
919                 goto edp_limit_err;
920
921         d_edp_reg_override = debugfs_create_file("edp_reg_override",
922                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
923                                 &edp_reg_override_debugfs_fops);
924
925         if (!d_edp_reg_override)
926                 goto edp_reg_override_err;
927
928         return 0;
929
930 edp_reg_override_err:
931         debugfs_remove(d_edp_limit);
932 edp_limit_err:
933         debugfs_remove(d_edp);
934 edp_err:
935         debugfs_remove(vdd_cpu_dir);
936 vdd_cpu_dir_err:
937         debugfs_remove(edp_dir);
938 edp_dir_err:
939         return -ENOMEM;
940 }
941
942 late_initcall(tegra_edp_debugfs_init);
943 #endif /* CONFIG_DEBUG_FS */