*
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/kthread.h>
+
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/sections.h>
-#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#include <asm/macio.h>
#define LOG_TEMP 0 /* continously log temperature */
-#define I2C_DRIVERID_G4FAN 0x9001 /* fixme */
-
static int do_probe( struct i2c_adapter *adapter, int addr, int kind);
/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
-static unsigned short normal_i2c[] = { 0x49, 0x2c, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { 0x48, 0x4f, 0x2c, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x2c, 0x2d, 0x2e, 0x2f,
+ I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
static struct {
volatile int running;
- struct completion completion;
- pid_t poll_task;
+ struct task_struct *poll_task;
struct semaphore lock;
struct of_device *of_dev;
setup_hardware( void )
{
int val;
+ int err;
/* save registers (if we unload the module) */
x.r0 = read_reg( x.fan, 0x00, 1 );
x.upind = -1;
/* tune_fan( fan_up_table[x.upind].fan_setting ); */
- device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
- device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
+ err = device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
+ err |= device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
+ if (err)
+ printk(KERN_WARNING
+ "Failed to create temperature attribute file(s).\n");
}
static void
write_reg( x.fan, 0x00, x.r0, 1 );
}
-static int
-control_loop( void *dummy )
+static int control_loop(void *dummy)
{
- daemonize("g4fand");
-
- down( &x.lock );
+ down(&x.lock);
setup_hardware();
+ up(&x.lock);
- while( x.running ) {
- up( &x.lock );
-
+ for (;;) {
msleep_interruptible(8000);
-
- down( &x.lock );
+ if (kthread_should_stop())
+ break;
+
+ down(&x.lock);
poll_temp();
+ up(&x.lock);
}
+ down(&x.lock);
restore_regs();
- up( &x.lock );
+ up(&x.lock);
- complete_and_exit( &x.completion, 0 );
+ return 0;
}
ret = i2c_probe( adapter, &addr_data, &do_probe );
if( x.thermostat && x.fan ) {
x.running = 1;
- init_completion( &x.completion );
- x.poll_task = kernel_thread( control_loop, NULL, SIGCHLD | CLONE_KERNEL );
+ x.poll_task = kthread_run(control_loop, NULL, "g4fand");
}
}
return ret;
else {
if( x.running ) {
x.running = 0;
- wait_for_completion( &x.completion );
+ kthread_stop(x.poll_task);
+ x.poll_task = NULL;
}
if( client == x.thermostat )
x.thermostat = NULL;
}
static struct i2c_driver g4fan_driver = {
- .owner = THIS_MODULE,
- .name = "therm_windtunnel",
- .id = I2C_DRIVERID_G4FAN,
- .flags = I2C_DF_NOTIFY,
+ .driver = {
+ .name = "therm_windtunnel",
+ },
.attach_adapter = do_attach,
.detach_client = do_detach,
};
| I2C_FUNC_SMBUS_WRITE_BYTE) )
return 0;
- if( !(cl=kmalloc(sizeof(*cl), GFP_KERNEL)) )
+ if( !(cl=kzalloc(sizeof(*cl), GFP_KERNEL)) )
return -ENOMEM;
- memset( cl, 0, sizeof(struct i2c_client) );
cl->addr = addr;
cl->adapter = adapter;
/************************************************************************/
static int
-therm_of_probe( struct of_device *dev, const struct of_match *match )
+therm_of_probe( struct of_device *dev, const struct of_device_id *match )
{
return i2c_add_driver( &g4fan_driver );
}
static int
therm_of_remove( struct of_device *dev )
{
- return i2c_del_driver( &g4fan_driver );
+ i2c_del_driver( &g4fan_driver );
+ return 0;
}
-static struct of_match therm_of_match[] = {{
+static struct of_device_id therm_of_match[] = {{
.name = "fan",
- .type = OF_ANY_MATCH,
.compatible = "adm1030"
}, {}
};
static int __init
g4fan_init( void )
{
- struct apple_thermal_info *info;
+ const struct apple_thermal_info *info;
struct device_node *np;
init_MUTEX( &x.lock );
if( !(np=of_find_node_by_name(NULL, "power-mgt")) )
return -ENODEV;
- info = (struct apple_thermal_info*)get_property(np, "thermal-info", NULL);
+ info = of_get_property(np, "thermal-info", NULL);
of_node_put(np);
if( !info || !machine_is_compatible("PowerMac3,6") )
}
if( !(np=of_find_node_by_name(NULL, "fan")) )
return -ENODEV;
- x.of_dev = of_platform_device_create( np, "temperature" );
+ x.of_dev = of_platform_device_create(np, "temperature", NULL);
of_node_put( np );
if( !x.of_dev ) {
return -ENODEV;
}
- of_register_driver( &therm_of_driver );
+ of_register_platform_driver( &therm_of_driver );
return 0;
}
static void __exit
g4fan_exit( void )
{
- of_unregister_driver( &therm_of_driver );
+ of_unregister_platform_driver( &therm_of_driver );
if( x.of_dev )
of_device_unregister( x.of_dev );