[IMPROVE] Driver: implement kernel -> user connect
[kernel/swap-modules.git] / energy / debugfs_energy.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  energy/debugfs_energy.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
22  *
23  */
24
25
26 #include <linux/fs.h>
27 #include <linux/module.h>
28 #include <linux/debugfs.h>
29 #include <linux/math64.h>
30 #include <driver/swap_debugfs.h>
31 #include "energy.h"
32 #include "rational_debugfs.h"
33 #include "lcd/lcd_debugfs.h"
34
35
36 /* CPU running */
37 static DEFINE_RATIONAL(cpu_running_coef);
38
39 static u64 cpu_system(void)
40 {
41         u64 time = get_parameter_energy(PE_TIME_SYSTEM);
42
43         return div_u64(time * cpu_running_coef.num, cpu_running_coef.denom);
44 }
45
46 static u64 cpu_apps(void)
47 {
48         u64 time = get_parameter_energy(PE_TIME_APPS);
49
50         return div_u64(time * cpu_running_coef.num, cpu_running_coef.denom);
51 }
52
53
54 /* CPU idle */
55 static DEFINE_RATIONAL(cpu_idle_coef);
56
57 static u64 cpu_idle_system(void)
58 {
59         u64 time = get_parameter_energy(PE_TIME_IDLE);
60
61         return div_u64(time * cpu_idle_coef.num, cpu_idle_coef.denom);
62 }
63
64
65 /* flash read */
66 static DEFINE_RATIONAL(fr_coef);
67
68 static u64 fr_system(void)
69 {
70         u64 byte = get_parameter_energy(PE_READ_SYSTEM);
71
72         return div_u64(byte * fr_coef.num, fr_coef.denom);
73 }
74
75 static u64 fr_apps(void)
76 {
77         u64 byte = get_parameter_energy(PE_READ_APPS);
78
79         return div_u64(byte * fr_coef.num, fr_coef.denom);
80 }
81
82
83 /* flash write */
84 static DEFINE_RATIONAL(fw_coef);
85
86 static u64 fw_system(void)
87 {
88         u64 byte = get_parameter_energy(PE_WRITE_SYSTEM);
89
90         return div_u64(byte * fw_coef.num, fw_coef.denom);
91 }
92
93 static u64 fw_apps(void)
94 {
95         u64 byte = get_parameter_energy(PE_WRITE_APPS);
96
97         return div_u64(byte * fw_coef.num, fw_coef.denom);
98 }
99
100
101
102
103
104 /* ============================================================================
105  * ===                             PARAMETERS                               ===
106  * ============================================================================
107  */
108 static int get_func_u64(void *data, u64 *val)
109 {
110         u64 (*func)(void) = data;
111         *val = func();
112         return 0;
113 }
114
115 DEFINE_SIMPLE_ATTRIBUTE(fops_get_u64, get_func_u64, NULL, "%llu\n");
116
117
118 struct param_data {
119         char *name;
120         struct rational *coef;
121         u64 (*system)(void);
122         u64 (*apps)(void);
123 };
124
125 static struct dentry *create_parameter(struct dentry *parent,
126                                        struct param_data *param)
127 {
128         struct dentry *name, *system, *apps = NULL;
129
130         name = debugfs_create_dir(param->name, parent);
131         if (name == NULL)
132                 return NULL;
133
134         system = debugfs_create_file("system", 0600, name, param->system,
135                                      &fops_get_u64);
136         if (system == NULL)
137                 goto rm_name;
138
139         if (param->apps) {
140                 apps = debugfs_create_file("apps", 0600, name, param->apps,
141                                            &fops_get_u64);
142                 if (apps == NULL)
143                         goto rm_system;
144         }
145
146         if (create_rational_files(name, param->coef,
147                                   "numerator", "denominator"))
148                 goto rm_apps;
149
150         return name;
151
152 rm_apps:
153         if (param->apps)
154                 debugfs_remove(apps);
155 rm_system:
156         debugfs_remove(system);
157 rm_name:
158         debugfs_remove(name);
159
160         return NULL;
161 }
162
163 struct param_data parameters[] = {
164         {
165                 .name = "cpu_running",
166                 .coef = &cpu_running_coef,
167                 .system = cpu_system,
168                 .apps = cpu_apps
169         },
170         {
171                 .name = "cpu_idle",
172                 .coef = &cpu_idle_coef,
173                 .system = cpu_idle_system,
174                 .apps = NULL
175         },
176         {
177                 .name = "flash_read",
178                 .coef = &fr_coef,
179                 .system = fr_system,
180                 .apps = fr_apps
181         },
182         {
183                 .name = "flash_write",
184                 .coef = &fw_coef,
185                 .system = fw_system,
186                 .apps = fw_apps
187         }
188 };
189
190 enum {
191         parameters_cnt = sizeof(parameters) / sizeof(struct param_data)
192 };
193
194
195
196
197
198 /* ============================================================================
199  * ===                              INIT/EXIT                               ===
200  * ============================================================================
201  */
202 static struct dentry *energy_dir = NULL;
203
204 void exit_debugfs_energy(void)
205 {
206         exit_lcd_debugfs();
207         if (energy_dir)
208                 debugfs_remove_recursive(energy_dir);
209
210         energy_dir = NULL;
211 }
212
213 int init_debugfs_energy(void)
214 {
215         int i, ret = -ENOMEM;
216         struct dentry *swap_dir, *dentry;
217
218         swap_dir = get_swap_debugfs_dir();
219         if (swap_dir == NULL)
220                 return -ENOENT;
221
222         energy_dir = debugfs_create_dir("energy", swap_dir);
223         if (energy_dir == NULL)
224                 return -ENOMEM;
225
226         for (i = 0; i < parameters_cnt; ++i) {
227                 dentry = create_parameter(energy_dir, &parameters[i]);
228                 if (dentry == NULL)
229                         goto fail;
230         }
231
232         ret = init_lcd_debugfs(energy_dir);
233         if (ret)
234                 goto fail;
235
236         return 0;
237
238 fail:
239         exit_debugfs_energy();
240         return ret;
241 }