aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh/therm_windtunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh/therm_windtunnel.c')
-rw-r--r--drivers/macintosh/therm_windtunnel.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index b66da74caa55..d11821af3b8d 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -36,6 +36,7 @@
36#include <linux/i2c.h> 36#include <linux/i2c.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/kthread.h>
39 40
40#include <asm/prom.h> 41#include <asm/prom.h>
41#include <asm/machdep.h> 42#include <asm/machdep.h>
@@ -59,8 +60,7 @@ I2C_CLIENT_INSMOD;
59 60
60static struct { 61static struct {
61 volatile int running; 62 volatile int running;
62 struct completion completion; 63 struct task_struct *poll_task;
63 pid_t poll_task;
64 64
65 struct semaphore lock; 65 struct semaphore lock;
66 struct of_device *of_dev; 66 struct of_device *of_dev;
@@ -221,6 +221,7 @@ static void
221setup_hardware( void ) 221setup_hardware( void )
222{ 222{
223 int val; 223 int val;
224 int err;
224 225
225 /* save registers (if we unload the module) */ 226 /* save registers (if we unload the module) */
226 x.r0 = read_reg( x.fan, 0x00, 1 ); 227 x.r0 = read_reg( x.fan, 0x00, 1 );
@@ -263,8 +264,11 @@ setup_hardware( void )
263 x.upind = -1; 264 x.upind = -1;
264 /* tune_fan( fan_up_table[x.upind].fan_setting ); */ 265 /* tune_fan( fan_up_table[x.upind].fan_setting ); */
265 266
266 device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature ); 267 err = device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
267 device_create_file( &x.of_dev->dev, &dev_attr_case_temperature ); 268 err |= device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
269 if (err)
270 printk(KERN_WARNING
271 "Failed to create temperature attribute file(s).\n");
268} 272}
269 273
270static void 274static void
@@ -280,27 +284,27 @@ restore_regs( void )
280 write_reg( x.fan, 0x00, x.r0, 1 ); 284 write_reg( x.fan, 0x00, x.r0, 1 );
281} 285}
282 286
283static int 287static int control_loop(void *dummy)
284control_loop( void *dummy )
285{ 288{
286 daemonize("g4fand"); 289 down(&x.lock);
287
288 down( &x.lock );
289 setup_hardware(); 290 setup_hardware();
291 up(&x.lock);
290 292
291 while( x.running ) { 293 for (;;) {
292 up( &x.lock );
293
294 msleep_interruptible(8000); 294 msleep_interruptible(8000);
295 295 if (kthread_should_stop())
296 down( &x.lock ); 296 break;
297
298 down(&x.lock);
297 poll_temp(); 299 poll_temp();
300 up(&x.lock);
298 } 301 }
299 302
303 down(&x.lock);
300 restore_regs(); 304 restore_regs();
301 up( &x.lock ); 305 up(&x.lock);
302 306
303 complete_and_exit( &x.completion, 0 ); 307 return 0;
304} 308}
305 309
306 310
@@ -320,8 +324,7 @@ do_attach( struct i2c_adapter *adapter )
320 ret = i2c_probe( adapter, &addr_data, &do_probe ); 324 ret = i2c_probe( adapter, &addr_data, &do_probe );
321 if( x.thermostat && x.fan ) { 325 if( x.thermostat && x.fan ) {
322 x.running = 1; 326 x.running = 1;
323 init_completion( &x.completion ); 327 x.poll_task = kthread_run(control_loop, NULL, "g4fand");
324 x.poll_task = kernel_thread( control_loop, NULL, SIGCHLD | CLONE_KERNEL );
325 } 328 }
326 } 329 }
327 return ret; 330 return ret;
@@ -337,7 +340,8 @@ do_detach( struct i2c_client *client )
337 else { 340 else {
338 if( x.running ) { 341 if( x.running ) {
339 x.running = 0; 342 x.running = 0;
340 wait_for_completion( &x.completion ); 343 kthread_stop(x.poll_task);
344 x.poll_task = NULL;
341 } 345 }
342 if( client == x.thermostat ) 346 if( client == x.thermostat )
343 x.thermostat = NULL; 347 x.thermostat = NULL;