Commit 1cbf4c563c0eaaf11c552a88b374e213181c6ddd

Authored by Thomas Renninger
Committed by Len Brown
1 parent d2149b5423

[ACPI] Allow return to active cooling mode once passive mode is entered

http://bugzilla.kernel.org/show_bug.cgi?id=3410
https://bugzilla.novell.com/show_bug.cgi?id=131543

Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Konstantin Karasyov <konstantin.a.karasyov@intel.com>
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Yu Luming <luming.yu@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>

Showing 2 changed files with 108 additions and 93 deletions Inline Diff

drivers/acpi/processor_thermal.c
1 /* 1 /*
2 * processor_thermal.c - Passive cooling submodule of the ACPI processor driver 2 * processor_thermal.c - Passive cooling submodule of the ACPI processor driver
3 * 3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> 6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> 7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
8 * - Added processor hotplug support 8 * - Added processor hotplug support
9 * 9 *
10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 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 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 14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version. 15 * your option) any later version.
16 * 16 *
17 * This program is distributed in the hope that it will be useful, but 17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details. 20 * General Public License for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License along 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., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 25 *
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 */ 27 */
28 28
29 #include <linux/kernel.h> 29 #include <linux/kernel.h>
30 #include <linux/module.h> 30 #include <linux/module.h>
31 #include <linux/init.h> 31 #include <linux/init.h>
32 #include <linux/cpufreq.h> 32 #include <linux/cpufreq.h>
33 #include <linux/proc_fs.h> 33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h> 34 #include <linux/seq_file.h>
35 35
36 #include <asm/uaccess.h> 36 #include <asm/uaccess.h>
37 37
38 #include <acpi/acpi_bus.h> 38 #include <acpi/acpi_bus.h>
39 #include <acpi/processor.h> 39 #include <acpi/processor.h>
40 #include <acpi/acpi_drivers.h> 40 #include <acpi/acpi_drivers.h>
41 41
42 #define ACPI_PROCESSOR_COMPONENT 0x01000000 42 #define ACPI_PROCESSOR_COMPONENT 0x01000000
43 #define ACPI_PROCESSOR_CLASS "processor" 43 #define ACPI_PROCESSOR_CLASS "processor"
44 #define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" 44 #define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
45 #define _COMPONENT ACPI_PROCESSOR_COMPONENT 45 #define _COMPONENT ACPI_PROCESSOR_COMPONENT
46 ACPI_MODULE_NAME("acpi_processor") 46 ACPI_MODULE_NAME("acpi_processor")
47 47
48 /* -------------------------------------------------------------------------- 48 /* --------------------------------------------------------------------------
49 Limit Interface 49 Limit Interface
50 -------------------------------------------------------------------------- */ 50 -------------------------------------------------------------------------- */
51 static int acpi_processor_apply_limit(struct acpi_processor *pr) 51 static int acpi_processor_apply_limit(struct acpi_processor *pr)
52 { 52 {
53 int result = 0; 53 int result = 0;
54 u16 px = 0; 54 u16 px = 0;
55 u16 tx = 0; 55 u16 tx = 0;
56 56
57 ACPI_FUNCTION_TRACE("acpi_processor_apply_limit"); 57 ACPI_FUNCTION_TRACE("acpi_processor_apply_limit");
58 58
59 if (!pr) 59 if (!pr)
60 return_VALUE(-EINVAL); 60 return_VALUE(-EINVAL);
61 61
62 if (!pr->flags.limit) 62 if (!pr->flags.limit)
63 return_VALUE(-ENODEV); 63 return_VALUE(-ENODEV);
64 64
65 if (pr->flags.throttling) { 65 if (pr->flags.throttling) {
66 if (pr->limit.user.tx > tx) 66 if (pr->limit.user.tx > tx)
67 tx = pr->limit.user.tx; 67 tx = pr->limit.user.tx;
68 if (pr->limit.thermal.tx > tx) 68 if (pr->limit.thermal.tx > tx)
69 tx = pr->limit.thermal.tx; 69 tx = pr->limit.thermal.tx;
70 70
71 result = acpi_processor_set_throttling(pr, tx); 71 result = acpi_processor_set_throttling(pr, tx);
72 if (result) 72 if (result)
73 goto end; 73 goto end;
74 } 74 }
75 75
76 pr->limit.state.px = px; 76 pr->limit.state.px = px;
77 pr->limit.state.tx = tx; 77 pr->limit.state.tx = tx;
78 78
79 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 79 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
80 "Processor [%d] limit set to (P%d:T%d)\n", pr->id, 80 "Processor [%d] limit set to (P%d:T%d)\n", pr->id,
81 pr->limit.state.px, pr->limit.state.tx)); 81 pr->limit.state.px, pr->limit.state.tx));
82 82
83 end: 83 end:
84 if (result) 84 if (result)
85 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n")); 85 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n"));
86 86
87 return_VALUE(result); 87 return_VALUE(result);
88 } 88 }
89 89
90 #ifdef CONFIG_CPU_FREQ 90 #ifdef CONFIG_CPU_FREQ
91 91
92 /* If a passive cooling situation is detected, primarily CPUfreq is used, as it 92 /* If a passive cooling situation is detected, primarily CPUfreq is used, as it
93 * offers (in most cases) voltage scaling in addition to frequency scaling, and 93 * offers (in most cases) voltage scaling in addition to frequency scaling, and
94 * thus a cubic (instead of linear) reduction of energy. Also, we allow for 94 * thus a cubic (instead of linear) reduction of energy. Also, we allow for
95 * _any_ cpufreq driver and not only the acpi-cpufreq driver. 95 * _any_ cpufreq driver and not only the acpi-cpufreq driver.
96 */ 96 */
97 97
98 static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS]; 98 static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
99 static unsigned int acpi_thermal_cpufreq_is_init = 0; 99 static unsigned int acpi_thermal_cpufreq_is_init = 0;
100 100
101 static int cpu_has_cpufreq(unsigned int cpu) 101 static int cpu_has_cpufreq(unsigned int cpu)
102 { 102 {
103 struct cpufreq_policy policy; 103 struct cpufreq_policy policy;
104 if (!acpi_thermal_cpufreq_is_init) 104 if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu))
105 return -ENODEV; 105 return -ENODEV;
106 if (!cpufreq_get_policy(&policy, cpu))
107 return -ENODEV;
108 return 0; 106 return 0;
109 } 107 }
110 108
111 static int acpi_thermal_cpufreq_increase(unsigned int cpu) 109 static int acpi_thermal_cpufreq_increase(unsigned int cpu)
112 { 110 {
113 if (!cpu_has_cpufreq(cpu)) 111 if (!cpu_has_cpufreq(cpu))
114 return -ENODEV; 112 return -ENODEV;
115 113
116 if (cpufreq_thermal_reduction_pctg[cpu] < 60) { 114 if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
117 cpufreq_thermal_reduction_pctg[cpu] += 20; 115 cpufreq_thermal_reduction_pctg[cpu] += 20;
118 cpufreq_update_policy(cpu); 116 cpufreq_update_policy(cpu);
119 return 0; 117 return 0;
120 } 118 }
121 119
122 return -ERANGE; 120 return -ERANGE;
123 } 121 }
124 122
125 static int acpi_thermal_cpufreq_decrease(unsigned int cpu) 123 static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
126 { 124 {
127 if (!cpu_has_cpufreq(cpu)) 125 if (!cpu_has_cpufreq(cpu))
128 return -ENODEV; 126 return -ENODEV;
129 127
130 if (cpufreq_thermal_reduction_pctg[cpu] >= 20) { 128 if (cpufreq_thermal_reduction_pctg[cpu] > 20)
131 cpufreq_thermal_reduction_pctg[cpu] -= 20; 129 cpufreq_thermal_reduction_pctg[cpu] -= 20;
132 cpufreq_update_policy(cpu); 130 else
133 return 0; 131 cpufreq_thermal_reduction_pctg[cpu] = 0;
134 } 132 cpufreq_update_policy(cpu);
135 133 /* We reached max freq again and can leave passive mode */
136 return -ERANGE; 134 return !cpufreq_thermal_reduction_pctg[cpu];
137 } 135 }
138 136
139 static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, 137 static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
140 unsigned long event, void *data) 138 unsigned long event, void *data)
141 { 139 {
142 struct cpufreq_policy *policy = data; 140 struct cpufreq_policy *policy = data;
143 unsigned long max_freq = 0; 141 unsigned long max_freq = 0;
144 142
145 if (event != CPUFREQ_ADJUST) 143 if (event != CPUFREQ_ADJUST)
146 goto out; 144 goto out;
147 145
148 max_freq = 146 max_freq =
149 (policy->cpuinfo.max_freq * 147 (policy->cpuinfo.max_freq *
150 (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100; 148 (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
151 149
152 cpufreq_verify_within_limits(policy, 0, max_freq); 150 cpufreq_verify_within_limits(policy, 0, max_freq);
153 151
154 out: 152 out:
155 return 0; 153 return 0;
156 } 154 }
157 155
158 static struct notifier_block acpi_thermal_cpufreq_notifier_block = { 156 static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
159 .notifier_call = acpi_thermal_cpufreq_notifier, 157 .notifier_call = acpi_thermal_cpufreq_notifier,
160 }; 158 };
161 159
162 void acpi_thermal_cpufreq_init(void) 160 void acpi_thermal_cpufreq_init(void)
163 { 161 {
164 int i; 162 int i;
165 163
166 for (i = 0; i < NR_CPUS; i++) 164 for (i = 0; i < NR_CPUS; i++)
167 cpufreq_thermal_reduction_pctg[i] = 0; 165 cpufreq_thermal_reduction_pctg[i] = 0;
168 166
169 i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, 167 i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
170 CPUFREQ_POLICY_NOTIFIER); 168 CPUFREQ_POLICY_NOTIFIER);
171 if (!i) 169 if (!i)
172 acpi_thermal_cpufreq_is_init = 1; 170 acpi_thermal_cpufreq_is_init = 1;
173 } 171 }
174 172
175 void acpi_thermal_cpufreq_exit(void) 173 void acpi_thermal_cpufreq_exit(void)
176 { 174 {
177 if (acpi_thermal_cpufreq_is_init) 175 if (acpi_thermal_cpufreq_is_init)
178 cpufreq_unregister_notifier 176 cpufreq_unregister_notifier
179 (&acpi_thermal_cpufreq_notifier_block, 177 (&acpi_thermal_cpufreq_notifier_block,
180 CPUFREQ_POLICY_NOTIFIER); 178 CPUFREQ_POLICY_NOTIFIER);
181 179
182 acpi_thermal_cpufreq_is_init = 0; 180 acpi_thermal_cpufreq_is_init = 0;
183 } 181 }
184 182
185 #else /* ! CONFIG_CPU_FREQ */ 183 #else /* ! CONFIG_CPU_FREQ */
186 184
187 static int acpi_thermal_cpufreq_increase(unsigned int cpu) 185 static int acpi_thermal_cpufreq_increase(unsigned int cpu)
188 { 186 {
189 return -ENODEV; 187 return -ENODEV;
190 } 188 }
191 static int acpi_thermal_cpufreq_decrease(unsigned int cpu) 189 static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
192 { 190 {
193 return -ENODEV; 191 return -ENODEV;
194 } 192 }
195 193
196 #endif 194 #endif
197 195
198 int acpi_processor_set_thermal_limit(acpi_handle handle, int type) 196 int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
199 { 197 {
200 int result = 0; 198 int result = 0;
201 struct acpi_processor *pr = NULL; 199 struct acpi_processor *pr = NULL;
202 struct acpi_device *device = NULL; 200 struct acpi_device *device = NULL;
203 int tx = 0; 201 int tx = 0, max_tx_px = 0;
204 202
205 ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit"); 203 ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
206 204
207 if ((type < ACPI_PROCESSOR_LIMIT_NONE) 205 if ((type < ACPI_PROCESSOR_LIMIT_NONE)
208 || (type > ACPI_PROCESSOR_LIMIT_DECREMENT)) 206 || (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
209 return_VALUE(-EINVAL); 207 return_VALUE(-EINVAL);
210 208
211 result = acpi_bus_get_device(handle, &device); 209 result = acpi_bus_get_device(handle, &device);
212 if (result) 210 if (result)
213 return_VALUE(result); 211 return_VALUE(result);
214 212
215 pr = (struct acpi_processor *)acpi_driver_data(device); 213 pr = (struct acpi_processor *)acpi_driver_data(device);
216 if (!pr) 214 if (!pr)
217 return_VALUE(-ENODEV); 215 return_VALUE(-ENODEV);
218 216
219 /* Thermal limits are always relative to the current Px/Tx state. */ 217 /* Thermal limits are always relative to the current Px/Tx state. */
220 if (pr->flags.throttling) 218 if (pr->flags.throttling)
221 pr->limit.thermal.tx = pr->throttling.state; 219 pr->limit.thermal.tx = pr->throttling.state;
222 220
223 /* 221 /*
224 * Our default policy is to only use throttling at the lowest 222 * Our default policy is to only use throttling at the lowest
225 * performance state. 223 * performance state.
226 */ 224 */
227 225
228 tx = pr->limit.thermal.tx; 226 tx = pr->limit.thermal.tx;
229 227
230 switch (type) { 228 switch (type) {
231 229
232 case ACPI_PROCESSOR_LIMIT_NONE: 230 case ACPI_PROCESSOR_LIMIT_NONE:
233 do { 231 do {
234 result = acpi_thermal_cpufreq_decrease(pr->id); 232 result = acpi_thermal_cpufreq_decrease(pr->id);
235 } while (!result); 233 } while (!result);
236 tx = 0; 234 tx = 0;
237 break; 235 break;
238 236
239 case ACPI_PROCESSOR_LIMIT_INCREMENT: 237 case ACPI_PROCESSOR_LIMIT_INCREMENT:
240 /* if going up: P-states first, T-states later */ 238 /* if going up: P-states first, T-states later */
241 239
242 result = acpi_thermal_cpufreq_increase(pr->id); 240 result = acpi_thermal_cpufreq_increase(pr->id);
243 if (!result) 241 if (!result)
244 goto end; 242 goto end;
245 else if (result == -ERANGE) 243 else if (result == -ERANGE)
246 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 244 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
247 "At maximum performance state\n")); 245 "At maximum performance state\n"));
248 246
249 if (pr->flags.throttling) { 247 if (pr->flags.throttling) {
250 if (tx == (pr->throttling.state_count - 1)) 248 if (tx == (pr->throttling.state_count - 1))
251 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 249 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
252 "At maximum throttling state\n")); 250 "At maximum throttling state\n"));
253 else 251 else
254 tx++; 252 tx++;
255 } 253 }
256 break; 254 break;
257 255
258 case ACPI_PROCESSOR_LIMIT_DECREMENT: 256 case ACPI_PROCESSOR_LIMIT_DECREMENT:
259 /* if going down: T-states first, P-states later */ 257 /* if going down: T-states first, P-states later */
260 258
261 if (pr->flags.throttling) { 259 if (pr->flags.throttling) {
262 if (tx == 0) 260 if (tx == 0) {
261 max_tx_px = 1;
263 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 262 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
264 "At minimum throttling state\n")); 263 "At minimum throttling state\n"));
265 else { 264 } else {
266 tx--; 265 tx--;
267 goto end; 266 goto end;
268 } 267 }
269 } 268 }
270 269
271 result = acpi_thermal_cpufreq_decrease(pr->id); 270 result = acpi_thermal_cpufreq_decrease(pr->id);
272 if (result == -ERANGE) 271 if (result) {
272 /*
273 * We only could get -ERANGE, 1 or 0.
274 * In the first two cases we reached max freq again.
275 */
273 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 276 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
274 "At minimum performance state\n")); 277 "At minimum performance state\n"));
278 max_tx_px = 1;
279 } else
280 max_tx_px = 0;
275 281
276 break; 282 break;
277 } 283 }
278 284
279 end: 285 end:
280 if (pr->flags.throttling) { 286 if (pr->flags.throttling) {
281 pr->limit.thermal.px = 0; 287 pr->limit.thermal.px = 0;
282 pr->limit.thermal.tx = tx; 288 pr->limit.thermal.tx = tx;
283 289
284 result = acpi_processor_apply_limit(pr); 290 result = acpi_processor_apply_limit(pr);
285 if (result) 291 if (result)
286 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 292 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
287 "Unable to set thermal limit\n")); 293 "Unable to set thermal limit\n"));
288 294
289 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n", 295 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
290 pr->limit.thermal.px, pr->limit.thermal.tx)); 296 pr->limit.thermal.px, pr->limit.thermal.tx));
291 } else 297 } else
292 result = 0; 298 result = 0;
293 299 if (max_tx_px)
294 return_VALUE(result); 300 return_VALUE(1);
301 else
302 return_VALUE(result);
295 } 303 }
296 304
297 int acpi_processor_get_limit_info(struct acpi_processor *pr) 305 int acpi_processor_get_limit_info(struct acpi_processor *pr)
298 { 306 {
299 ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info"); 307 ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info");
300 308
301 if (!pr) 309 if (!pr)
302 return_VALUE(-EINVAL); 310 return_VALUE(-EINVAL);
303 311
304 if (pr->flags.throttling) 312 if (pr->flags.throttling)
305 pr->flags.limit = 1; 313 pr->flags.limit = 1;
306 314
307 return_VALUE(0); 315 return_VALUE(0);
308 } 316 }
309 317
310 /* /proc interface */ 318 /* /proc interface */
311 319
312 static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) 320 static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
313 { 321 {
314 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 322 struct acpi_processor *pr = (struct acpi_processor *)seq->private;
315 323
316 ACPI_FUNCTION_TRACE("acpi_processor_limit_seq_show"); 324 ACPI_FUNCTION_TRACE("acpi_processor_limit_seq_show");
317 325
318 if (!pr) 326 if (!pr)
319 goto end; 327 goto end;
320 328
321 if (!pr->flags.limit) { 329 if (!pr->flags.limit) {
322 seq_puts(seq, "<not supported>\n"); 330 seq_puts(seq, "<not supported>\n");
323 goto end; 331 goto end;
324 } 332 }
325 333
326 seq_printf(seq, "active limit: P%d:T%d\n" 334 seq_printf(seq, "active limit: P%d:T%d\n"
327 "user limit: P%d:T%d\n" 335 "user limit: P%d:T%d\n"
328 "thermal limit: P%d:T%d\n", 336 "thermal limit: P%d:T%d\n",
329 pr->limit.state.px, pr->limit.state.tx, 337 pr->limit.state.px, pr->limit.state.tx,
330 pr->limit.user.px, pr->limit.user.tx, 338 pr->limit.user.px, pr->limit.user.tx,
331 pr->limit.thermal.px, pr->limit.thermal.tx); 339 pr->limit.thermal.px, pr->limit.thermal.tx);
332 340
333 end: 341 end:
334 return_VALUE(0); 342 return_VALUE(0);
335 } 343 }
336 344
337 static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file) 345 static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
338 { 346 {
339 return single_open(file, acpi_processor_limit_seq_show, 347 return single_open(file, acpi_processor_limit_seq_show,
340 PDE(inode)->data); 348 PDE(inode)->data);
341 } 349 }
342 350
343 ssize_t acpi_processor_write_limit(struct file * file, 351 ssize_t acpi_processor_write_limit(struct file * file,
344 const char __user * buffer, 352 const char __user * buffer,
345 size_t count, loff_t * data) 353 size_t count, loff_t * data)
346 { 354 {
347 int result = 0; 355 int result = 0;
348 struct seq_file *m = (struct seq_file *)file->private_data; 356 struct seq_file *m = (struct seq_file *)file->private_data;
349 struct acpi_processor *pr = (struct acpi_processor *)m->private; 357 struct acpi_processor *pr = (struct acpi_processor *)m->private;
350 char limit_string[25] = { '\0' }; 358 char limit_string[25] = { '\0' };
351 int px = 0; 359 int px = 0;
352 int tx = 0; 360 int tx = 0;
353 361
354 ACPI_FUNCTION_TRACE("acpi_processor_write_limit"); 362 ACPI_FUNCTION_TRACE("acpi_processor_write_limit");
355 363
356 if (!pr || (count > sizeof(limit_string) - 1)) { 364 if (!pr || (count > sizeof(limit_string) - 1)) {
357 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n")); 365 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
358 return_VALUE(-EINVAL); 366 return_VALUE(-EINVAL);
359 } 367 }
360 368
361 if (copy_from_user(limit_string, buffer, count)) { 369 if (copy_from_user(limit_string, buffer, count)) {
362 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); 370 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
363 return_VALUE(-EFAULT); 371 return_VALUE(-EFAULT);
364 } 372 }
365 373
366 limit_string[count] = '\0'; 374 limit_string[count] = '\0';
367 375
368 if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { 376 if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) {
369 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); 377 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
370 return_VALUE(-EINVAL); 378 return_VALUE(-EINVAL);
371 } 379 }
372 380
373 if (pr->flags.throttling) { 381 if (pr->flags.throttling) {
374 if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { 382 if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
375 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n")); 383 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n"));
376 return_VALUE(-EINVAL); 384 return_VALUE(-EINVAL);
377 } 385 }
378 pr->limit.user.tx = tx; 386 pr->limit.user.tx = tx;
379 } 387 }
380 388
381 result = acpi_processor_apply_limit(pr); 389 result = acpi_processor_apply_limit(pr);
382 390
383 return_VALUE(count); 391 return_VALUE(count);
384 } 392 }
385 393
386 struct file_operations acpi_processor_limit_fops = { 394 struct file_operations acpi_processor_limit_fops = {
387 .open = acpi_processor_limit_open_fs, 395 .open = acpi_processor_limit_open_fs,
388 .read = seq_read, 396 .read = seq_read,
389 .llseek = seq_lseek, 397 .llseek = seq_lseek,
390 .release = single_release, 398 .release = single_release,
drivers/acpi/thermal.c
1 /* 1 /*
2 * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $) 2 * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $)
3 * 3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * 6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at 11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version. 12 * your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, but 14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. 17 * General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License along 19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc., 20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * 22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 * 24 *
25 * This driver fully implements the ACPI thermal policy as described in the 25 * This driver fully implements the ACPI thermal policy as described in the
26 * ACPI 2.0 Specification. 26 * ACPI 2.0 Specification.
27 * 27 *
28 * TBD: 1. Implement passive cooling hysteresis. 28 * TBD: 1. Implement passive cooling hysteresis.
29 * 2. Enhance passive cooling (CPU) states/limit interface to support 29 * 2. Enhance passive cooling (CPU) states/limit interface to support
30 * concepts of 'multiple limiters', upper/lower limits, etc. 30 * concepts of 'multiple limiters', upper/lower limits, etc.
31 * 31 *
32 */ 32 */
33 33
34 #include <linux/kernel.h> 34 #include <linux/kernel.h>
35 #include <linux/module.h> 35 #include <linux/module.h>
36 #include <linux/init.h> 36 #include <linux/init.h>
37 #include <linux/types.h> 37 #include <linux/types.h>
38 #include <linux/proc_fs.h> 38 #include <linux/proc_fs.h>
39 #include <linux/sched.h> 39 #include <linux/sched.h>
40 #include <linux/kmod.h> 40 #include <linux/kmod.h>
41 #include <linux/seq_file.h> 41 #include <linux/seq_file.h>
42 #include <asm/uaccess.h> 42 #include <asm/uaccess.h>
43 43
44 #include <acpi/acpi_bus.h> 44 #include <acpi/acpi_bus.h>
45 #include <acpi/acpi_drivers.h> 45 #include <acpi/acpi_drivers.h>
46 46
47 #define ACPI_THERMAL_COMPONENT 0x04000000 47 #define ACPI_THERMAL_COMPONENT 0x04000000
48 #define ACPI_THERMAL_CLASS "thermal_zone" 48 #define ACPI_THERMAL_CLASS "thermal_zone"
49 #define ACPI_THERMAL_DRIVER_NAME "ACPI Thermal Zone Driver" 49 #define ACPI_THERMAL_DRIVER_NAME "ACPI Thermal Zone Driver"
50 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 50 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone"
51 #define ACPI_THERMAL_FILE_STATE "state" 51 #define ACPI_THERMAL_FILE_STATE "state"
52 #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" 52 #define ACPI_THERMAL_FILE_TEMPERATURE "temperature"
53 #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" 53 #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points"
54 #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" 54 #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode"
55 #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" 55 #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency"
56 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 56 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
57 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 57 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81
58 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 58 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82
59 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 59 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0
60 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 60 #define ACPI_THERMAL_NOTIFY_HOT 0xF1
61 #define ACPI_THERMAL_MODE_ACTIVE 0x00 61 #define ACPI_THERMAL_MODE_ACTIVE 0x00
62 #define ACPI_THERMAL_MODE_PASSIVE 0x01 62 #define ACPI_THERMAL_MODE_PASSIVE 0x01
63 #define ACPI_THERMAL_MODE_CRITICAL 0xff 63 #define ACPI_THERMAL_MODE_CRITICAL 0xff
64 #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" 64 #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff"
65 65
66 #define ACPI_THERMAL_MAX_ACTIVE 10 66 #define ACPI_THERMAL_MAX_ACTIVE 10
67 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 67 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
68 68
69 #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10) 69 #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
70 #define CELSIUS_TO_KELVIN(t) ((t+273)*10) 70 #define CELSIUS_TO_KELVIN(t) ((t+273)*10)
71 71
72 #define _COMPONENT ACPI_THERMAL_COMPONENT 72 #define _COMPONENT ACPI_THERMAL_COMPONENT
73 ACPI_MODULE_NAME("acpi_thermal") 73 ACPI_MODULE_NAME("acpi_thermal")
74 74
75 MODULE_AUTHOR("Paul Diefenbaugh"); 75 MODULE_AUTHOR("Paul Diefenbaugh");
76 MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); 76 MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
77 MODULE_LICENSE("GPL"); 77 MODULE_LICENSE("GPL");
78 78
79 static int tzp; 79 static int tzp;
80 module_param(tzp, int, 0); 80 module_param(tzp, int, 0);
81 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); 81 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
82 82
83 static int acpi_thermal_add(struct acpi_device *device); 83 static int acpi_thermal_add(struct acpi_device *device);
84 static int acpi_thermal_remove(struct acpi_device *device, int type); 84 static int acpi_thermal_remove(struct acpi_device *device, int type);
85 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 85 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
86 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 86 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
87 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 87 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
88 static ssize_t acpi_thermal_write_trip_points(struct file *, 88 static ssize_t acpi_thermal_write_trip_points(struct file *,
89 const char __user *, size_t, 89 const char __user *, size_t,
90 loff_t *); 90 loff_t *);
91 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); 91 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
92 static ssize_t acpi_thermal_write_cooling_mode(struct file *, 92 static ssize_t acpi_thermal_write_cooling_mode(struct file *,
93 const char __user *, size_t, 93 const char __user *, size_t,
94 loff_t *); 94 loff_t *);
95 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); 95 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
96 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, 96 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
97 size_t, loff_t *); 97 size_t, loff_t *);
98 98
99 static struct acpi_driver acpi_thermal_driver = { 99 static struct acpi_driver acpi_thermal_driver = {
100 .name = ACPI_THERMAL_DRIVER_NAME, 100 .name = ACPI_THERMAL_DRIVER_NAME,
101 .class = ACPI_THERMAL_CLASS, 101 .class = ACPI_THERMAL_CLASS,
102 .ids = ACPI_THERMAL_HID, 102 .ids = ACPI_THERMAL_HID,
103 .ops = { 103 .ops = {
104 .add = acpi_thermal_add, 104 .add = acpi_thermal_add,
105 .remove = acpi_thermal_remove, 105 .remove = acpi_thermal_remove,
106 }, 106 },
107 }; 107 };
108 108
109 struct acpi_thermal_state { 109 struct acpi_thermal_state {
110 u8 critical:1; 110 u8 critical:1;
111 u8 hot:1; 111 u8 hot:1;
112 u8 passive:1; 112 u8 passive:1;
113 u8 active:1; 113 u8 active:1;
114 u8 reserved:4; 114 u8 reserved:4;
115 int active_index; 115 int active_index;
116 }; 116 };
117 117
118 struct acpi_thermal_state_flags { 118 struct acpi_thermal_state_flags {
119 u8 valid:1; 119 u8 valid:1;
120 u8 enabled:1; 120 u8 enabled:1;
121 u8 reserved:6; 121 u8 reserved:6;
122 }; 122 };
123 123
124 struct acpi_thermal_critical { 124 struct acpi_thermal_critical {
125 struct acpi_thermal_state_flags flags; 125 struct acpi_thermal_state_flags flags;
126 unsigned long temperature; 126 unsigned long temperature;
127 }; 127 };
128 128
129 struct acpi_thermal_hot { 129 struct acpi_thermal_hot {
130 struct acpi_thermal_state_flags flags; 130 struct acpi_thermal_state_flags flags;
131 unsigned long temperature; 131 unsigned long temperature;
132 }; 132 };
133 133
134 struct acpi_thermal_passive { 134 struct acpi_thermal_passive {
135 struct acpi_thermal_state_flags flags; 135 struct acpi_thermal_state_flags flags;
136 unsigned long temperature; 136 unsigned long temperature;
137 unsigned long tc1; 137 unsigned long tc1;
138 unsigned long tc2; 138 unsigned long tc2;
139 unsigned long tsp; 139 unsigned long tsp;
140 struct acpi_handle_list devices; 140 struct acpi_handle_list devices;
141 }; 141 };
142 142
143 struct acpi_thermal_active { 143 struct acpi_thermal_active {
144 struct acpi_thermal_state_flags flags; 144 struct acpi_thermal_state_flags flags;
145 unsigned long temperature; 145 unsigned long temperature;
146 struct acpi_handle_list devices; 146 struct acpi_handle_list devices;
147 }; 147 };
148 148
149 struct acpi_thermal_trips { 149 struct acpi_thermal_trips {
150 struct acpi_thermal_critical critical; 150 struct acpi_thermal_critical critical;
151 struct acpi_thermal_hot hot; 151 struct acpi_thermal_hot hot;
152 struct acpi_thermal_passive passive; 152 struct acpi_thermal_passive passive;
153 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 153 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
154 }; 154 };
155 155
156 struct acpi_thermal_flags { 156 struct acpi_thermal_flags {
157 u8 cooling_mode:1; /* _SCP */ 157 u8 cooling_mode:1; /* _SCP */
158 u8 devices:1; /* _TZD */ 158 u8 devices:1; /* _TZD */
159 u8 reserved:6; 159 u8 reserved:6;
160 }; 160 };
161 161
162 struct acpi_thermal { 162 struct acpi_thermal {
163 acpi_handle handle; 163 acpi_handle handle;
164 acpi_bus_id name; 164 acpi_bus_id name;
165 unsigned long temperature; 165 unsigned long temperature;
166 unsigned long last_temperature; 166 unsigned long last_temperature;
167 unsigned long polling_frequency; 167 unsigned long polling_frequency;
168 u8 cooling_mode; 168 u8 cooling_mode;
169 volatile u8 zombie; 169 volatile u8 zombie;
170 struct acpi_thermal_flags flags; 170 struct acpi_thermal_flags flags;
171 struct acpi_thermal_state state; 171 struct acpi_thermal_state state;
172 struct acpi_thermal_trips trips; 172 struct acpi_thermal_trips trips;
173 struct acpi_handle_list devices; 173 struct acpi_handle_list devices;
174 struct timer_list timer; 174 struct timer_list timer;
175 }; 175 };
176 176
177 static struct file_operations acpi_thermal_state_fops = { 177 static struct file_operations acpi_thermal_state_fops = {
178 .open = acpi_thermal_state_open_fs, 178 .open = acpi_thermal_state_open_fs,
179 .read = seq_read, 179 .read = seq_read,
180 .llseek = seq_lseek, 180 .llseek = seq_lseek,
181 .release = single_release, 181 .release = single_release,
182 }; 182 };
183 183
184 static struct file_operations acpi_thermal_temp_fops = { 184 static struct file_operations acpi_thermal_temp_fops = {
185 .open = acpi_thermal_temp_open_fs, 185 .open = acpi_thermal_temp_open_fs,
186 .read = seq_read, 186 .read = seq_read,
187 .llseek = seq_lseek, 187 .llseek = seq_lseek,
188 .release = single_release, 188 .release = single_release,
189 }; 189 };
190 190
191 static struct file_operations acpi_thermal_trip_fops = { 191 static struct file_operations acpi_thermal_trip_fops = {
192 .open = acpi_thermal_trip_open_fs, 192 .open = acpi_thermal_trip_open_fs,
193 .read = seq_read, 193 .read = seq_read,
194 .write = acpi_thermal_write_trip_points, 194 .write = acpi_thermal_write_trip_points,
195 .llseek = seq_lseek, 195 .llseek = seq_lseek,
196 .release = single_release, 196 .release = single_release,
197 }; 197 };
198 198
199 static struct file_operations acpi_thermal_cooling_fops = { 199 static struct file_operations acpi_thermal_cooling_fops = {
200 .open = acpi_thermal_cooling_open_fs, 200 .open = acpi_thermal_cooling_open_fs,
201 .read = seq_read, 201 .read = seq_read,
202 .write = acpi_thermal_write_cooling_mode, 202 .write = acpi_thermal_write_cooling_mode,
203 .llseek = seq_lseek, 203 .llseek = seq_lseek,
204 .release = single_release, 204 .release = single_release,
205 }; 205 };
206 206
207 static struct file_operations acpi_thermal_polling_fops = { 207 static struct file_operations acpi_thermal_polling_fops = {
208 .open = acpi_thermal_polling_open_fs, 208 .open = acpi_thermal_polling_open_fs,
209 .read = seq_read, 209 .read = seq_read,
210 .write = acpi_thermal_write_polling, 210 .write = acpi_thermal_write_polling,
211 .llseek = seq_lseek, 211 .llseek = seq_lseek,
212 .release = single_release, 212 .release = single_release,
213 }; 213 };
214 214
215 /* -------------------------------------------------------------------------- 215 /* --------------------------------------------------------------------------
216 Thermal Zone Management 216 Thermal Zone Management
217 -------------------------------------------------------------------------- */ 217 -------------------------------------------------------------------------- */
218 218
219 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 219 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
220 { 220 {
221 acpi_status status = AE_OK; 221 acpi_status status = AE_OK;
222 222
223 ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature"); 223 ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature");
224 224
225 if (!tz) 225 if (!tz)
226 return_VALUE(-EINVAL); 226 return_VALUE(-EINVAL);
227 227
228 tz->last_temperature = tz->temperature; 228 tz->last_temperature = tz->temperature;
229 229
230 status = 230 status =
231 acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature); 231 acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature);
232 if (ACPI_FAILURE(status)) 232 if (ACPI_FAILURE(status))
233 return_VALUE(-ENODEV); 233 return_VALUE(-ENODEV);
234 234
235 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", 235 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
236 tz->temperature)); 236 tz->temperature));
237 237
238 return_VALUE(0); 238 return_VALUE(0);
239 } 239 }
240 240
241 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 241 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
242 { 242 {
243 acpi_status status = AE_OK; 243 acpi_status status = AE_OK;
244 244
245 ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency"); 245 ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency");
246 246
247 if (!tz) 247 if (!tz)
248 return_VALUE(-EINVAL); 248 return_VALUE(-EINVAL);
249 249
250 status = 250 status =
251 acpi_evaluate_integer(tz->handle, "_TZP", NULL, 251 acpi_evaluate_integer(tz->handle, "_TZP", NULL,
252 &tz->polling_frequency); 252 &tz->polling_frequency);
253 if (ACPI_FAILURE(status)) 253 if (ACPI_FAILURE(status))
254 return_VALUE(-ENODEV); 254 return_VALUE(-ENODEV);
255 255
256 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", 256 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
257 tz->polling_frequency)); 257 tz->polling_frequency));
258 258
259 return_VALUE(0); 259 return_VALUE(0);
260 } 260 }
261 261
262 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) 262 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
263 { 263 {
264 ACPI_FUNCTION_TRACE("acpi_thermal_set_polling"); 264 ACPI_FUNCTION_TRACE("acpi_thermal_set_polling");
265 265
266 if (!tz) 266 if (!tz)
267 return_VALUE(-EINVAL); 267 return_VALUE(-EINVAL);
268 268
269 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ 269 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
270 270
271 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 271 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
272 "Polling frequency set to %lu seconds\n", 272 "Polling frequency set to %lu seconds\n",
273 tz->polling_frequency)); 273 tz->polling_frequency));
274 274
275 return_VALUE(0); 275 return_VALUE(0);
276 } 276 }
277 277
278 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) 278 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
279 { 279 {
280 acpi_status status = AE_OK; 280 acpi_status status = AE_OK;
281 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 281 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
282 struct acpi_object_list arg_list = { 1, &arg0 }; 282 struct acpi_object_list arg_list = { 1, &arg0 };
283 acpi_handle handle = NULL; 283 acpi_handle handle = NULL;
284 284
285 ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode"); 285 ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode");
286 286
287 if (!tz) 287 if (!tz)
288 return_VALUE(-EINVAL); 288 return_VALUE(-EINVAL);
289 289
290 status = acpi_get_handle(tz->handle, "_SCP", &handle); 290 status = acpi_get_handle(tz->handle, "_SCP", &handle);
291 if (ACPI_FAILURE(status)) { 291 if (ACPI_FAILURE(status)) {
292 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); 292 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
293 return_VALUE(-ENODEV); 293 return_VALUE(-ENODEV);
294 } 294 }
295 295
296 arg0.integer.value = mode; 296 arg0.integer.value = mode;
297 297
298 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 298 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
299 if (ACPI_FAILURE(status)) 299 if (ACPI_FAILURE(status))
300 return_VALUE(-ENODEV); 300 return_VALUE(-ENODEV);
301 301
302 tz->cooling_mode = mode; 302 tz->cooling_mode = mode;
303 303
304 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", 304 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n",
305 mode ? "passive" : "active")); 305 mode ? "passive" : "active"));
306 306
307 return_VALUE(0); 307 return_VALUE(0);
308 } 308 }
309 309
310 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 310 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
311 { 311 {
312 acpi_status status = AE_OK; 312 acpi_status status = AE_OK;
313 int i = 0; 313 int i = 0;
314 314
315 ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points"); 315 ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points");
316 316
317 if (!tz) 317 if (!tz)
318 return_VALUE(-EINVAL); 318 return_VALUE(-EINVAL);
319 319
320 /* Critical Shutdown (required) */ 320 /* Critical Shutdown (required) */
321 321
322 status = acpi_evaluate_integer(tz->handle, "_CRT", NULL, 322 status = acpi_evaluate_integer(tz->handle, "_CRT", NULL,
323 &tz->trips.critical.temperature); 323 &tz->trips.critical.temperature);
324 if (ACPI_FAILURE(status)) { 324 if (ACPI_FAILURE(status)) {
325 tz->trips.critical.flags.valid = 0; 325 tz->trips.critical.flags.valid = 0;
326 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n")); 326 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n"));
327 return_VALUE(-ENODEV); 327 return_VALUE(-ENODEV);
328 } else { 328 } else {
329 tz->trips.critical.flags.valid = 1; 329 tz->trips.critical.flags.valid = 1;
330 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 330 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
331 "Found critical threshold [%lu]\n", 331 "Found critical threshold [%lu]\n",
332 tz->trips.critical.temperature)); 332 tz->trips.critical.temperature));
333 } 333 }
334 334
335 /* Critical Sleep (optional) */ 335 /* Critical Sleep (optional) */
336 336
337 status = 337 status =
338 acpi_evaluate_integer(tz->handle, "_HOT", NULL, 338 acpi_evaluate_integer(tz->handle, "_HOT", NULL,
339 &tz->trips.hot.temperature); 339 &tz->trips.hot.temperature);
340 if (ACPI_FAILURE(status)) { 340 if (ACPI_FAILURE(status)) {
341 tz->trips.hot.flags.valid = 0; 341 tz->trips.hot.flags.valid = 0;
342 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n")); 342 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n"));
343 } else { 343 } else {
344 tz->trips.hot.flags.valid = 1; 344 tz->trips.hot.flags.valid = 1;
345 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", 345 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n",
346 tz->trips.hot.temperature)); 346 tz->trips.hot.temperature));
347 } 347 }
348 348
349 /* Passive: Processors (optional) */ 349 /* Passive: Processors (optional) */
350 350
351 status = 351 status =
352 acpi_evaluate_integer(tz->handle, "_PSV", NULL, 352 acpi_evaluate_integer(tz->handle, "_PSV", NULL,
353 &tz->trips.passive.temperature); 353 &tz->trips.passive.temperature);
354 if (ACPI_FAILURE(status)) { 354 if (ACPI_FAILURE(status)) {
355 tz->trips.passive.flags.valid = 0; 355 tz->trips.passive.flags.valid = 0;
356 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); 356 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
357 } else { 357 } else {
358 tz->trips.passive.flags.valid = 1; 358 tz->trips.passive.flags.valid = 1;
359 359
360 status = 360 status =
361 acpi_evaluate_integer(tz->handle, "_TC1", NULL, 361 acpi_evaluate_integer(tz->handle, "_TC1", NULL,
362 &tz->trips.passive.tc1); 362 &tz->trips.passive.tc1);
363 if (ACPI_FAILURE(status)) 363 if (ACPI_FAILURE(status))
364 tz->trips.passive.flags.valid = 0; 364 tz->trips.passive.flags.valid = 0;
365 365
366 status = 366 status =
367 acpi_evaluate_integer(tz->handle, "_TC2", NULL, 367 acpi_evaluate_integer(tz->handle, "_TC2", NULL,
368 &tz->trips.passive.tc2); 368 &tz->trips.passive.tc2);
369 if (ACPI_FAILURE(status)) 369 if (ACPI_FAILURE(status))
370 tz->trips.passive.flags.valid = 0; 370 tz->trips.passive.flags.valid = 0;
371 371
372 status = 372 status =
373 acpi_evaluate_integer(tz->handle, "_TSP", NULL, 373 acpi_evaluate_integer(tz->handle, "_TSP", NULL,
374 &tz->trips.passive.tsp); 374 &tz->trips.passive.tsp);
375 if (ACPI_FAILURE(status)) 375 if (ACPI_FAILURE(status))
376 tz->trips.passive.flags.valid = 0; 376 tz->trips.passive.flags.valid = 0;
377 377
378 status = 378 status =
379 acpi_evaluate_reference(tz->handle, "_PSL", NULL, 379 acpi_evaluate_reference(tz->handle, "_PSL", NULL,
380 &tz->trips.passive.devices); 380 &tz->trips.passive.devices);
381 if (ACPI_FAILURE(status)) 381 if (ACPI_FAILURE(status))
382 tz->trips.passive.flags.valid = 0; 382 tz->trips.passive.flags.valid = 0;
383 383
384 if (!tz->trips.passive.flags.valid) 384 if (!tz->trips.passive.flags.valid)
385 ACPI_DEBUG_PRINT((ACPI_DB_WARN, 385 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
386 "Invalid passive threshold\n")); 386 "Invalid passive threshold\n"));
387 else 387 else
388 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 388 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
389 "Found passive threshold [%lu]\n", 389 "Found passive threshold [%lu]\n",
390 tz->trips.passive.temperature)); 390 tz->trips.passive.temperature));
391 } 391 }
392 392
393 /* Active: Fans, etc. (optional) */ 393 /* Active: Fans, etc. (optional) */
394 394
395 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 395 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
396 396
397 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 397 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
398 398
399 status = 399 status =
400 acpi_evaluate_integer(tz->handle, name, NULL, 400 acpi_evaluate_integer(tz->handle, name, NULL,
401 &tz->trips.active[i].temperature); 401 &tz->trips.active[i].temperature);
402 if (ACPI_FAILURE(status)) 402 if (ACPI_FAILURE(status))
403 break; 403 break;
404 404
405 name[2] = 'L'; 405 name[2] = 'L';
406 status = 406 status =
407 acpi_evaluate_reference(tz->handle, name, NULL, 407 acpi_evaluate_reference(tz->handle, name, NULL,
408 &tz->trips.active[i].devices); 408 &tz->trips.active[i].devices);
409 if (ACPI_SUCCESS(status)) { 409 if (ACPI_SUCCESS(status)) {
410 tz->trips.active[i].flags.valid = 1; 410 tz->trips.active[i].flags.valid = 1;
411 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 411 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
412 "Found active threshold [%d]:[%lu]\n", 412 "Found active threshold [%d]:[%lu]\n",
413 i, tz->trips.active[i].temperature)); 413 i, tz->trips.active[i].temperature));
414 } else 414 } else
415 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 415 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
416 "Invalid active threshold [%d]\n", 416 "Invalid active threshold [%d]\n",
417 i)); 417 i));
418 } 418 }
419 419
420 return_VALUE(0); 420 return_VALUE(0);
421 } 421 }
422 422
423 static int acpi_thermal_get_devices(struct acpi_thermal *tz) 423 static int acpi_thermal_get_devices(struct acpi_thermal *tz)
424 { 424 {
425 acpi_status status = AE_OK; 425 acpi_status status = AE_OK;
426 426
427 ACPI_FUNCTION_TRACE("acpi_thermal_get_devices"); 427 ACPI_FUNCTION_TRACE("acpi_thermal_get_devices");
428 428
429 if (!tz) 429 if (!tz)
430 return_VALUE(-EINVAL); 430 return_VALUE(-EINVAL);
431 431
432 status = 432 status =
433 acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices); 433 acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices);
434 if (ACPI_FAILURE(status)) 434 if (ACPI_FAILURE(status))
435 return_VALUE(-ENODEV); 435 return_VALUE(-ENODEV);
436 436
437 return_VALUE(0); 437 return_VALUE(0);
438 } 438 }
439 439
440 static int acpi_thermal_call_usermode(char *path) 440 static int acpi_thermal_call_usermode(char *path)
441 { 441 {
442 char *argv[2] = { NULL, NULL }; 442 char *argv[2] = { NULL, NULL };
443 char *envp[3] = { NULL, NULL, NULL }; 443 char *envp[3] = { NULL, NULL, NULL };
444 444
445 ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode"); 445 ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode");
446 446
447 if (!path) 447 if (!path)
448 return_VALUE(-EINVAL); 448 return_VALUE(-EINVAL);
449 449
450 argv[0] = path; 450 argv[0] = path;
451 451
452 /* minimal command environment */ 452 /* minimal command environment */
453 envp[0] = "HOME=/"; 453 envp[0] = "HOME=/";
454 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 454 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
455 455
456 call_usermodehelper(argv[0], argv, envp, 0); 456 call_usermodehelper(argv[0], argv, envp, 0);
457 457
458 return_VALUE(0); 458 return_VALUE(0);
459 } 459 }
460 460
461 static int acpi_thermal_critical(struct acpi_thermal *tz) 461 static int acpi_thermal_critical(struct acpi_thermal *tz)
462 { 462 {
463 int result = 0; 463 int result = 0;
464 struct acpi_device *device = NULL; 464 struct acpi_device *device = NULL;
465 465
466 ACPI_FUNCTION_TRACE("acpi_thermal_critical"); 466 ACPI_FUNCTION_TRACE("acpi_thermal_critical");
467 467
468 if (!tz || !tz->trips.critical.flags.valid) 468 if (!tz || !tz->trips.critical.flags.valid)
469 return_VALUE(-EINVAL); 469 return_VALUE(-EINVAL);
470 470
471 if (tz->temperature >= tz->trips.critical.temperature) { 471 if (tz->temperature >= tz->trips.critical.temperature) {
472 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n")); 472 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n"));
473 tz->trips.critical.flags.enabled = 1; 473 tz->trips.critical.flags.enabled = 1;
474 } else if (tz->trips.critical.flags.enabled) 474 } else if (tz->trips.critical.flags.enabled)
475 tz->trips.critical.flags.enabled = 0; 475 tz->trips.critical.flags.enabled = 0;
476 476
477 result = acpi_bus_get_device(tz->handle, &device); 477 result = acpi_bus_get_device(tz->handle, &device);
478 if (result) 478 if (result)
479 return_VALUE(result); 479 return_VALUE(result);
480 480
481 printk(KERN_EMERG 481 printk(KERN_EMERG
482 "Critical temperature reached (%ld C), shutting down.\n", 482 "Critical temperature reached (%ld C), shutting down.\n",
483 KELVIN_TO_CELSIUS(tz->temperature)); 483 KELVIN_TO_CELSIUS(tz->temperature));
484 acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, 484 acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL,
485 tz->trips.critical.flags.enabled); 485 tz->trips.critical.flags.enabled);
486 486
487 acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); 487 acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF);
488 488
489 return_VALUE(0); 489 return_VALUE(0);
490 } 490 }
491 491
492 static int acpi_thermal_hot(struct acpi_thermal *tz) 492 static int acpi_thermal_hot(struct acpi_thermal *tz)
493 { 493 {
494 int result = 0; 494 int result = 0;
495 struct acpi_device *device = NULL; 495 struct acpi_device *device = NULL;
496 496
497 ACPI_FUNCTION_TRACE("acpi_thermal_hot"); 497 ACPI_FUNCTION_TRACE("acpi_thermal_hot");
498 498
499 if (!tz || !tz->trips.hot.flags.valid) 499 if (!tz || !tz->trips.hot.flags.valid)
500 return_VALUE(-EINVAL); 500 return_VALUE(-EINVAL);
501 501
502 if (tz->temperature >= tz->trips.hot.temperature) { 502 if (tz->temperature >= tz->trips.hot.temperature) {
503 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n")); 503 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n"));
504 tz->trips.hot.flags.enabled = 1; 504 tz->trips.hot.flags.enabled = 1;
505 } else if (tz->trips.hot.flags.enabled) 505 } else if (tz->trips.hot.flags.enabled)
506 tz->trips.hot.flags.enabled = 0; 506 tz->trips.hot.flags.enabled = 0;
507 507
508 result = acpi_bus_get_device(tz->handle, &device); 508 result = acpi_bus_get_device(tz->handle, &device);
509 if (result) 509 if (result)
510 return_VALUE(result); 510 return_VALUE(result);
511 511
512 acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, 512 acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT,
513 tz->trips.hot.flags.enabled); 513 tz->trips.hot.flags.enabled);
514 514
515 /* TBD: Call user-mode "sleep(S4)" function */ 515 /* TBD: Call user-mode "sleep(S4)" function */
516 516
517 return_VALUE(0); 517 return_VALUE(0);
518 } 518 }
519 519
520 static int acpi_thermal_passive(struct acpi_thermal *tz) 520 static void acpi_thermal_passive(struct acpi_thermal *tz)
521 { 521 {
522 int result = 0; 522 int result = 1;
523 struct acpi_thermal_passive *passive = NULL; 523 struct acpi_thermal_passive *passive = NULL;
524 int trend = 0; 524 int trend = 0;
525 int i = 0; 525 int i = 0;
526 526
527 ACPI_FUNCTION_TRACE("acpi_thermal_passive"); 527 ACPI_FUNCTION_TRACE("acpi_thermal_passive");
528 528
529 if (!tz || !tz->trips.passive.flags.valid) 529 if (!tz || !tz->trips.passive.flags.valid)
530 return_VALUE(-EINVAL); 530 return;
531 531
532 passive = &(tz->trips.passive); 532 passive = &(tz->trips.passive);
533 533
534 /* 534 /*
535 * Above Trip? 535 * Above Trip?
536 * ----------- 536 * -----------
537 * Calculate the thermal trend (using the passive cooling equation) 537 * Calculate the thermal trend (using the passive cooling equation)
538 * and modify the performance limit for all passive cooling devices 538 * and modify the performance limit for all passive cooling devices
539 * accordingly. Note that we assume symmetry. 539 * accordingly. Note that we assume symmetry.
540 */ 540 */
541 if (tz->temperature >= passive->temperature) { 541 if (tz->temperature >= passive->temperature) {
542 trend = 542 trend =
543 (passive->tc1 * (tz->temperature - tz->last_temperature)) + 543 (passive->tc1 * (tz->temperature - tz->last_temperature)) +
544 (passive->tc2 * (tz->temperature - passive->temperature)); 544 (passive->tc2 * (tz->temperature - passive->temperature));
545 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 545 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
546 "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", 546 "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
547 trend, passive->tc1, tz->temperature, 547 trend, passive->tc1, tz->temperature,
548 tz->last_temperature, passive->tc2, 548 tz->last_temperature, passive->tc2,
549 tz->temperature, passive->temperature)); 549 tz->temperature, passive->temperature));
550 tz->trips.passive.flags.enabled = 1; 550 passive->flags.enabled = 1;
551 /* Heating up? */ 551 /* Heating up? */
552 if (trend > 0) 552 if (trend > 0)
553 for (i = 0; i < passive->devices.count; i++) 553 for (i = 0; i < passive->devices.count; i++)
554 acpi_processor_set_thermal_limit(passive-> 554 acpi_processor_set_thermal_limit(passive->
555 devices. 555 devices.
556 handles[i], 556 handles[i],
557 ACPI_PROCESSOR_LIMIT_INCREMENT); 557 ACPI_PROCESSOR_LIMIT_INCREMENT);
558 /* Cooling off? */ 558 /* Cooling off? */
559 else if (trend < 0) 559 else if (trend < 0) {
560 for (i = 0; i < passive->devices.count; i++) 560 for (i = 0; i < passive->devices.count; i++)
561 acpi_processor_set_thermal_limit(passive-> 561 /*
562 devices. 562 * assume that we are on highest
563 handles[i], 563 * freq/lowest thrott and can leave
564 ACPI_PROCESSOR_LIMIT_DECREMENT); 564 * passive mode, even in error case
565 */
566 if (!acpi_processor_set_thermal_limit
567 (passive->devices.handles[i],
568 ACPI_PROCESSOR_LIMIT_DECREMENT))
569 result = 0;
570 /*
571 * Leave cooling mode, even if the temp might
572 * higher than trip point This is because some
573 * machines might have long thermal polling
574 * frequencies (tsp) defined. We will fall back
575 * into passive mode in next cycle (probably quicker)
576 */
577 if (result) {
578 passive->flags.enabled = 0;
579 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
580 "Disabling passive cooling, still above threshold,"
581 " but we are cooling down\n"));
582 }
583 }
584 return;
565 } 585 }
566 586
567 /* 587 /*
568 * Below Trip? 588 * Below Trip?
569 * ----------- 589 * -----------
570 * Implement passive cooling hysteresis to slowly increase performance 590 * Implement passive cooling hysteresis to slowly increase performance
571 * and avoid thrashing around the passive trip point. Note that we 591 * and avoid thrashing around the passive trip point. Note that we
572 * assume symmetry. 592 * assume symmetry.
573 */ 593 */
574 else if (tz->trips.passive.flags.enabled) { 594 if (!passive->flags.enabled)
575 for (i = 0; i < passive->devices.count; i++) 595 return;
576 result = 596 for (i = 0; i < passive->devices.count; i++)
577 acpi_processor_set_thermal_limit(passive->devices. 597 if (!acpi_processor_set_thermal_limit
578 handles[i], 598 (passive->devices.handles[i],
579 ACPI_PROCESSOR_LIMIT_DECREMENT); 599 ACPI_PROCESSOR_LIMIT_DECREMENT))
580 if (result == 1) { 600 result = 0;
581 tz->trips.passive.flags.enabled = 0; 601 if (result) {
582 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 602 passive->flags.enabled = 0;
583 "Disabling passive cooling (zone is cool)\n")); 603 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
584 } 604 "Disabling passive cooling (zone is cool)\n"));
585 } 605 }
586
587 return_VALUE(0);
588 } 606 }
589 607
590 static int acpi_thermal_active(struct acpi_thermal *tz) 608 static void acpi_thermal_active(struct acpi_thermal *tz)
591 { 609 {
592 int result = 0; 610 int result = 0;
593 struct acpi_thermal_active *active = NULL; 611 struct acpi_thermal_active *active = NULL;
594 int i = 0; 612 int i = 0;
595 int j = 0; 613 int j = 0;
596 unsigned long maxtemp = 0; 614 unsigned long maxtemp = 0;
597 615
598 ACPI_FUNCTION_TRACE("acpi_thermal_active"); 616 ACPI_FUNCTION_TRACE("acpi_thermal_active");
599 617
600 if (!tz) 618 if (!tz)
601 return_VALUE(-EINVAL); 619 return;
602 620
603 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 621 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
604
605 active = &(tz->trips.active[i]); 622 active = &(tz->trips.active[i]);
606 if (!active || !active->flags.valid) 623 if (!active || !active->flags.valid)
607 break; 624 break;
608
609 /*
610 * Above Threshold?
611 * ----------------
612 * If not already enabled, turn ON all cooling devices
613 * associated with this active threshold.
614 */
615 if (tz->temperature >= active->temperature) { 625 if (tz->temperature >= active->temperature) {
626 /*
627 * Above Threshold?
628 * ----------------
629 * If not already enabled, turn ON all cooling devices
630 * associated with this active threshold.
631 */
616 if (active->temperature > maxtemp) 632 if (active->temperature > maxtemp)
617 tz->state.active_index = i, maxtemp = 633 tz->state.active_index = i;
618 active->temperature; 634 maxtemp = active->temperature;
619 if (!active->flags.enabled) { 635 if (active->flags.enabled)
620 for (j = 0; j < active->devices.count; j++) { 636 continue;
621 result =
622 acpi_bus_set_power(active->devices.
623 handles[j],
624 ACPI_STATE_D0);
625 if (result) {
626 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
627 "Unable to turn cooling device [%p] 'on'\n",
628 active->
629 devices.
630 handles[j]));
631 continue;
632 }
633 active->flags.enabled = 1;
634 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
635 "Cooling device [%p] now 'on'\n",
636 active->devices.
637 handles[j]));
638 }
639 }
640 }
641 /*
642 * Below Threshold?
643 * ----------------
644 * Turn OFF all cooling devices associated with this
645 * threshold.
646 */
647 else if (active->flags.enabled) {
648 for (j = 0; j < active->devices.count; j++) { 637 for (j = 0; j < active->devices.count; j++) {
649 result = 638 result =
650 acpi_bus_set_power(active->devices. 639 acpi_bus_set_power(active->devices.
651 handles[j], 640 handles[j],
652 ACPI_STATE_D3); 641 ACPI_STATE_D0);
653 if (result) { 642 if (result) {
654 ACPI_DEBUG_PRINT((ACPI_DB_WARN, 643 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
655 "Unable to turn cooling device [%p] 'off'\n", 644 "Unable to turn cooling device [%p] 'on'\n",
656 active->devices. 645 active->devices.
657 handles[j])); 646 handles[j]));
658 continue; 647 continue;
659 } 648 }
660 active->flags.enabled = 0; 649 active->flags.enabled = 1;
661 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 650 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
662 "Cooling device [%p] now 'off'\n", 651 "Cooling device [%p] now 'on'\n",
663 active->devices.handles[j])); 652 active->devices.handles[j]));
664 } 653 }
654 continue;
665 } 655 }
656 if (!active->flags.enabled)
657 continue;
658 /*
659 * Below Threshold?
660 * ----------------
661 * Turn OFF all cooling devices associated with this
662 * threshold.
663 */
664 for (j = 0; j < active->devices.count; j++) {
665 result = acpi_bus_set_power(active->devices.handles[j],
666 ACPI_STATE_D3);
667 if (result) {
668 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
669 "Unable to turn cooling device [%p] 'off'\n",
670 active->devices.handles[j]));
671 continue;
672 }
673 active->flags.enabled = 0;
674 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
675 "Cooling device [%p] now 'off'\n",
676 active->devices.handles[j]));
677 }
666 } 678 }
667
668 return_VALUE(0);
669 } 679 }
670 680
671 static void acpi_thermal_check(void *context); 681 static void acpi_thermal_check(void *context);
672 682
673 static void acpi_thermal_run(unsigned long data) 683 static void acpi_thermal_run(unsigned long data)
674 { 684 {
675 struct acpi_thermal *tz = (struct acpi_thermal *)data; 685 struct acpi_thermal *tz = (struct acpi_thermal *)data;
676 if (!tz->zombie) 686 if (!tz->zombie)
677 acpi_os_queue_for_execution(OSD_PRIORITY_GPE, 687 acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
678 acpi_thermal_check, (void *)data); 688 acpi_thermal_check, (void *)data);
679 } 689 }
680 690
681 static void acpi_thermal_check(void *data) 691 static void acpi_thermal_check(void *data)
682 { 692 {
683 int result = 0; 693 int result = 0;
684 struct acpi_thermal *tz = (struct acpi_thermal *)data; 694 struct acpi_thermal *tz = (struct acpi_thermal *)data;
685 unsigned long sleep_time = 0; 695 unsigned long sleep_time = 0;
686 int i = 0; 696 int i = 0;
687 struct acpi_thermal_state state; 697 struct acpi_thermal_state state;
688 698
689 ACPI_FUNCTION_TRACE("acpi_thermal_check"); 699 ACPI_FUNCTION_TRACE("acpi_thermal_check");
690 700
691 if (!tz) { 701 if (!tz) {
692 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); 702 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
693 return_VOID; 703 return_VOID;
694 } 704 }
695 705
696 state = tz->state; 706 state = tz->state;
697 707
698 result = acpi_thermal_get_temperature(tz); 708 result = acpi_thermal_get_temperature(tz);
699 if (result) 709 if (result)
700 return_VOID; 710 return_VOID;
701 711
702 memset(&tz->state, 0, sizeof(tz->state)); 712 memset(&tz->state, 0, sizeof(tz->state));
703 713
704 /* 714 /*
705 * Check Trip Points 715 * Check Trip Points
706 * ----------------- 716 * -----------------
707 * Compare the current temperature to the trip point values to see 717 * Compare the current temperature to the trip point values to see
708 * if we've entered one of the thermal policy states. Note that 718 * if we've entered one of the thermal policy states. Note that
709 * this function determines when a state is entered, but the 719 * this function determines when a state is entered, but the
710 * individual policy decides when it is exited (e.g. hysteresis). 720 * individual policy decides when it is exited (e.g. hysteresis).
711 */ 721 */
712 if (tz->trips.critical.flags.valid) 722 if (tz->trips.critical.flags.valid)
713 state.critical |= 723 state.critical |=
714 (tz->temperature >= tz->trips.critical.temperature); 724 (tz->temperature >= tz->trips.critical.temperature);
715 if (tz->trips.hot.flags.valid) 725 if (tz->trips.hot.flags.valid)
716 state.hot |= (tz->temperature >= tz->trips.hot.temperature); 726 state.hot |= (tz->temperature >= tz->trips.hot.temperature);
717 if (tz->trips.passive.flags.valid) 727 if (tz->trips.passive.flags.valid)
718 state.passive |= 728 state.passive |=
719 (tz->temperature >= tz->trips.passive.temperature); 729 (tz->temperature >= tz->trips.passive.temperature);
720 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 730 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
721 if (tz->trips.active[i].flags.valid) 731 if (tz->trips.active[i].flags.valid)
722 state.active |= 732 state.active |=
723 (tz->temperature >= 733 (tz->temperature >=
724 tz->trips.active[i].temperature); 734 tz->trips.active[i].temperature);
725 735
726 /* 736 /*
727 * Invoke Policy 737 * Invoke Policy
728 * ------------- 738 * -------------
729 * Separated from the above check to allow individual policy to 739 * Separated from the above check to allow individual policy to
730 * determine when to exit a given state. 740 * determine when to exit a given state.
731 */ 741 */
732 if (state.critical) 742 if (state.critical)
733 acpi_thermal_critical(tz); 743 acpi_thermal_critical(tz);
734 if (state.hot) 744 if (state.hot)
735 acpi_thermal_hot(tz); 745 acpi_thermal_hot(tz);
736 if (state.passive) 746 if (state.passive)
737 acpi_thermal_passive(tz); 747 acpi_thermal_passive(tz);
738 if (state.active) 748 if (state.active)
739 acpi_thermal_active(tz); 749 acpi_thermal_active(tz);
740 750
741 /* 751 /*
742 * Calculate State 752 * Calculate State
743 * --------------- 753 * ---------------
744 * Again, separated from the above two to allow independent policy 754 * Again, separated from the above two to allow independent policy
745 * decisions. 755 * decisions.
746 */ 756 */
747 if (tz->trips.critical.flags.enabled) 757 tz->state.critical = tz->trips.critical.flags.enabled;
748 tz->state.critical = 1; 758 tz->state.hot = tz->trips.hot.flags.enabled;
749 if (tz->trips.hot.flags.enabled) 759 tz->state.passive = tz->trips.passive.flags.enabled;
750 tz->state.hot = 1; 760 tz->state.active = 0;
751 if (tz->trips.passive.flags.enabled)
752 tz->state.passive = 1;
753 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 761 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
754 if (tz->trips.active[i].flags.enabled) 762 tz->state.active |= tz->trips.active[i].flags.enabled;
755 tz->state.active = 1;
756 763
757 /* 764 /*
758 * Calculate Sleep Time 765 * Calculate Sleep Time
759 * -------------------- 766 * --------------------
760 * If we're in the passive state, use _TSP's value. Otherwise 767 * If we're in the passive state, use _TSP's value. Otherwise
761 * use the default polling frequency (e.g. _TZP). If no polling 768 * use the default polling frequency (e.g. _TZP). If no polling
762 * frequency is specified then we'll wait forever (at least until 769 * frequency is specified then we'll wait forever (at least until
763 * a thermal event occurs). Note that _TSP and _TZD values are 770 * a thermal event occurs). Note that _TSP and _TZD values are
764 * given in 1/10th seconds (we must covert to milliseconds). 771 * given in 1/10th seconds (we must covert to milliseconds).
765 */ 772 */
766 if (tz->state.passive) 773 if (tz->state.passive)
767 sleep_time = tz->trips.passive.tsp * 100; 774 sleep_time = tz->trips.passive.tsp * 100;
768 else if (tz->polling_frequency > 0) 775 else if (tz->polling_frequency > 0)
769 sleep_time = tz->polling_frequency * 100; 776 sleep_time = tz->polling_frequency * 100;
770 777
771 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", 778 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
772 tz->name, tz->temperature, sleep_time)); 779 tz->name, tz->temperature, sleep_time));
773 780
774 /* 781 /*
775 * Schedule Next Poll 782 * Schedule Next Poll
776 * ------------------ 783 * ------------------
777 */ 784 */
778 if (!sleep_time) { 785 if (!sleep_time) {
779 if (timer_pending(&(tz->timer))) 786 if (timer_pending(&(tz->timer)))
780 del_timer(&(tz->timer)); 787 del_timer(&(tz->timer));
781 } else { 788 } else {
782 if (timer_pending(&(tz->timer))) 789 if (timer_pending(&(tz->timer)))
783 mod_timer(&(tz->timer), (HZ * sleep_time) / 1000); 790 mod_timer(&(tz->timer), (HZ * sleep_time) / 1000);
784 else { 791 else {
785 tz->timer.data = (unsigned long)tz; 792 tz->timer.data = (unsigned long)tz;
786 tz->timer.function = acpi_thermal_run; 793 tz->timer.function = acpi_thermal_run;
787 tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; 794 tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
788 add_timer(&(tz->timer)); 795 add_timer(&(tz->timer));
789 } 796 }
790 } 797 }
791 798
792 return_VOID; 799 return_VOID;
793 } 800 }
794 801
795 /* -------------------------------------------------------------------------- 802 /* --------------------------------------------------------------------------
796 FS Interface (/proc) 803 FS Interface (/proc)
797 -------------------------------------------------------------------------- */ 804 -------------------------------------------------------------------------- */
798 805
799 static struct proc_dir_entry *acpi_thermal_dir; 806 static struct proc_dir_entry *acpi_thermal_dir;
800 807
801 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 808 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
802 { 809 {
803 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 810 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
804 811
805 ACPI_FUNCTION_TRACE("acpi_thermal_state_seq_show"); 812 ACPI_FUNCTION_TRACE("acpi_thermal_state_seq_show");
806 813
807 if (!tz) 814 if (!tz)
808 goto end; 815 goto end;
809 816
810 seq_puts(seq, "state: "); 817 seq_puts(seq, "state: ");
811 818
812 if (!tz->state.critical && !tz->state.hot && !tz->state.passive 819 if (!tz->state.critical && !tz->state.hot && !tz->state.passive
813 && !tz->state.active) 820 && !tz->state.active)
814 seq_puts(seq, "ok\n"); 821 seq_puts(seq, "ok\n");
815 else { 822 else {
816 if (tz->state.critical) 823 if (tz->state.critical)
817 seq_puts(seq, "critical "); 824 seq_puts(seq, "critical ");
818 if (tz->state.hot) 825 if (tz->state.hot)
819 seq_puts(seq, "hot "); 826 seq_puts(seq, "hot ");
820 if (tz->state.passive) 827 if (tz->state.passive)
821 seq_puts(seq, "passive "); 828 seq_puts(seq, "passive ");
822 if (tz->state.active) 829 if (tz->state.active)
823 seq_printf(seq, "active[%d]", tz->state.active_index); 830 seq_printf(seq, "active[%d]", tz->state.active_index);
824 seq_puts(seq, "\n"); 831 seq_puts(seq, "\n");
825 } 832 }
826 833
827 end: 834 end:
828 return_VALUE(0); 835 return_VALUE(0);
829 } 836 }
830 837
831 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) 838 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
832 { 839 {
833 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); 840 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
834 } 841 }
835 842
836 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) 843 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
837 { 844 {
838 int result = 0; 845 int result = 0;
839 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 846 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
840 847
841 ACPI_FUNCTION_TRACE("acpi_thermal_temp_seq_show"); 848 ACPI_FUNCTION_TRACE("acpi_thermal_temp_seq_show");
842 849
843 if (!tz) 850 if (!tz)
844 goto end; 851 goto end;
845 852
846 result = acpi_thermal_get_temperature(tz); 853 result = acpi_thermal_get_temperature(tz);
847 if (result) 854 if (result)
848 goto end; 855 goto end;
849 856
850 seq_printf(seq, "temperature: %ld C\n", 857 seq_printf(seq, "temperature: %ld C\n",
851 KELVIN_TO_CELSIUS(tz->temperature)); 858 KELVIN_TO_CELSIUS(tz->temperature));
852 859
853 end: 860 end:
854 return_VALUE(0); 861 return_VALUE(0);
855 } 862 }
856 863
857 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) 864 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
858 { 865 {
859 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); 866 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
860 } 867 }
861 868
862 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) 869 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
863 { 870 {
864 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 871 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
865 int i = 0; 872 int i = 0;
866 int j = 0; 873 int j = 0;
867 874
868 ACPI_FUNCTION_TRACE("acpi_thermal_trip_seq_show"); 875 ACPI_FUNCTION_TRACE("acpi_thermal_trip_seq_show");
869 876
870 if (!tz) 877 if (!tz)
871 goto end; 878 goto end;
872 879
873 if (tz->trips.critical.flags.valid) 880 if (tz->trips.critical.flags.valid)
874 seq_printf(seq, "critical (S5): %ld C\n", 881 seq_printf(seq, "critical (S5): %ld C\n",
875 KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); 882 KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
876 883
877 if (tz->trips.hot.flags.valid) 884 if (tz->trips.hot.flags.valid)
878 seq_printf(seq, "hot (S4): %ld C\n", 885 seq_printf(seq, "hot (S4): %ld C\n",
879 KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); 886 KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
880 887
881 if (tz->trips.passive.flags.valid) { 888 if (tz->trips.passive.flags.valid) {
882 seq_printf(seq, 889 seq_printf(seq,
883 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", 890 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
884 KELVIN_TO_CELSIUS(tz->trips.passive.temperature), 891 KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
885 tz->trips.passive.tc1, tz->trips.passive.tc2, 892 tz->trips.passive.tc1, tz->trips.passive.tc2,
886 tz->trips.passive.tsp); 893 tz->trips.passive.tsp);
887 for (j = 0; j < tz->trips.passive.devices.count; j++) { 894 for (j = 0; j < tz->trips.passive.devices.count; j++) {
888 895
889 seq_printf(seq, "0x%p ", 896 seq_printf(seq, "0x%p ",
890 tz->trips.passive.devices.handles[j]); 897 tz->trips.passive.devices.handles[j]);
891 } 898 }
892 seq_puts(seq, "\n"); 899 seq_puts(seq, "\n");
893 } 900 }
894 901
895 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 902 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
896 if (!(tz->trips.active[i].flags.valid)) 903 if (!(tz->trips.active[i].flags.valid))
897 break; 904 break;
898 seq_printf(seq, "active[%d]: %ld C: devices=", 905 seq_printf(seq, "active[%d]: %ld C: devices=",
899 i, 906 i,
900 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); 907 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
901 for (j = 0; j < tz->trips.active[i].devices.count; j++) 908 for (j = 0; j < tz->trips.active[i].devices.count; j++)
902 seq_printf(seq, "0x%p ", 909 seq_printf(seq, "0x%p ",
903 tz->trips.active[i].devices.handles[j]); 910 tz->trips.active[i].devices.handles[j]);
904 seq_puts(seq, "\n"); 911 seq_puts(seq, "\n");
905 } 912 }
906 913
907 end: 914 end:
908 return_VALUE(0); 915 return_VALUE(0);
909 } 916 }
910 917
911 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) 918 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
912 { 919 {
913 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); 920 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
914 } 921 }
915 922
916 static ssize_t 923 static ssize_t
917 acpi_thermal_write_trip_points(struct file *file, 924 acpi_thermal_write_trip_points(struct file *file,
918 const char __user * buffer, 925 const char __user * buffer,
919 size_t count, loff_t * ppos) 926 size_t count, loff_t * ppos)
920 { 927 {
921 struct seq_file *m = (struct seq_file *)file->private_data; 928 struct seq_file *m = (struct seq_file *)file->private_data;
922 struct acpi_thermal *tz = (struct acpi_thermal *)m->private; 929 struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
923 930
924 char *limit_string; 931 char *limit_string;
925 int num, critical, hot, passive; 932 int num, critical, hot, passive;
926 int *active; 933 int *active;
927 int i = 0; 934 int i = 0;
928 935
929 ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points"); 936 ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
930 937
931 limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL); 938 limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
932 if (!limit_string) 939 if (!limit_string)
933 return_VALUE(-ENOMEM); 940 return_VALUE(-ENOMEM);
934 941
935 memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN); 942 memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
936 943
937 active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL); 944 active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL);
938 if (!active) 945 if (!active)
939 return_VALUE(-ENOMEM); 946 return_VALUE(-ENOMEM);
940 947
941 if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) { 948 if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) {
942 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n")); 949 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
943 count = -EINVAL; 950 count = -EINVAL;
944 goto end; 951 goto end;
945 } 952 }
946 953
947 if (copy_from_user(limit_string, buffer, count)) { 954 if (copy_from_user(limit_string, buffer, count)) {
948 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); 955 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
949 count = -EFAULT; 956 count = -EFAULT;
950 goto end; 957 goto end;
951 } 958 }
952 959
953 limit_string[count] = '\0'; 960 limit_string[count] = '\0';
954 961
955 num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", 962 num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
956 &critical, &hot, &passive, 963 &critical, &hot, &passive,
957 &active[0], &active[1], &active[2], &active[3], &active[4], 964 &active[0], &active[1], &active[2], &active[3], &active[4],
958 &active[5], &active[6], &active[7], &active[8], 965 &active[5], &active[6], &active[7], &active[8],
959 &active[9]); 966 &active[9]);
960 if (!(num >= 5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) { 967 if (!(num >= 5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
961 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); 968 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
962 count = -EINVAL; 969 count = -EINVAL;
963 goto end; 970 goto end;
964 } 971 }
965 972
966 tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical); 973 tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);
967 tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot); 974 tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot);
968 tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive); 975 tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive);
969 for (i = 0; i < num - 3; i++) { 976 for (i = 0; i < num - 3; i++) {
970 if (!(tz->trips.active[i].flags.valid)) 977 if (!(tz->trips.active[i].flags.valid))
971 break; 978 break;
972 tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]); 979 tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
973 } 980 }
974 981
975 end: 982 end:
976 kfree(active); 983 kfree(active);
977 kfree(limit_string); 984 kfree(limit_string);
978 return_VALUE(count); 985 return_VALUE(count);
979 } 986 }
980 987
981 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) 988 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
982 { 989 {
983 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 990 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
984 991
985 ACPI_FUNCTION_TRACE("acpi_thermal_cooling_seq_show"); 992 ACPI_FUNCTION_TRACE("acpi_thermal_cooling_seq_show");
986 993
987 if (!tz) 994 if (!tz)
988 goto end; 995 goto end;
989 996
990 if (!tz->flags.cooling_mode) { 997 if (!tz->flags.cooling_mode) {
991 seq_puts(seq, "<setting not supported>\n"); 998 seq_puts(seq, "<setting not supported>\n");
992 } 999 }
993 1000
994 if (tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL) 1001 if (tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL)
995 seq_printf(seq, "cooling mode: critical\n"); 1002 seq_printf(seq, "cooling mode: critical\n");
996 else 1003 else
997 seq_printf(seq, "cooling mode: %s\n", 1004 seq_printf(seq, "cooling mode: %s\n",
998 tz->cooling_mode ? "passive" : "active"); 1005 tz->cooling_mode ? "passive" : "active");
999 1006
1000 end: 1007 end:
1001 return_VALUE(0); 1008 return_VALUE(0);
1002 } 1009 }
1003 1010
1004 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) 1011 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
1005 { 1012 {
1006 return single_open(file, acpi_thermal_cooling_seq_show, 1013 return single_open(file, acpi_thermal_cooling_seq_show,
1007 PDE(inode)->data); 1014 PDE(inode)->data);
1008 } 1015 }
1009 1016
1010 static ssize_t 1017 static ssize_t
1011 acpi_thermal_write_cooling_mode(struct file *file, 1018 acpi_thermal_write_cooling_mode(struct file *file,
1012 const char __user * buffer, 1019 const char __user * buffer,
1013 size_t count, loff_t * ppos) 1020 size_t count, loff_t * ppos)
1014 { 1021 {
1015 struct seq_file *m = (struct seq_file *)file->private_data; 1022 struct seq_file *m = (struct seq_file *)file->private_data;
1016 struct acpi_thermal *tz = (struct acpi_thermal *)m->private; 1023 struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
1017 int result = 0; 1024 int result = 0;
1018 char mode_string[12] = { '\0' }; 1025 char mode_string[12] = { '\0' };
1019 1026
1020 ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode"); 1027 ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode");
1021 1028
1022 if (!tz || (count > sizeof(mode_string) - 1)) 1029 if (!tz || (count > sizeof(mode_string) - 1))
1023 return_VALUE(-EINVAL); 1030 return_VALUE(-EINVAL);
1024 1031
1025 if (!tz->flags.cooling_mode) 1032 if (!tz->flags.cooling_mode)
1026 return_VALUE(-ENODEV); 1033 return_VALUE(-ENODEV);
1027 1034
1028 if (copy_from_user(mode_string, buffer, count)) 1035 if (copy_from_user(mode_string, buffer, count))
1029 return_VALUE(-EFAULT); 1036 return_VALUE(-EFAULT);
1030 1037
1031 mode_string[count] = '\0'; 1038 mode_string[count] = '\0';
1032 1039
1033 result = acpi_thermal_set_cooling_mode(tz, 1040 result = acpi_thermal_set_cooling_mode(tz,
1034 simple_strtoul(mode_string, NULL, 1041 simple_strtoul(mode_string, NULL,
1035 0)); 1042 0));
1036 if (result) 1043 if (result)
1037 return_VALUE(result); 1044 return_VALUE(result);
1038 1045
1039 acpi_thermal_check(tz); 1046 acpi_thermal_check(tz);
1040 1047
1041 return_VALUE(count); 1048 return_VALUE(count);
1042 } 1049 }
1043 1050
1044 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) 1051 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1045 { 1052 {
1046 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 1053 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
1047 1054
1048 ACPI_FUNCTION_TRACE("acpi_thermal_polling_seq_show"); 1055 ACPI_FUNCTION_TRACE("acpi_thermal_polling_seq_show");
1049 1056
1050 if (!tz) 1057 if (!tz)
1051 goto end; 1058 goto end;
1052 1059
1053 if (!tz->polling_frequency) { 1060 if (!tz->polling_frequency) {
1054 seq_puts(seq, "<polling disabled>\n"); 1061 seq_puts(seq, "<polling disabled>\n");
1055 goto end; 1062 goto end;
1056 } 1063 }
1057 1064
1058 seq_printf(seq, "polling frequency: %lu seconds\n", 1065 seq_printf(seq, "polling frequency: %lu seconds\n",
1059 (tz->polling_frequency / 10)); 1066 (tz->polling_frequency / 10));
1060 1067
1061 end: 1068 end:
1062 return_VALUE(0); 1069 return_VALUE(0);
1063 } 1070 }
1064 1071
1065 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) 1072 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
1066 { 1073 {
1067 return single_open(file, acpi_thermal_polling_seq_show, 1074 return single_open(file, acpi_thermal_polling_seq_show,
1068 PDE(inode)->data); 1075 PDE(inode)->data);
1069 } 1076 }
1070 1077
1071 static ssize_t 1078 static ssize_t
1072 acpi_thermal_write_polling(struct file *file, 1079 acpi_thermal_write_polling(struct file *file,
1073 const char __user * buffer, 1080 const char __user * buffer,
1074 size_t count, loff_t * ppos) 1081 size_t count, loff_t * ppos)
1075 { 1082 {
1076 struct seq_file *m = (struct seq_file *)file->private_data; 1083 struct seq_file *m = (struct seq_file *)file->private_data;
1077 struct acpi_thermal *tz = (struct acpi_thermal *)m->private; 1084 struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
1078 int result = 0; 1085 int result = 0;
1079 char polling_string[12] = { '\0' }; 1086 char polling_string[12] = { '\0' };
1080 int seconds = 0; 1087 int seconds = 0;
1081 1088
1082 ACPI_FUNCTION_TRACE("acpi_thermal_write_polling"); 1089 ACPI_FUNCTION_TRACE("acpi_thermal_write_polling");
1083 1090
1084 if (!tz || (count > sizeof(polling_string) - 1)) 1091 if (!tz || (count > sizeof(polling_string) - 1))
1085 return_VALUE(-EINVAL); 1092 return_VALUE(-EINVAL);
1086 1093
1087 if (copy_from_user(polling_string, buffer, count)) 1094 if (copy_from_user(polling_string, buffer, count))
1088 return_VALUE(-EFAULT); 1095 return_VALUE(-EFAULT);
1089 1096
1090 polling_string[count] = '\0'; 1097 polling_string[count] = '\0';
1091 1098
1092 seconds = simple_strtoul(polling_string, NULL, 0); 1099 seconds = simple_strtoul(polling_string, NULL, 0);
1093 1100
1094 result = acpi_thermal_set_polling(tz, seconds); 1101 result = acpi_thermal_set_polling(tz, seconds);
1095 if (result) 1102 if (result)
1096 return_VALUE(result); 1103 return_VALUE(result);
1097 1104
1098 acpi_thermal_check(tz); 1105 acpi_thermal_check(tz);
1099 1106
1100 return_VALUE(count); 1107 return_VALUE(count);
1101 } 1108 }
1102 1109
1103 static int acpi_thermal_add_fs(struct acpi_device *device) 1110 static int acpi_thermal_add_fs(struct acpi_device *device)
1104 { 1111 {
1105 struct proc_dir_entry *entry = NULL; 1112 struct proc_dir_entry *entry = NULL;
1106 1113
1107 ACPI_FUNCTION_TRACE("acpi_thermal_add_fs"); 1114 ACPI_FUNCTION_TRACE("acpi_thermal_add_fs");
1108 1115
1109 if (!acpi_device_dir(device)) { 1116 if (!acpi_device_dir(device)) {
1110 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1117 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1111 acpi_thermal_dir); 1118 acpi_thermal_dir);
1112 if (!acpi_device_dir(device)) 1119 if (!acpi_device_dir(device))
1113 return_VALUE(-ENODEV); 1120 return_VALUE(-ENODEV);
1114 acpi_device_dir(device)->owner = THIS_MODULE; 1121 acpi_device_dir(device)->owner = THIS_MODULE;
1115 } 1122 }
1116 1123
1117 /* 'state' [R] */ 1124 /* 'state' [R] */
1118 entry = create_proc_entry(ACPI_THERMAL_FILE_STATE, 1125 entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,
1119 S_IRUGO, acpi_device_dir(device)); 1126 S_IRUGO, acpi_device_dir(device));
1120 if (!entry) 1127 if (!entry)
1121 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1128 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1122 "Unable to create '%s' fs entry\n", 1129 "Unable to create '%s' fs entry\n",
1123 ACPI_THERMAL_FILE_STATE)); 1130 ACPI_THERMAL_FILE_STATE));
1124 else { 1131 else {
1125 entry->proc_fops = &acpi_thermal_state_fops; 1132 entry->proc_fops = &acpi_thermal_state_fops;
1126 entry->data = acpi_driver_data(device); 1133 entry->data = acpi_driver_data(device);
1127 entry->owner = THIS_MODULE; 1134 entry->owner = THIS_MODULE;
1128 } 1135 }
1129 1136
1130 /* 'temperature' [R] */ 1137 /* 'temperature' [R] */
1131 entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1138 entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1132 S_IRUGO, acpi_device_dir(device)); 1139 S_IRUGO, acpi_device_dir(device));
1133 if (!entry) 1140 if (!entry)
1134 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1141 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1135 "Unable to create '%s' fs entry\n", 1142 "Unable to create '%s' fs entry\n",
1136 ACPI_THERMAL_FILE_TEMPERATURE)); 1143 ACPI_THERMAL_FILE_TEMPERATURE));
1137 else { 1144 else {
1138 entry->proc_fops = &acpi_thermal_temp_fops; 1145 entry->proc_fops = &acpi_thermal_temp_fops;
1139 entry->data = acpi_driver_data(device); 1146 entry->data = acpi_driver_data(device);
1140 entry->owner = THIS_MODULE; 1147 entry->owner = THIS_MODULE;
1141 } 1148 }
1142 1149
1143 /* 'trip_points' [R/W] */ 1150 /* 'trip_points' [R/W] */
1144 entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1151 entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1145 S_IFREG | S_IRUGO | S_IWUSR, 1152 S_IFREG | S_IRUGO | S_IWUSR,
1146 acpi_device_dir(device)); 1153 acpi_device_dir(device));
1147 if (!entry) 1154 if (!entry)
1148 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1155 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1149 "Unable to create '%s' fs entry\n", 1156 "Unable to create '%s' fs entry\n",
1150 ACPI_THERMAL_FILE_TRIP_POINTS)); 1157 ACPI_THERMAL_FILE_TRIP_POINTS));
1151 else { 1158 else {
1152 entry->proc_fops = &acpi_thermal_trip_fops; 1159 entry->proc_fops = &acpi_thermal_trip_fops;
1153 entry->data = acpi_driver_data(device); 1160 entry->data = acpi_driver_data(device);
1154 entry->owner = THIS_MODULE; 1161 entry->owner = THIS_MODULE;
1155 } 1162 }
1156 1163
1157 /* 'cooling_mode' [R/W] */ 1164 /* 'cooling_mode' [R/W] */
1158 entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1165 entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1159 S_IFREG | S_IRUGO | S_IWUSR, 1166 S_IFREG | S_IRUGO | S_IWUSR,
1160 acpi_device_dir(device)); 1167 acpi_device_dir(device));
1161 if (!entry) 1168 if (!entry)
1162 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1169 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1163 "Unable to create '%s' fs entry\n", 1170 "Unable to create '%s' fs entry\n",
1164 ACPI_THERMAL_FILE_COOLING_MODE)); 1171 ACPI_THERMAL_FILE_COOLING_MODE));
1165 else { 1172 else {
1166 entry->proc_fops = &acpi_thermal_cooling_fops; 1173 entry->proc_fops = &acpi_thermal_cooling_fops;
1167 entry->data = acpi_driver_data(device); 1174 entry->data = acpi_driver_data(device);
1168 entry->owner = THIS_MODULE; 1175 entry->owner = THIS_MODULE;
1169 } 1176 }
1170 1177
1171 /* 'polling_frequency' [R/W] */ 1178 /* 'polling_frequency' [R/W] */
1172 entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1179 entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1173 S_IFREG | S_IRUGO | S_IWUSR, 1180 S_IFREG | S_IRUGO | S_IWUSR,
1174 acpi_device_dir(device)); 1181 acpi_device_dir(device));
1175 if (!entry) 1182 if (!entry)
1176 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1183 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1177 "Unable to create '%s' fs entry\n", 1184 "Unable to create '%s' fs entry\n",
1178 ACPI_THERMAL_FILE_POLLING_FREQ)); 1185 ACPI_THERMAL_FILE_POLLING_FREQ));
1179 else { 1186 else {
1180 entry->proc_fops = &acpi_thermal_polling_fops; 1187 entry->proc_fops = &acpi_thermal_polling_fops;
1181 entry->data = acpi_driver_data(device); 1188 entry->data = acpi_driver_data(device);
1182 entry->owner = THIS_MODULE; 1189 entry->owner = THIS_MODULE;
1183 } 1190 }
1184 1191
1185 return_VALUE(0); 1192 return_VALUE(0);
1186 } 1193 }
1187 1194
1188 static int acpi_thermal_remove_fs(struct acpi_device *device) 1195 static int acpi_thermal_remove_fs(struct acpi_device *device)
1189 { 1196 {
1190 ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs"); 1197 ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs");
1191 1198
1192 if (acpi_device_dir(device)) { 1199 if (acpi_device_dir(device)) {
1193 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1200 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1194 acpi_device_dir(device)); 1201 acpi_device_dir(device));
1195 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1202 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1196 acpi_device_dir(device)); 1203 acpi_device_dir(device));
1197 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1204 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1198 acpi_device_dir(device)); 1205 acpi_device_dir(device));
1199 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1206 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1200 acpi_device_dir(device)); 1207 acpi_device_dir(device));
1201 remove_proc_entry(ACPI_THERMAL_FILE_STATE, 1208 remove_proc_entry(ACPI_THERMAL_FILE_STATE,
1202 acpi_device_dir(device)); 1209 acpi_device_dir(device));
1203 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); 1210 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
1204 acpi_device_dir(device) = NULL; 1211 acpi_device_dir(device) = NULL;
1205 } 1212 }
1206 1213
1207 return_VALUE(0); 1214 return_VALUE(0);
1208 } 1215 }
1209 1216
1210 /* -------------------------------------------------------------------------- 1217 /* --------------------------------------------------------------------------
1211 Driver Interface 1218 Driver Interface
1212 -------------------------------------------------------------------------- */ 1219 -------------------------------------------------------------------------- */
1213 1220
1214 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 1221 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
1215 { 1222 {
1216 struct acpi_thermal *tz = (struct acpi_thermal *)data; 1223 struct acpi_thermal *tz = (struct acpi_thermal *)data;
1217 struct acpi_device *device = NULL; 1224 struct acpi_device *device = NULL;
1218 1225
1219 ACPI_FUNCTION_TRACE("acpi_thermal_notify"); 1226 ACPI_FUNCTION_TRACE("acpi_thermal_notify");
1220 1227
1221 if (!tz) 1228 if (!tz)
1222 return_VOID; 1229 return_VOID;
1223 1230
1224 if (acpi_bus_get_device(tz->handle, &device)) 1231 if (acpi_bus_get_device(tz->handle, &device))
1225 return_VOID; 1232 return_VOID;
1226 1233
1227 switch (event) { 1234 switch (event) {
1228 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 1235 case ACPI_THERMAL_NOTIFY_TEMPERATURE:
1229 acpi_thermal_check(tz); 1236 acpi_thermal_check(tz);
1230 break; 1237 break;
1231 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 1238 case ACPI_THERMAL_NOTIFY_THRESHOLDS:
1232 acpi_thermal_get_trip_points(tz); 1239 acpi_thermal_get_trip_points(tz);
1233 acpi_thermal_check(tz); 1240 acpi_thermal_check(tz);
1234 acpi_bus_generate_event(device, event, 0); 1241 acpi_bus_generate_event(device, event, 0);
1235 break; 1242 break;
1236 case ACPI_THERMAL_NOTIFY_DEVICES: 1243 case ACPI_THERMAL_NOTIFY_DEVICES:
1237 if (tz->flags.devices) 1244 if (tz->flags.devices)
1238 acpi_thermal_get_devices(tz); 1245 acpi_thermal_get_devices(tz);
1239 acpi_bus_generate_event(device, event, 0); 1246 acpi_bus_generate_event(device, event, 0);
1240 break; 1247 break;
1241 default: 1248 default:
1242 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1249 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1243 "Unsupported event [0x%x]\n", event)); 1250 "Unsupported event [0x%x]\n", event));
1244 break; 1251 break;
1245 } 1252 }
1246 1253
1247 return_VOID; 1254 return_VOID;
1248 } 1255 }
1249 1256
1250 static int acpi_thermal_get_info(struct acpi_thermal *tz) 1257 static int acpi_thermal_get_info(struct acpi_thermal *tz)
1251 { 1258 {
1252 int result = 0; 1259 int result = 0;
1253 1260
1254 ACPI_FUNCTION_TRACE("acpi_thermal_get_info"); 1261 ACPI_FUNCTION_TRACE("acpi_thermal_get_info");
1255 1262
1256 if (!tz) 1263 if (!tz)
1257 return_VALUE(-EINVAL); 1264 return_VALUE(-EINVAL);
1258 1265
1259 /* Get temperature [_TMP] (required) */ 1266 /* Get temperature [_TMP] (required) */
1260 result = acpi_thermal_get_temperature(tz); 1267 result = acpi_thermal_get_temperature(tz);
1261 if (result) 1268 if (result)
1262 return_VALUE(result); 1269 return_VALUE(result);
1263 1270
1264 /* Get trip points [_CRT, _PSV, etc.] (required) */ 1271 /* Get trip points [_CRT, _PSV, etc.] (required) */
1265 result = acpi_thermal_get_trip_points(tz); 1272 result = acpi_thermal_get_trip_points(tz);
1266 if (result) 1273 if (result)
1267 return_VALUE(result); 1274 return_VALUE(result);
1268 1275
1269 /* Set the cooling mode [_SCP] to active cooling (default) */ 1276 /* Set the cooling mode [_SCP] to active cooling (default) */
1270 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); 1277 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
1271 if (!result) 1278 if (!result)
1272 tz->flags.cooling_mode = 1; 1279 tz->flags.cooling_mode = 1;
1273 else { 1280 else {
1274 /* Oh,we have not _SCP method. 1281 /* Oh,we have not _SCP method.
1275 Generally show cooling_mode by _ACx, _PSV,spec 12.2 */ 1282 Generally show cooling_mode by _ACx, _PSV,spec 12.2 */
1276 tz->flags.cooling_mode = 0; 1283 tz->flags.cooling_mode = 0;
1277 if (tz->trips.active[0].flags.valid 1284 if (tz->trips.active[0].flags.valid
1278 && tz->trips.passive.flags.valid) { 1285 && tz->trips.passive.flags.valid) {
1279 if (tz->trips.passive.temperature > 1286 if (tz->trips.passive.temperature >
1280 tz->trips.active[0].temperature) 1287 tz->trips.active[0].temperature)
1281 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; 1288 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
1282 else 1289 else
1283 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; 1290 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
1284 } else if (!tz->trips.active[0].flags.valid 1291 } else if (!tz->trips.active[0].flags.valid
1285 && tz->trips.passive.flags.valid) { 1292 && tz->trips.passive.flags.valid) {
1286 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; 1293 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
1287 } else if (tz->trips.active[0].flags.valid 1294 } else if (tz->trips.active[0].flags.valid
1288 && !tz->trips.passive.flags.valid) { 1295 && !tz->trips.passive.flags.valid) {
1289 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; 1296 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
1290 } else { 1297 } else {
1291 /* _ACx and _PSV are optional, but _CRT is required */ 1298 /* _ACx and _PSV are optional, but _CRT is required */
1292 tz->cooling_mode = ACPI_THERMAL_MODE_CRITICAL; 1299 tz->cooling_mode = ACPI_THERMAL_MODE_CRITICAL;
1293 } 1300 }
1294 } 1301 }
1295 1302
1296 /* Get default polling frequency [_TZP] (optional) */ 1303 /* Get default polling frequency [_TZP] (optional) */
1297 if (tzp) 1304 if (tzp)
1298 tz->polling_frequency = tzp; 1305 tz->polling_frequency = tzp;
1299 else 1306 else
1300 acpi_thermal_get_polling_frequency(tz); 1307 acpi_thermal_get_polling_frequency(tz);
1301 1308
1302 /* Get devices in this thermal zone [_TZD] (optional) */ 1309 /* Get devices in this thermal zone [_TZD] (optional) */
1303 result = acpi_thermal_get_devices(tz); 1310 result = acpi_thermal_get_devices(tz);
1304 if (!result) 1311 if (!result)
1305 tz->flags.devices = 1; 1312 tz->flags.devices = 1;
1306 1313
1307 return_VALUE(0); 1314 return_VALUE(0);
1308 } 1315 }
1309 1316
1310 static int acpi_thermal_add(struct acpi_device *device) 1317 static int acpi_thermal_add(struct acpi_device *device)
1311 { 1318 {
1312 int result = 0; 1319 int result = 0;
1313 acpi_status status = AE_OK; 1320 acpi_status status = AE_OK;
1314 struct acpi_thermal *tz = NULL; 1321 struct acpi_thermal *tz = NULL;
1315 1322
1316 ACPI_FUNCTION_TRACE("acpi_thermal_add"); 1323 ACPI_FUNCTION_TRACE("acpi_thermal_add");
1317 1324
1318 if (!device) 1325 if (!device)
1319 return_VALUE(-EINVAL); 1326 return_VALUE(-EINVAL);
1320 1327
1321 tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 1328 tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
1322 if (!tz) 1329 if (!tz)
1323 return_VALUE(-ENOMEM); 1330 return_VALUE(-ENOMEM);
1324 memset(tz, 0, sizeof(struct acpi_thermal)); 1331 memset(tz, 0, sizeof(struct acpi_thermal));
1325 1332
1326 tz->handle = device->handle; 1333 tz->handle = device->handle;
1327 strcpy(tz->name, device->pnp.bus_id); 1334 strcpy(tz->name, device->pnp.bus_id);
1328 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1335 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1329 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1336 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1330 acpi_driver_data(device) = tz; 1337 acpi_driver_data(device) = tz;
1331 1338
1332 result = acpi_thermal_get_info(tz); 1339 result = acpi_thermal_get_info(tz);
1333 if (result) 1340 if (result)
1334 goto end; 1341 goto end;
1335 1342
1336 result = acpi_thermal_add_fs(device); 1343 result = acpi_thermal_add_fs(device);
1337 if (result) 1344 if (result)
1338 return_VALUE(result); 1345 return_VALUE(result);
1339 1346
1340 init_timer(&tz->timer); 1347 init_timer(&tz->timer);
1341 1348
1342 acpi_thermal_check(tz); 1349 acpi_thermal_check(tz);
1343 1350
1344 status = acpi_install_notify_handler(tz->handle, 1351 status = acpi_install_notify_handler(tz->handle,
1345 ACPI_DEVICE_NOTIFY, 1352 ACPI_DEVICE_NOTIFY,
1346 acpi_thermal_notify, tz); 1353 acpi_thermal_notify, tz);
1347 if (ACPI_FAILURE(status)) { 1354 if (ACPI_FAILURE(status)) {
1348 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1355 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1349 "Error installing notify handler\n")); 1356 "Error installing notify handler\n"));
1350 result = -ENODEV; 1357 result = -ENODEV;
1351 goto end; 1358 goto end;
1352 } 1359 }
1353 1360
1354 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", 1361 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
1355 acpi_device_name(device), acpi_device_bid(device), 1362 acpi_device_name(device), acpi_device_bid(device),
1356 KELVIN_TO_CELSIUS(tz->temperature)); 1363 KELVIN_TO_CELSIUS(tz->temperature));
1357 1364
1358 end: 1365 end:
1359 if (result) { 1366 if (result) {
1360 acpi_thermal_remove_fs(device); 1367 acpi_thermal_remove_fs(device);
1361 kfree(tz); 1368 kfree(tz);
1362 } 1369 }
1363 1370
1364 return_VALUE(result); 1371 return_VALUE(result);
1365 } 1372 }
1366 1373
1367 static int acpi_thermal_remove(struct acpi_device *device, int type) 1374 static int acpi_thermal_remove(struct acpi_device *device, int type)
1368 { 1375 {
1369 acpi_status status = AE_OK; 1376 acpi_status status = AE_OK;
1370 struct acpi_thermal *tz = NULL; 1377 struct acpi_thermal *tz = NULL;
1371 1378
1372 ACPI_FUNCTION_TRACE("acpi_thermal_remove"); 1379 ACPI_FUNCTION_TRACE("acpi_thermal_remove");
1373 1380
1374 if (!device || !acpi_driver_data(device)) 1381 if (!device || !acpi_driver_data(device))
1375 return_VALUE(-EINVAL); 1382 return_VALUE(-EINVAL);
1376 1383
1377 tz = (struct acpi_thermal *)acpi_driver_data(device); 1384 tz = (struct acpi_thermal *)acpi_driver_data(device);
1378 1385
1379 /* avoid timer adding new defer task */ 1386 /* avoid timer adding new defer task */
1380 tz->zombie = 1; 1387 tz->zombie = 1;
1381 /* wait for running timer (on other CPUs) finish */ 1388 /* wait for running timer (on other CPUs) finish */
1382 del_timer_sync(&(tz->timer)); 1389 del_timer_sync(&(tz->timer));
1383 /* synchronize deferred task */ 1390 /* synchronize deferred task */
1384 acpi_os_wait_events_complete(NULL); 1391 acpi_os_wait_events_complete(NULL);
1385 /* deferred task may reinsert timer */ 1392 /* deferred task may reinsert timer */
1386 del_timer_sync(&(tz->timer)); 1393 del_timer_sync(&(tz->timer));
1387 1394
1388 status = acpi_remove_notify_handler(tz->handle, 1395 status = acpi_remove_notify_handler(tz->handle,
1389 ACPI_DEVICE_NOTIFY, 1396 ACPI_DEVICE_NOTIFY,
1390 acpi_thermal_notify); 1397 acpi_thermal_notify);
1391 if (ACPI_FAILURE(status)) 1398 if (ACPI_FAILURE(status))
1392 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1399 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1393 "Error removing notify handler\n")); 1400 "Error removing notify handler\n"));
1394 1401
1395 /* Terminate policy */ 1402 /* Terminate policy */
1396 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { 1403 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
1397 tz->trips.passive.flags.enabled = 0; 1404 tz->trips.passive.flags.enabled = 0;
1398 acpi_thermal_passive(tz); 1405 acpi_thermal_passive(tz);
1399 } 1406 }
1400 if (tz->trips.active[0].flags.valid 1407 if (tz->trips.active[0].flags.valid
1401 && tz->trips.active[0].flags.enabled) { 1408 && tz->trips.active[0].flags.enabled) {
1402 tz->trips.active[0].flags.enabled = 0; 1409 tz->trips.active[0].flags.enabled = 0;
1403 acpi_thermal_active(tz); 1410 acpi_thermal_active(tz);