Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[linux-2.6] / drivers / acpi / processor_throttling.c
1 /*
2  * processor_throttling.c - Throttling submodule of the ACPI processor driver
3  *
4  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6  *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
7  *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
8  *                      - Added processor hotplug support
9  *
10  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or (at
15  *  your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful, but
18  *  WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  *  General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License along
23  *  with this program; if not, write to the Free Software Foundation, Inc.,
24  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25  *
26  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27  */
28
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/cpufreq.h>
33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h>
35
36 #include <asm/io.h>
37 #include <asm/uaccess.h>
38
39 #include <acpi/acpi_bus.h>
40 #include <acpi/processor.h>
41
42 #define ACPI_PROCESSOR_COMPONENT        0x01000000
43 #define ACPI_PROCESSOR_CLASS            "processor"
44 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
45 ACPI_MODULE_NAME("processor_throttling");
46
47 /* --------------------------------------------------------------------------
48                               Throttling Control
49    -------------------------------------------------------------------------- */
50 static int acpi_processor_get_throttling(struct acpi_processor *pr)
51 {
52         int state = 0;
53         u32 value = 0;
54         u32 duty_mask = 0;
55         u32 duty_value = 0;
56
57
58         if (!pr)
59                 return -EINVAL;
60
61         if (!pr->flags.throttling)
62                 return -ENODEV;
63
64         pr->throttling.state = 0;
65
66         duty_mask = pr->throttling.state_count - 1;
67
68         duty_mask <<= pr->throttling.duty_offset;
69
70         local_irq_disable();
71
72         value = inl(pr->throttling.address);
73
74         /*
75          * Compute the current throttling state when throttling is enabled
76          * (bit 4 is on).
77          */
78         if (value & 0x10) {
79                 duty_value = value & duty_mask;
80                 duty_value >>= pr->throttling.duty_offset;
81
82                 if (duty_value)
83                         state = pr->throttling.state_count - duty_value;
84         }
85
86         pr->throttling.state = state;
87
88         local_irq_enable();
89
90         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
91                           "Throttling state is T%d (%d%% throttling applied)\n",
92                           state, pr->throttling.states[state].performance));
93
94         return 0;
95 }
96
97 int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
98 {
99         u32 value = 0;
100         u32 duty_mask = 0;
101         u32 duty_value = 0;
102
103
104         if (!pr)
105                 return -EINVAL;
106
107         if ((state < 0) || (state > (pr->throttling.state_count - 1)))
108                 return -EINVAL;
109
110         if (!pr->flags.throttling)
111                 return -ENODEV;
112
113         if (state == pr->throttling.state)
114                 return 0;
115
116         /*
117          * Calculate the duty_value and duty_mask.
118          */
119         if (state) {
120                 duty_value = pr->throttling.state_count - state;
121
122                 duty_value <<= pr->throttling.duty_offset;
123
124                 /* Used to clear all duty_value bits */
125                 duty_mask = pr->throttling.state_count - 1;
126
127                 duty_mask <<= acpi_gbl_FADT.duty_offset;
128                 duty_mask = ~duty_mask;
129         }
130
131         local_irq_disable();
132
133         /*
134          * Disable throttling by writing a 0 to bit 4.  Note that we must
135          * turn it off before you can change the duty_value.
136          */
137         value = inl(pr->throttling.address);
138         if (value & 0x10) {
139                 value &= 0xFFFFFFEF;
140                 outl(value, pr->throttling.address);
141         }
142
143         /*
144          * Write the new duty_value and then enable throttling.  Note
145          * that a state value of 0 leaves throttling disabled.
146          */
147         if (state) {
148                 value &= duty_mask;
149                 value |= duty_value;
150                 outl(value, pr->throttling.address);
151
152                 value |= 0x00000010;
153                 outl(value, pr->throttling.address);
154         }
155
156         pr->throttling.state = state;
157
158         local_irq_enable();
159
160         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
161                           "Throttling state set to T%d (%d%%)\n", state,
162                           (pr->throttling.states[state].performance ? pr->
163                            throttling.states[state].performance / 10 : 0)));
164
165         return 0;
166 }
167
168 int acpi_processor_get_throttling_info(struct acpi_processor *pr)
169 {
170         int result = 0;
171         int step = 0;
172         int i = 0;
173
174
175         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
176                           "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
177                           pr->throttling.address,
178                           pr->throttling.duty_offset,
179                           pr->throttling.duty_width));
180
181         if (!pr)
182                 return -EINVAL;
183
184         /* TBD: Support ACPI 2.0 objects */
185
186         if (!pr->throttling.address) {
187                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
188                 return 0;
189         } else if (!pr->throttling.duty_width) {
190                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
191                 return 0;
192         }
193         /* TBD: Support duty_cycle values that span bit 4. */
194         else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
195                 printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
196                 return 0;
197         }
198
199         /*
200          * PIIX4 Errata: We don't support throttling on the original PIIX4.
201          * This shouldn't be an issue as few (if any) mobile systems ever
202          * used this part.
203          */
204         if (errata.piix4.throttle) {
205                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
206                                   "Throttling not supported on PIIX4 A- or B-step\n"));
207                 return 0;
208         }
209
210         pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
211
212         /*
213          * Compute state values. Note that throttling displays a linear power/
214          * performance relationship (at 50% performance the CPU will consume
215          * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
216          */
217
218         step = (1000 / pr->throttling.state_count);
219
220         for (i = 0; i < pr->throttling.state_count; i++) {
221                 pr->throttling.states[i].performance = step * i;
222                 pr->throttling.states[i].power = step * i;
223         }
224
225         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
226                           pr->throttling.state_count));
227
228         pr->flags.throttling = 1;
229
230         /*
231          * Disable throttling (if enabled).  We'll let subsequent policy (e.g.
232          * thermal) decide to lower performance if it so chooses, but for now
233          * we'll crank up the speed.
234          */
235
236         result = acpi_processor_get_throttling(pr);
237         if (result)
238                 goto end;
239
240         if (pr->throttling.state) {
241                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
242                                   "Disabling throttling (was T%d)\n",
243                                   pr->throttling.state));
244                 result = acpi_processor_set_throttling(pr, 0);
245                 if (result)
246                         goto end;
247         }
248
249       end:
250         if (result)
251                 pr->flags.throttling = 0;
252
253         return result;
254 }
255
256 /* proc interface */
257
258 static int acpi_processor_throttling_seq_show(struct seq_file *seq,
259                                               void *offset)
260 {
261         struct acpi_processor *pr = seq->private;
262         int i = 0;
263         int result = 0;
264
265
266         if (!pr)
267                 goto end;
268
269         if (!(pr->throttling.state_count > 0)) {
270                 seq_puts(seq, "<not supported>\n");
271                 goto end;
272         }
273
274         result = acpi_processor_get_throttling(pr);
275
276         if (result) {
277                 seq_puts(seq,
278                          "Could not determine current throttling state.\n");
279                 goto end;
280         }
281
282         seq_printf(seq, "state count:             %d\n"
283                    "active state:            T%d\n",
284                    pr->throttling.state_count, pr->throttling.state);
285
286         seq_puts(seq, "states:\n");
287         for (i = 0; i < pr->throttling.state_count; i++)
288                 seq_printf(seq, "   %cT%d:                  %02d%%\n",
289                            (i == pr->throttling.state ? '*' : ' '), i,
290                            (pr->throttling.states[i].performance ? pr->
291                             throttling.states[i].performance / 10 : 0));
292
293       end:
294         return 0;
295 }
296
297 static int acpi_processor_throttling_open_fs(struct inode *inode,
298                                              struct file *file)
299 {
300         return single_open(file, acpi_processor_throttling_seq_show,
301                            PDE(inode)->data);
302 }
303
304 static ssize_t acpi_processor_write_throttling(struct file * file,
305                                                const char __user * buffer,
306                                                size_t count, loff_t * data)
307 {
308         int result = 0;
309         struct seq_file *m = file->private_data;
310         struct acpi_processor *pr = m->private;
311         char state_string[12] = { '\0' };
312
313
314         if (!pr || (count > sizeof(state_string) - 1))
315                 return -EINVAL;
316
317         if (copy_from_user(state_string, buffer, count))
318                 return -EFAULT;
319
320         state_string[count] = '\0';
321
322         result = acpi_processor_set_throttling(pr,
323                                                simple_strtoul(state_string,
324                                                               NULL, 0));
325         if (result)
326                 return result;
327
328         return count;
329 }
330
331 struct file_operations acpi_processor_throttling_fops = {
332         .open = acpi_processor_throttling_open_fs,
333         .read = seq_read,
334         .write = acpi_processor_write_throttling,
335         .llseek = seq_lseek,
336         .release = single_release,
337 };