1 /* 2 * Device driver for the i2c thermostat found on the iBook G4, Albook G4 3 * 4 * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt 5 * 6 * Documentation from 115254175ADT7467_pra.pdf and 3686221171167ADT7460_b.pdf 7 * http://www.onsemi.com/PowerSolutions/product.do?id=ADT7467 8 * http://www.onsemi.com/PowerSolutions/product.do?id=ADT7460 9 * 10 */ 11 12 #include <linux/types.h> 13 #include <linux/module.h> 14 #include <linux/errno.h> 15 #include <linux/kernel.h> 16 #include <linux/delay.h> 17 #include <linux/sched.h> 18 #include <linux/i2c.h> 19 #include <linux/slab.h> 20 #include <linux/init.h> 21 #include <linux/spinlock.h> 22 #include <linux/wait.h> 23 #include <linux/suspend.h> 24 #include <linux/kthread.h> 25 #include <linux/moduleparam.h> 26 #include <linux/freezer.h> 27 #include <linux/of_platform.h> 28 29 #include <asm/prom.h> 30 #include <asm/machdep.h> 31 #include <asm/io.h> 32 #include <asm/sections.h> 33 34 #undef DEBUG 35 36 #define CONFIG_REG 0x40 37 #define MANUAL_MASK 0xe0 38 #define AUTO_MASK 0x20 39 #define INVERT_MASK 0x10 40 41 static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ 42 static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ 43 static u8 MANUAL_MODE[2] = {0x5c, 0x5d}; 44 static u8 REM_CONTROL[2] = {0x00, 0x40}; 45 static u8 FAN_SPEED[2] = {0x28, 0x2a}; 46 static u8 FAN_SPD_SET[2] = {0x30, 0x31}; 47 48 static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ 49 static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ 50 static const char *sensor_location[3]; 51 52 static int limit_adjust; 53 static int fan_speed = -1; 54 static bool verbose; 55 56 MODULE_AUTHOR("Colin Leroy <colin@colino.net>"); 57 MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and " 58 "Powerbook G4 Alu"); 59 MODULE_LICENSE("GPL"); 60 61 module_param(limit_adjust, int, 0644); 62 MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 sensor1, 70 sensor2) " 63 "by N degrees."); 64 65 module_param(fan_speed, int, 0644); 66 MODULE_PARM_DESC(fan_speed,"Specify starting fan speed (0-255) " 67 "(default 64)"); 68 69 module_param(verbose, bool, 0); 70 MODULE_PARM_DESC(verbose,"Verbose log operations " 71 "(default 0)"); 72 73 struct thermostat { 74 struct i2c_client *clt; 75 u8 temps[3]; 76 u8 cached_temp[3]; 77 u8 initial_limits[3]; 78 u8 limits[3]; 79 int last_speed[2]; 80 int last_var[2]; 81 int pwm_inv[2]; 82 }; 83 84 static enum {ADT7460, ADT7467} therm_type; 85 static int therm_bus, therm_address; 86 static struct platform_device * of_dev; 87 static struct thermostat* thermostat; 88 static struct task_struct *thread_therm = NULL; 89 90 static void write_both_fan_speed(struct thermostat *th, int speed); 91 static void write_fan_speed(struct thermostat *th, int speed, int fan); 92 static void thermostat_create_files(void); 93 static void thermostat_remove_files(void); 94 95 static int 96 write_reg(struct thermostat* th, int reg, u8 data) 97 { 98 u8 tmp[2]; 99 int rc; 100 101 tmp[0] = reg; 102 tmp[1] = data; 103 rc = i2c_master_send(th->clt, (const char *)tmp, 2); 104 if (rc < 0) 105 return rc; 106 if (rc != 2) 107 return -ENODEV; 108 return 0; 109 } 110 111 static int 112 read_reg(struct thermostat* th, int reg) 113 { 114 u8 reg_addr, data; 115 int rc; 116 117 reg_addr = (u8)reg; 118 rc = i2c_master_send(th->clt, ®_addr, 1); 119 if (rc < 0) 120 return rc; 121 if (rc != 1) 122 return -ENODEV; 123 rc = i2c_master_recv(th->clt, (char *)&data, 1); 124 if (rc < 0) 125 return rc; 126 return data; 127 } 128 129 static struct i2c_driver thermostat_driver; 130 131 static int 132 attach_thermostat(struct i2c_adapter *adapter) 133 { 134 unsigned long bus_no; 135 struct i2c_board_info info; 136 struct i2c_client *client; 137 138 if (strncmp(adapter->name, "uni-n", 5)) 139 return -ENODEV; 140 bus_no = simple_strtoul(adapter->name + 6, NULL, 10); 141 if (bus_no != therm_bus) 142 return -ENODEV; 143 144 memset(&info, 0, sizeof(struct i2c_board_info)); 145 strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE); 146 info.addr = therm_address; 147 client = i2c_new_device(adapter, &info); 148 if (!client) 149 return -ENODEV; 150 151 /* 152 * Let i2c-core delete that device on driver removal. 153 * This is safe because i2c-core holds the core_lock mutex for us. 154 */ 155 list_add_tail(&client->detected, &thermostat_driver.clients); 156 return 0; 157 } 158 159 static int 160 remove_thermostat(struct i2c_client *client) 161 { 162 struct thermostat *th = i2c_get_clientdata(client); 163 int i; 164 165 thermostat_remove_files(); 166 167 if (thread_therm != NULL) { 168 kthread_stop(thread_therm); 169 } 170 171 printk(KERN_INFO "adt746x: Putting max temperatures back from " 172 "%d, %d, %d to %d, %d, %d\n", 173 th->limits[0], th->limits[1], th->limits[2], 174 th->initial_limits[0], th->initial_limits[1], 175 th->initial_limits[2]); 176 177 for (i = 0; i < 3; i++) 178 write_reg(th, LIMIT_REG[i], th->initial_limits[i]); 179 180 write_both_fan_speed(th, -1); 181 182 thermostat = NULL; 183 184 kfree(th); 185 186 return 0; 187 } 188 189 static int read_fan_speed(struct thermostat *th, u8 addr) 190 { 191 u8 tmp[2]; 192 u16 res; 193 194 /* should start with low byte */ 195 tmp[1] = read_reg(th, addr); 196 tmp[0] = read_reg(th, addr + 1); 197 198 res = tmp[1] + (tmp[0] << 8); 199 /* "a value of 0xffff means that the fan has stopped" */ 200 return (res == 0xffff ? 0 : (90000*60)/res); 201 } 202 203 static void write_both_fan_speed(struct thermostat *th, int speed) 204 { 205 write_fan_speed(th, speed, 0); 206 if (therm_type == ADT7460) 207 write_fan_speed(th, speed, 1); 208 } 209 210 static void write_fan_speed(struct thermostat *th, int speed, int fan) 211 { 212 u8 manual; 213 214 if (speed > 0xff) 215 speed = 0xff; 216 else if (speed < -1) 217 speed = 0; 218 219 if (therm_type == ADT7467 && fan == 1) 220 return; 221 222 if (th->last_speed[fan] != speed) { 223 if (verbose) { 224 if (speed == -1) 225 printk(KERN_DEBUG "adt746x: Setting speed to automatic " 226 "for %s fan.\n", sensor_location[fan+1]); 227 else 228 printk(KERN_DEBUG "adt746x: Setting speed to %d " 229 "for %s fan.\n", speed, sensor_location[fan+1]); 230 } 231 } else 232 return; 233 234 if (speed >= 0) { 235 manual = read_reg(th, MANUAL_MODE[fan]); 236 manual &= ~INVERT_MASK; 237 write_reg(th, MANUAL_MODE[fan], 238 manual | MANUAL_MASK | th->pwm_inv[fan]); 239 write_reg(th, FAN_SPD_SET[fan], speed); 240 } else { 241 /* back to automatic */ 242 if(therm_type == ADT7460) { 243 manual = read_reg(th, 244 MANUAL_MODE[fan]) & (~MANUAL_MASK); 245 manual &= ~INVERT_MASK; 246 manual |= th->pwm_inv[fan]; 247 write_reg(th, 248 MANUAL_MODE[fan], manual|REM_CONTROL[fan]); 249 } else { 250 manual = read_reg(th, MANUAL_MODE[fan]); 251 manual &= ~INVERT_MASK; 252 manual |= th->pwm_inv[fan]; 253 write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); 254 } 255 } 256 257 th->last_speed[fan] = speed; 258 } 259 260 static void read_sensors(struct thermostat *th) 261 { 262 int i = 0; 263 264 for (i = 0; i < 3; i++) 265 th->temps[i] = read_reg(th, TEMP_REG[i]); 266 } 267 268 #ifdef DEBUG 269 static void display_stats(struct thermostat *th) 270 { 271 if (th->temps[0] != th->cached_temp[0] 272 || th->temps[1] != th->cached_temp[1] 273 || th->temps[2] != th->cached_temp[2]) { 274 printk(KERN_INFO "adt746x: Temperature infos:" 275 " thermostats: %d,%d,%d;" 276 " limits: %d,%d,%d;" 277 " fan speed: %d RPM\n", 278 th->temps[0], th->temps[1], th->temps[2], 279 th->limits[0], th->limits[1], th->limits[2], 280 read_fan_speed(th, FAN_SPEED[0])); 281 } 282 th->cached_temp[0] = th->temps[0]; 283 th->cached_temp[1] = th->temps[1]; 284 th->cached_temp[2] = th->temps[2]; 285 } 286 #endif 287 288 static void update_fans_speed (struct thermostat *th) 289 { 290 int lastvar = 0; /* last variation, for iBook */ 291 int i = 0; 292 293 /* we don't care about local sensor, so we start at sensor 1 */ 294 for (i = 1; i < 3; i++) { 295 int started = 0; 296 int fan_number = (therm_type == ADT7460 && i == 2); 297 int var = th->temps[i] - th->limits[i]; 298 299 if (var > -1) { 300 int step = (255 - fan_speed) / 7; 301 int new_speed = 0; 302 303 /* hysteresis : change fan speed only if variation is 304 * more than two degrees */ 305 if (abs(var - th->last_var[fan_number]) < 2) 306 continue; 307 308 started = 1; 309 new_speed = fan_speed + ((var-1)*step); 310 311 if (new_speed < fan_speed) 312 new_speed = fan_speed; 313 if (new_speed > 255) 314 new_speed = 255; 315 316 if (verbose) 317 printk(KERN_DEBUG "adt746x: Setting fans speed to %d " 318 "(limit exceeded by %d on %s)\n", 319 new_speed, var, 320 sensor_location[fan_number+1]); 321 write_both_fan_speed(th, new_speed); 322 th->last_var[fan_number] = var; 323 } else if (var < -2) { 324 /* don't stop fan if sensor2 is cold and sensor1 is not 325 * so cold (lastvar >= -1) */ 326 if (i == 2 && lastvar < -1) { 327 if (th->last_speed[fan_number] != 0) 328 if (verbose) 329 printk(KERN_DEBUG "adt746x: Stopping " 330 "fans.\n"); 331 write_both_fan_speed(th, 0); 332 } 333 } 334 335 lastvar = var; 336 337 if (started) 338 return; /* we don't want to re-stop the fan 339 * if sensor1 is heating and sensor2 is not */ 340 } 341 } 342 343 static int monitor_task(void *arg) 344 { 345 struct thermostat* th = arg; 346 347 set_freezable(); 348 while(!kthread_should_stop()) { 349 try_to_freeze(); 350 msleep_interruptible(2000); 351 352 #ifndef DEBUG 353 if (fan_speed != -1) 354 read_sensors(th); 355 #else 356 read_sensors(th); 357 #endif 358 359 if (fan_speed != -1) 360 update_fans_speed(th); 361 362 #ifdef DEBUG 363 display_stats(th); 364 #endif 365 366 } 367 368 return 0; 369 } 370 371 static void set_limit(struct thermostat *th, int i) 372 { 373 /* Set sensor1 limit higher to avoid powerdowns */ 374 th->limits[i] = default_limits_chip[i] + limit_adjust; 375 write_reg(th, LIMIT_REG[i], th->limits[i]); 376 377 /* set our limits to normal */ 378 th->limits[i] = default_limits_local[i] + limit_adjust; 379 } 380 381 static int probe_thermostat(struct i2c_client *client, 382 const struct i2c_device_id *id) 383 { 384 struct thermostat* th; 385 int rc; 386 int i; 387 388 if (thermostat) 389 return 0; 390 391 th = kzalloc(sizeof(struct thermostat), GFP_KERNEL); 392 if (!th) 393 return -ENOMEM; 394 395 i2c_set_clientdata(client, th); 396 th->clt = client; 397 398 rc = read_reg(th, CONFIG_REG); 399 if (rc < 0) { 400 dev_err(&client->dev, "Thermostat failed to read config!\n"); 401 kfree(th); 402 return -ENODEV; 403 } 404 405 /* force manual control to start the fan quieter */ 406 if (fan_speed == -1) 407 fan_speed = 64; 408 409 if(therm_type == ADT7460) { 410 printk(KERN_INFO "adt746x: ADT7460 initializing\n"); 411 /* The 7460 needs to be started explicitly */ 412 write_reg(th, CONFIG_REG, 1); 413 } else 414 printk(KERN_INFO "adt746x: ADT7467 initializing\n"); 415 416 for (i = 0; i < 3; i++) { 417 th->initial_limits[i] = read_reg(th, LIMIT_REG[i]); 418 set_limit(th, i); 419 } 420 421 printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d" 422 " to %d, %d, %d\n", 423 th->initial_limits[0], th->initial_limits[1], 424 th->initial_limits[2], th->limits[0], th->limits[1], 425 th->limits[2]); 426 427 thermostat = th; 428 429 /* record invert bit status because fw can corrupt it after suspend */ 430 th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK; 431 th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK; 432 433 /* be sure to really write fan speed the first time */ 434 th->last_speed[0] = -2; 435 th->last_speed[1] = -2; 436 th->last_var[0] = -80; 437 th->last_var[1] = -80; 438 439 if (fan_speed != -1) { 440 /* manual mode, stop fans */ 441 write_both_fan_speed(th, 0); 442 } else { 443 /* automatic mode */ 444 write_both_fan_speed(th, -1); 445 } 446 447 thread_therm = kthread_run(monitor_task, th, "kfand"); 448 449 if (thread_therm == ERR_PTR(-ENOMEM)) { 450 printk(KERN_INFO "adt746x: Kthread creation failed\n"); 451 thread_therm = NULL; 452 return -ENOMEM; 453 } 454 455 thermostat_create_files(); 456 457 return 0; 458 } 459 460 static const struct i2c_device_id therm_adt746x_id[] = { 461 { "therm_adt746x", 0 }, 462 { } 463 }; 464 465 static struct i2c_driver thermostat_driver = { 466 .driver = { 467 .name = "therm_adt746x", 468 }, 469 .attach_adapter = attach_thermostat, 470 .probe = probe_thermostat, 471 .remove = remove_thermostat, 472 .id_table = therm_adt746x_id, 473 }; 474 475 /* 476 * Now, unfortunately, sysfs doesn't give us a nice void * we could 477 * pass around to the attribute functions, so we don't really have 478 * choice but implement a bunch of them... 479 * 480 * FIXME, it does now... 481 */ 482 #define BUILD_SHOW_FUNC_INT(name, data) \ 483 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 484 { \ 485 return sprintf(buf, "%d\n", data); \ 486 } 487 488 #define BUILD_SHOW_FUNC_STR(name, data) \ 489 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 490 { \ 491 return sprintf(buf, "%s\n", data); \ 492 } 493 494 #define BUILD_SHOW_FUNC_FAN(name, data) \ 495 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 496 { \ 497 return sprintf(buf, "%d (%d rpm)\n", \ 498 thermostat->last_speed[data], \ 499 read_fan_speed(thermostat, FAN_SPEED[data]) \ 500 ); \ 501 } 502 503 #define BUILD_STORE_FUNC_DEG(name, data) \ 504 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \ 505 { \ 506 int val; \ 507 int i; \ 508 val = simple_strtol(buf, NULL, 10); \ 509 printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \ 510 limit_adjust = val; \ 511 for (i=0; i < 3; i++) \ 512 set_limit(thermostat, i); \ 513 return n; \ 514 } 515 516 #define BUILD_STORE_FUNC_INT(name, data) \ 517 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \ 518 { \ 519 int val; \ 520 val = simple_strtol(buf, NULL, 10); \ 521 if (val < 0 || val > 255) \ 522 return -EINVAL; \ 523 printk(KERN_INFO "Setting specified fan speed to %d\n", val); \ 524 data = val; \ 525 return n; \ 526 } 527 528 BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(thermostat, TEMP_REG[1]))) 529 BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(thermostat, TEMP_REG[2]))) 530 BUILD_SHOW_FUNC_INT(sensor1_limit, thermostat->limits[1]) 531 BUILD_SHOW_FUNC_INT(sensor2_limit, thermostat->limits[2]) 532 BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1]) 533 BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2]) 534 535 BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed) 536 BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0) 537 BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1) 538 539 BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed) 540 BUILD_SHOW_FUNC_INT(limit_adjust, limit_adjust) 541 BUILD_STORE_FUNC_DEG(limit_adjust, thermostat) 542 543 static DEVICE_ATTR(sensor1_temperature, S_IRUGO, 544 show_sensor1_temperature,NULL); 545 static DEVICE_ATTR(sensor2_temperature, S_IRUGO, 546 show_sensor2_temperature,NULL); 547 static DEVICE_ATTR(sensor1_limit, S_IRUGO, 548 show_sensor1_limit, NULL); 549 static DEVICE_ATTR(sensor2_limit, S_IRUGO, 550 show_sensor2_limit, NULL); 551 static DEVICE_ATTR(sensor1_location, S_IRUGO, 552 show_sensor1_location, NULL); 553 static DEVICE_ATTR(sensor2_location, S_IRUGO, 554 show_sensor2_location, NULL); 555 556 static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 557 show_specified_fan_speed,store_specified_fan_speed); 558 559 static DEVICE_ATTR(sensor1_fan_speed, S_IRUGO, 560 show_sensor1_fan_speed, NULL); 561 static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO, 562 show_sensor2_fan_speed, NULL); 563 564 static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 565 show_limit_adjust, store_limit_adjust); 566 567 568 static int __init 569 thermostat_init(void) 570 { 571 struct device_node* np; 572 const u32 *prop; 573 int i = 0, offset = 0; 574 575 np = of_find_node_by_name(NULL, "fan"); 576 if (!np) 577 return -ENODEV; 578 if (of_device_is_compatible(np, "adt7460")) 579 therm_type = ADT7460; 580 else if (of_device_is_compatible(np, "adt7467")) 581 therm_type = ADT7467; 582 else { 583 of_node_put(np); 584 return -ENODEV; 585 } 586 587 prop = of_get_property(np, "hwsensor-params-version", NULL); 588 printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop, 589 (*prop == 1)?"":"un"); 590 if (*prop != 1) { 591 of_node_put(np); 592 return -ENODEV; 593 } 594 595 prop = of_get_property(np, "reg", NULL); 596 if (!prop) { 597 of_node_put(np); 598 return -ENODEV; 599 } 600 601 /* look for bus either by path or using "reg" */ 602 if (strstr(np->full_name, "/i2c-bus@") != NULL) { 603 const char *tmp_bus = (strstr(np->full_name, "/i2c-bus@") + 9); 604 therm_bus = tmp_bus[0]-'0'; 605 } else { 606 therm_bus = ((*prop) >> 8) & 0x0f; 607 } 608 609 therm_address = ((*prop) & 0xff) >> 1; 610 611 printk(KERN_INFO "adt746x: Thermostat bus: %d, address: 0x%02x, " 612 "limit_adjust: %d, fan_speed: %d\n", 613 therm_bus, therm_address, limit_adjust, fan_speed); 614 615 if (of_get_property(np, "hwsensor-location", NULL)) { 616 for (i = 0; i < 3; i++) { 617 sensor_location[i] = of_get_property(np, 618 "hwsensor-location", NULL) + offset; 619 620 if (sensor_location[i] == NULL) 621 sensor_location[i] = ""; 622 623 printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]); 624 offset += strlen(sensor_location[i]) + 1; 625 } 626 } else { 627 sensor_location[0] = "?"; 628 sensor_location[1] = "?"; 629 sensor_location[2] = "?"; 630 } 631 632 of_dev = of_platform_device_create(np, "temperatures", NULL); 633 of_node_put(np); 634 635 if (of_dev == NULL) { 636 printk(KERN_ERR "Can't register temperatures device !\n"); 637 return -ENODEV; 638 } 639 640 #ifndef CONFIG_I2C_POWERMAC 641 request_module("i2c-powermac"); 642 #endif 643 644 return i2c_add_driver(&thermostat_driver); 645 } 646 647 static void thermostat_create_files(void) 648 { 649 int err; 650 651 err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); 652 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); 653 err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); 654 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); 655 err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location); 656 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location); 657 err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust); 658 err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); 659 err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); 660 if(therm_type == ADT7460) 661 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); 662 if (err) 663 printk(KERN_WARNING 664 "Failed to create temperature attribute file(s).\n"); 665 } 666 667 static void thermostat_remove_files(void) 668 { 669 if (of_dev) { 670 device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); 671 device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature); 672 device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit); 673 device_remove_file(&of_dev->dev, &dev_attr_sensor2_limit); 674 device_remove_file(&of_dev->dev, &dev_attr_sensor1_location); 675 device_remove_file(&of_dev->dev, &dev_attr_sensor2_location); 676 device_remove_file(&of_dev->dev, &dev_attr_limit_adjust); 677 device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed); 678 device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); 679 680 if(therm_type == ADT7460) 681 device_remove_file(&of_dev->dev, 682 &dev_attr_sensor2_fan_speed); 683 684 } 685 } 686 687 static void __exit 688 thermostat_exit(void) 689 { 690 i2c_del_driver(&thermostat_driver); 691 of_device_unregister(of_dev); 692 } 693 694 module_init(thermostat_init); 695 module_exit(thermostat_exit); 696