ARM: tegra: restructuring battery EDP init code
[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_vdd_cpu_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 tegra_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 /* Constants for EDP calculations */
328 static int temperatures[] = { 23, 40, 50, 60, 70, 75, 80, 85, 90, 95 };
329 static struct tegra_edp_cpu_leakage_params leakage_params[] = {
330         {
331                 .cpu_speedo_id      = 0, /* SKU 0 */
332                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
333                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
334                 .leakage_consts_ijk = {
335                          /* i = 0 */
336                          { {  -42746668,   -5458429,   164998,  -1711, },
337                            {  178262421,   13375684,  -411791,   4590, },
338                            { -228866784,  -10482993,   331248,  -4062, },
339                            {   94301550,    2618719,   -85983,   1193, },
340                          },
341                          /* i = 1 */
342                          { { -256611791,   49677413, -1655785,  14917, },
343                            {  584675433, -132620939,  4541560, -41812, },
344                            { -398106336,  115987156, -4102328,  38737, },
345                            {   68897184,  -33030745,  1217839, -11801, },
346                          },
347                          /* i = 2 */
348                          { {  186324676,  -36019083,  1177969, -10669, },
349                            { -439237936,   98429131, -3276444,  30301, },
350                            {  315060898,  -88635036,  3004777, -28474, },
351                            {  -60854399,   26267188,  -907121,   8844, },
352                          },
353                          /* i = 3 */
354                          { {  -35432997,    6154621,  -202200,   1830, },
355                            {   87402153,  -16908683,   565152,  -5220, },
356                            {  -67775314,   15326770,  -521221,   4927, },
357                            {   15618709,   -4576116,   158401,  -1538, },
358                          },
359                  },
360         },
361 };
362
363 static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
364 static unsigned int freq_voltage_lut_size;
365
366 static inline s64 edp_pow(s64 val, int pwr)
367 {
368         s64 retval = 1;
369
370         while (pwr) {
371                 if (pwr & 1)
372                         retval *= val;
373                 pwr >>= 1;
374                 if (pwr)
375                         val *= val;
376         }
377
378         return retval;
379 }
380
381 /*
382  * Find the maximum frequency that results in dynamic and leakage current that
383  * is less than the regulator current limit.
384  */
385 unsigned int edp_calculate_maxf(struct tegra_edp_cpu_leakage_params *params,
386                                 int temp_C,
387                                 int iddq_mA,
388                                 int n_cores_idx)
389 {
390         unsigned int voltage_mV, freq_MHz;
391         unsigned int cur_effective = regulator_cur - edp_reg_override_mA;
392         int f, i, j, k;
393         s64 leakage_mA, dyn_mA, leakage_calc_step;
394
395         for (f = freq_voltage_lut_size - 1; f >= 0; f--) {
396                 freq_MHz = freq_voltage_lut[f].freq / 1000000;
397                 voltage_mV = freq_voltage_lut[f].voltage_mV;
398
399                 /* Calculate leakage current */
400                 leakage_mA = 0;
401                 for (i = 0; i <= 3; i++) {
402                         for (j = 0; j <= 3; j++) {
403                                 for (k = 0; k <= 3; k++) {
404                                         leakage_calc_step =
405                                                 params->leakage_consts_ijk
406                                                 [i][j][k] * edp_pow(iddq_mA, i);
407                                         /* Convert (mA)^i to (A)^i */
408                                         leakage_calc_step =
409                                                 div64_s64(leakage_calc_step,
410                                                           edp_pow(1000, i));
411                                         leakage_calc_step *=
412                                                 edp_pow(voltage_mV, j);
413                                         /* Convert (mV)^i to (V)^i */
414                                         leakage_calc_step =
415                                                 div64_s64(leakage_calc_step,
416                                                           edp_pow(1000, j));
417                                         leakage_calc_step *=
418                                                 edp_pow(temp_C, k);
419                                         /* leakage_consts_ijk was X 100,000 */
420                                         leakage_calc_step =
421                                                 div64_s64(leakage_calc_step,
422                                                           100000);
423                                         leakage_mA += leakage_calc_step;
424                                 }
425                         }
426                 }
427                 leakage_mA *= params->leakage_consts_n[n_cores_idx];
428                 /* leakage_const_n was pre-multiplied by 1,000,000 */
429                 leakage_mA = div64_s64(leakage_mA, 1000000);
430
431                 /* Calculate dynamic current */
432                 dyn_mA = voltage_mV * freq_MHz;
433                 /* Convert mV to V */
434                 dyn_mA = div64_s64(dyn_mA, 1000);
435                 dyn_mA *= params->dyn_consts_n[n_cores_idx];
436                 /* dyn_const_n was pre-multiplied by 1,000,000 */
437                 dyn_mA = div64_s64(dyn_mA, 1000000);
438
439                 if ((leakage_mA + dyn_mA) <= cur_effective)
440                         return freq_MHz * 1000;
441         }
442         return 0;
443 }
444
445 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
446                                 unsigned int cpu_speedo_idx)
447 {
448         unsigned int i, j, freq;
449         int voltage_mV;
450
451         for (i = 0, j = 0, freq = 0;
452                  i < freq_voltage_lut_size;
453                  i++, freq += FREQ_STEP) {
454
455                 /* Predict voltages */
456                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
457                 if (voltage_mV < 0) {
458                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
459                                __func__, freq, voltage_mV);
460                         return -EINVAL;
461                 }
462
463                 /* Cache frequency / voltage / voltage constant relationship */
464                 freq_voltage_lut[i].freq = freq;
465                 freq_voltage_lut[i].voltage_mV = voltage_mV;
466         }
467         return 0;
468 }
469
470 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
471 {
472         int i;
473
474         for (i = 0; i < ARRAY_SIZE(leakage_params); i++)
475                 if (cpu_speedo_id == leakage_params[i].cpu_speedo_id) {
476                         *cpu_speedo_idx = i;
477                         return 0;
478                 }
479
480         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
481                __func__, cpu_speedo_id);
482         return -EINVAL;
483 }
484
485 static int init_cpu_edp_limits_calculated(void)
486 {
487         unsigned int temp_idx, n_cores_idx;
488         unsigned int cpu_g_minf, cpu_g_maxf;
489         unsigned int iddq_mA;
490         unsigned int cpu_speedo_idx;
491         struct tegra_edp_limits *edp_calculated_limits;
492         struct tegra_edp_cpu_leakage_params *params;
493         int ret;
494         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
495         int cpu_speedo_id = tegra_cpu_speedo_id();
496
497         /* Determine all inputs to EDP formula */
498         iddq_mA = tegra_get_cpu_iddq_value();
499         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
500         if (ret)
501                 return ret;
502
503         params = &leakage_params[cpu_speedo_idx];
504
505         edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
506                                         * ARRAY_SIZE(temperatures), GFP_KERNEL);
507         BUG_ON(!edp_calculated_limits);
508
509         cpu_g_minf = 0;
510         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
511         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
512         freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
513                                    * freq_voltage_lut_size, GFP_KERNEL);
514         if (!freq_voltage_lut) {
515                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
516                 return -ENOMEM;
517         }
518
519         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
520         if (ret) {
521                 kfree(freq_voltage_lut);
522                 return ret;
523         }
524
525         /* Calculate EDP table */
526         for (temp_idx = 0; temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
527                 edp_calculated_limits[temp_idx].
528                         temperature = temperatures[temp_idx];
529                 for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++)
530                         edp_calculated_limits[temp_idx].
531                                 freq_limits[n_cores_idx] =
532                                 edp_calculate_maxf(params,
533                                                    temperatures[temp_idx],
534                                                    iddq_mA,
535                                                    n_cores_idx);
536         }
537
538         /*
539          * If this is an EDP table update, need to overwrite old table.
540          * The old table's address must remain valid.
541          */
542         if (edp_limits != edp_default_limits) {
543                 memcpy(edp_limits, edp_calculated_limits,
544                        sizeof(struct tegra_edp_limits)
545                        * ARRAY_SIZE(temperatures));
546                 kfree(edp_calculated_limits);
547         }
548         else {
549                 edp_limits = edp_calculated_limits;
550                 edp_limits_size = ARRAY_SIZE(temperatures);
551         }
552
553         kfree(freq_voltage_lut);
554         return 0;
555 }
556
557 static int __init init_cpu_edp_limits_lookup(void)
558 {
559         int i, j;
560         struct tegra_edp_limits *e;
561         struct tegra_edp_vdd_cpu_entry *t;
562         int tsize;
563         int cpu_speedo_id = tegra_cpu_speedo_id();
564
565         t = (struct tegra_edp_vdd_cpu_entry *)tegra_edp_vdd_cpu_map;
566         tsize = sizeof(tegra_edp_vdd_cpu_map)
567                 / sizeof(struct tegra_edp_vdd_cpu_entry);
568
569         for (i = 0; i < tsize; i++) {
570                 if (t[i].speedo_id == cpu_speedo_id &&
571                     t[i].regulator_100mA <= regulator_cur / 100)
572                         break;
573         }
574
575         /* No entry found in tegra_edp_vdd_cpu_map */
576         if (i >= tsize)
577                 return -EINVAL;
578
579         /* Find all rows for this entry */
580         for (j = i + 1; j < tsize; j++) {
581                 if (t[i].speedo_id != t[j].speedo_id ||
582                     t[i].regulator_100mA != t[j].regulator_100mA)
583                         break;
584         }
585
586         edp_limits_size = j - i;
587         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
588                     GFP_KERNEL);
589         BUG_ON(!e);
590
591         for (j = 0; j < edp_limits_size; j++) {
592                 e[j].temperature = (int)t[i+j].temperature;
593                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
594                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
595                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
596                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
597         }
598
599         if (edp_limits != edp_default_limits)
600                 kfree(edp_limits);
601
602         edp_limits = e;
603         return 0;
604 }
605
606 void tegra_recalculate_cpu_edp_limits(void)
607 {
608         if (tegra_chip_id == TEGRA11X)
609                 init_cpu_edp_limits_calculated();
610 }
611
612 /*
613  * Specify regulator current in mA, e.g. 5000mA
614  * Use 0 for default
615  */
616 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
617 {
618         if (!regulator_mA) {
619                 edp_limits = edp_default_limits;
620                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
621                 return;
622         }
623         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
624
625         switch (tegra_chip_id) {
626         case TEGRA30:
627                 if (init_cpu_edp_limits_lookup() == 0)
628                         return;
629                 break;
630         case TEGRA11X:
631                 if (init_cpu_edp_limits_calculated() == 0)
632                         return;
633                 break;
634         case TEGRA20:
635         default:
636                 BUG();
637                 break;
638         }
639
640         edp_limits = edp_default_limits;
641         edp_limits_size = ARRAY_SIZE(edp_default_limits);
642 }
643
644 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
645 {
646         int cpu_speedo_id = tegra_cpu_speedo_id();
647         int i;
648         unsigned int *e;
649         struct tegra_system_edp_entry *t = tegra_system_edp_map;
650         int tsize = ARRAY_SIZE(tegra_system_edp_map);
651
652         if (!power_limit_mW) {
653                 e = NULL;
654                 goto out;
655         }
656
657         for (i = 0; i < tsize; i++)
658                 if (t[i].speedo_id == cpu_speedo_id)
659                         break;
660
661         if (i >= tsize) {
662                 e = NULL;
663                 goto out;
664         }
665
666         do {
667                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
668                         break;
669                 i++;
670         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
671
672         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
673                 i--; /* No low enough entry in the table, use best possible */
674
675         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
676         BUG_ON(!e);
677
678         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
679         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
680         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
681         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
682
683 out:
684         kfree(system_edp_limits);
685
686         system_edp_limits = e;
687 }
688
689
690 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
691 {
692         *limits = edp_limits;
693         *size = edp_limits_size;
694 }
695
696 void tegra_get_system_edp_limits(const unsigned int **limits)
697 {
698         *limits = system_edp_limits;
699 }
700
701 #ifdef CONFIG_DEBUG_FS
702
703 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
704 {
705         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
706         return 0;
707 }
708
709 static int edp_debugfs_show(struct seq_file *s, void *data)
710 {
711         int i, th_idx;
712
713         tegra_get_edp_limit(&th_idx);
714         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
715                    edp_limits == edp_default_limits ? "default " : "",
716                    regulator_cur - edp_reg_override_mA,
717                    regulator_cur, edp_reg_override_mA);
718         seq_printf(s, "%6s %10s %10s %10s %10s\n",
719                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
720         for (i = 0; i < edp_limits_size; i++) {
721                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
722                            i == th_idx ? '>' : ' ',
723                            edp_limits[i].temperature,
724                            edp_limits[i].freq_limits[0],
725                            edp_limits[i].freq_limits[1],
726                            edp_limits[i].freq_limits[2],
727                            edp_limits[i].freq_limits[3]);
728         }
729
730         if (system_edp_limits) {
731                 seq_printf(s, "\n-- System EDP table --\n");
732                 seq_printf(s, "%10u %10u %10u %10u\n",
733                            system_edp_limits[0],
734                            system_edp_limits[1],
735                            system_edp_limits[2],
736                            system_edp_limits[3]);
737         }
738
739         return 0;
740 }
741
742 static int edp_reg_override_show(struct seq_file *s, void *data)
743 {
744         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
745                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
746         return 0;
747 }
748
749 static int edp_reg_override_write(struct file *file,
750         const char __user *userbuf, size_t count, loff_t *ppos)
751 {
752         char buf[32], *end;
753         unsigned int edp_reg_override_mA_temp;
754         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
755
756         if (sizeof(buf) <= count)
757                 goto override_err;
758
759         if (copy_from_user(buf, userbuf, count))
760                 goto override_err;
761
762         /* terminate buffer and trim - white spaces may be appended
763          *  at the end when invoked from shell command line */
764         buf[count]='\0';
765         strim(buf);
766
767         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
768         if (*end != '\0')
769                 goto override_err;
770
771         if (edp_reg_override_mA_temp >= regulator_cur)
772                 goto override_err;
773
774         if (edp_reg_override_mA == edp_reg_override_mA_temp)
775                 return count;
776
777         edp_reg_override_mA = edp_reg_override_mA_temp;
778         if (init_cpu_edp_limits_calculated()) {
779                 /* Revert to previous override value if new value fails */
780                 edp_reg_override_mA = edp_reg_override_mA_prev;
781                 goto override_err;
782         }
783
784         if (tegra_cpu_set_speed_cap(NULL)) {
785                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
786                 goto override_out;
787         }
788
789         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
790                         " %u mA\n", regulator_cur - edp_reg_override_mA);
791
792         return count;
793
794 override_err:
795         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
796                buf);
797 override_out:
798         return -EINVAL;
799 }
800
801 static int edp_debugfs_open(struct inode *inode, struct file *file)
802 {
803         return single_open(file, edp_debugfs_show, inode->i_private);
804 }
805
806 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
807 {
808         return single_open(file, edp_limit_debugfs_show, inode->i_private);
809 }
810
811 static int edp_reg_override_open(struct inode *inode, struct file *file)
812 {
813         return single_open(file, edp_reg_override_show, inode->i_private);
814 }
815
816 static const struct file_operations edp_debugfs_fops = {
817         .open           = edp_debugfs_open,
818         .read           = seq_read,
819         .llseek         = seq_lseek,
820         .release        = single_release,
821 };
822
823 static const struct file_operations edp_limit_debugfs_fops = {
824         .open           = edp_limit_debugfs_open,
825         .read           = seq_read,
826         .llseek         = seq_lseek,
827         .release        = single_release,
828 };
829
830 static const struct file_operations edp_reg_override_debugfs_fops = {
831         .open           = edp_reg_override_open,
832         .read           = seq_read,
833         .write          = edp_reg_override_write,
834         .llseek         = seq_lseek,
835         .release        = single_release,
836 };
837
838 static int __init tegra_edp_debugfs_init(void)
839 {
840         struct dentry *d_edp;
841         struct dentry *d_edp_limit;
842         struct dentry *d_edp_reg_override;
843         struct dentry *edp_dir;
844         struct dentry *vdd_cpu_dir;
845
846         edp_dir = debugfs_create_dir("edp", NULL);
847
848         if (!edp_dir)
849                 goto edp_dir_err;
850
851         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
852
853         if (!vdd_cpu_dir)
854                 goto vdd_cpu_dir_err;
855
856         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
857                                 &edp_debugfs_fops);
858
859         if (!d_edp)
860                 goto edp_err;
861
862         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
863                                 NULL, &edp_limit_debugfs_fops);
864
865         if (!d_edp_limit)
866                 goto edp_limit_err;
867
868         d_edp_reg_override = debugfs_create_file("edp_reg_override",
869                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
870                                 &edp_reg_override_debugfs_fops);
871
872         if (!d_edp_reg_override)
873                 goto edp_reg_override_err;
874
875         if (tegra_core_edp_debugfs_init(edp_dir))
876                 goto edp_reg_override_err;
877
878         return 0;
879
880 edp_reg_override_err:
881         debugfs_remove(d_edp_limit);
882 edp_limit_err:
883         debugfs_remove(d_edp);
884 edp_err:
885         debugfs_remove(vdd_cpu_dir);
886 vdd_cpu_dir_err:
887         debugfs_remove(edp_dir);
888 edp_dir_err:
889         return -ENOMEM;
890 }
891
892 late_initcall(tegra_edp_debugfs_init);
893 #endif /* CONFIG_DEBUG_FS */